Support unknown property types when serializing and deserializing
このコミットが含まれているのは:
コミット
c91db1e4ae
|
@ -91,7 +91,7 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() ([]*Method, []*Functi
|
||||||
/*params=*/ nil,
|
/*params=*/ nil,
|
||||||
[]jen.Code{jen.Interface(), jen.Error()},
|
[]jen.Code{jen.Interface(), jen.Error()},
|
||||||
[]jen.Code{serializeFns, jen.Return(
|
[]jen.Code{serializeFns, jen.Return(
|
||||||
jen.Nil(),
|
jen.Id(This()).Dot(unknownMemberName),
|
||||||
jen.Nil(),
|
jen.Nil(),
|
||||||
)},
|
)},
|
||||||
jen.Commentf("%s converts this into an interface representation suitable for marshalling into a text or binary format.", p.serializeFnName()),
|
jen.Commentf("%s converts this into an interface representation suitable for marshalling into a text or binary format.", p.serializeFnName()),
|
||||||
|
@ -136,7 +136,7 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() ([]*Method, []*Functi
|
||||||
[]jen.Code{jen.Id("i").Interface()},
|
[]jen.Code{jen.Id("i").Interface()},
|
||||||
[]jen.Code{jen.Op("*").Id(p.structName()), jen.Error()},
|
[]jen.Code{jen.Op("*").Id(p.structName()), jen.Error()},
|
||||||
[]jen.Code{
|
[]jen.Code{
|
||||||
deserializeFns,
|
deserializeFns.Add(p.unknownDeserializeCode()),
|
||||||
jen.Return(
|
jen.Return(
|
||||||
jen.Nil(),
|
jen.Nil(),
|
||||||
jen.Nil(),
|
jen.Nil(),
|
||||||
|
@ -161,7 +161,7 @@ func (p *FunctionalPropertyGenerator) serializationFuncs() ([]*Method, []*Functi
|
||||||
),
|
),
|
||||||
jen.Id("ok"),
|
jen.Id("ok"),
|
||||||
).Block(
|
).Block(
|
||||||
deserializeFns,
|
deserializeFns.Add(p.unknownDeserializeCode()),
|
||||||
),
|
),
|
||||||
jen.Return(
|
jen.Return(
|
||||||
jen.Nil(),
|
jen.Nil(),
|
||||||
|
@ -184,7 +184,10 @@ func (p *FunctionalPropertyGenerator) singleTypeDef() *Struct {
|
||||||
if p.asIterator {
|
if p.asIterator {
|
||||||
comment = jen.Commentf("%s is an iterator for a property. It is permitted to be a single nilable value type.", p.structName())
|
comment = jen.Commentf("%s is an iterator for a property. It is permitted to be a single nilable value type.", p.structName())
|
||||||
}
|
}
|
||||||
kindMembers = []jen.Code{jen.Id(p.memberName(0)).Id(p.Kinds[0].ConcreteKind)}
|
kindMembers = []jen.Code{
|
||||||
|
jen.Id(p.memberName(0)).Id(p.Kinds[0].ConcreteKind),
|
||||||
|
p.unknownMemberDef(),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
comment = jen.Commentf("%s is the functional property %q. It is permitted to be a single default-valued value type.", p.structName(), p.propertyName())
|
comment = jen.Commentf("%s is the functional property %q. It is permitted to be a single default-valued value type.", p.structName(), p.propertyName())
|
||||||
if p.asIterator {
|
if p.asIterator {
|
||||||
|
@ -193,6 +196,7 @@ func (p *FunctionalPropertyGenerator) singleTypeDef() *Struct {
|
||||||
kindMembers = []jen.Code{
|
kindMembers = []jen.Code{
|
||||||
jen.Id(p.memberName(0)).Id(p.Kinds[0].ConcreteKind),
|
jen.Id(p.memberName(0)).Id(p.Kinds[0].ConcreteKind),
|
||||||
jen.Id(p.hasMemberName(0)).Bool(),
|
jen.Id(p.hasMemberName(0)).Bool(),
|
||||||
|
p.unknownMemberDef(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
methods, funcs := p.serializationFuncs()
|
methods, funcs := p.serializationFuncs()
|
||||||
|
@ -308,6 +312,7 @@ func (p *FunctionalPropertyGenerator) multiTypeDef() *Struct {
|
||||||
kindMembers = append(kindMembers, jen.Id(p.hasMemberName(i)).Bool())
|
kindMembers = append(kindMembers, jen.Id(p.hasMemberName(i)).Bool())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
kindMembers = append(kindMembers, p.unknownMemberDef())
|
||||||
explanation := jen.Commentf(
|
explanation := jen.Commentf(
|
||||||
"At most, one type of value can be present, or none at all. Setting a value will",
|
"At most, one type of value can be present, or none at all. Setting a value will",
|
||||||
).Line().Commentf(
|
).Line().Commentf(
|
||||||
|
@ -454,3 +459,33 @@ func (p *FunctionalPropertyGenerator) multiTypeFuncs() []*Method {
|
||||||
}
|
}
|
||||||
return methods
|
return methods
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unknownMemberDef returns the definition of a struct member that handles
|
||||||
|
// a property whose type is unknown.
|
||||||
|
func (p *FunctionalPropertyGenerator) unknownMemberDef() jen.Code {
|
||||||
|
return jen.Id(unknownMemberName).Index().Byte()
|
||||||
|
}
|
||||||
|
|
||||||
|
// unknownDeserializeCode generates the "else if it's a []byte" code used for
|
||||||
|
// deserializing unknown values.
|
||||||
|
func (p *FunctionalPropertyGenerator) unknownDeserializeCode() jen.Code {
|
||||||
|
return jen.Else().If(
|
||||||
|
jen.List(
|
||||||
|
jen.Id("v"),
|
||||||
|
jen.Id("ok"),
|
||||||
|
).Op(":=").Id("i").Assert(
|
||||||
|
jen.Index().Byte(),
|
||||||
|
),
|
||||||
|
jen.Id("ok"),
|
||||||
|
).Block(
|
||||||
|
jen.Id(This()).Op(":=").Op("&").Id(p.structName()).Values(
|
||||||
|
jen.Dict{
|
||||||
|
jen.Id(unknownMemberName): jen.Id("v"),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
jen.Return(
|
||||||
|
jen.Id(This()),
|
||||||
|
jen.Err(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"github.com/dave/jennifer/jen"
|
"github.com/dave/jennifer/jen"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Deserialize & generated structs preserve "unknown" elements.
|
|
||||||
// TODO: Natural language map.
|
// TODO: Natural language map.
|
||||||
// TODO: Kind serialize/deserialize use Method/Function.
|
// TODO: Kind serialize/deserialize use Method/Function.
|
||||||
|
|
||||||
|
@ -29,6 +28,8 @@ const (
|
||||||
nameMethod = "Name"
|
nameMethod = "Name"
|
||||||
serializeIteratorMethod = "serialize"
|
serializeIteratorMethod = "serialize"
|
||||||
deserializeIteratorMethod = "deserialize"
|
deserializeIteratorMethod = "deserialize"
|
||||||
|
// Member names for generated code
|
||||||
|
unknownMemberName = "unknown"
|
||||||
)
|
)
|
||||||
|
|
||||||
// join appends a bunch of Go Code together, each on their own line.
|
// join appends a bunch of Go Code together, each on their own line.
|
||||||
|
|
読み込み中…
新しいイシューから参照