Skip to content

Commit

Permalink
feat: add inline union representation to schema parser
Browse files Browse the repository at this point in the history
  • Loading branch information
rvagg committed Jun 28, 2023
1 parent 499e9b9 commit 65bfa53
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .ipld
34 changes: 29 additions & 5 deletions schema/dmt/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,15 @@ func spawnType(ts *schema.TypeSystem, name schema.TypeName, defn TypeDefn) (sche
switch {
case member.TypeName != nil:
memberName := *member.TypeName
validMember(memberName)
if err := validMember(memberName); err != nil {
return nil, err
}
table[kind] = memberName
case member.UnionMemberInlineDefn != nil:
tname := anonLinkName(*member.UnionMemberInlineDefn.TypeDefnLink)
validMember(tname)
if err := validMember(tname); err != nil {
return nil, err
}
table[kind] = tname
}
}
Expand All @@ -351,21 +355,41 @@ func spawnType(ts *schema.TypeSystem, name schema.TypeName, defn TypeDefn) (sche
switch {
case member.TypeName != nil:
memberName := *member.TypeName
validMember(memberName)
if err := validMember(memberName); err != nil {
return nil, err
}
table[key] = memberName
case member.UnionMemberInlineDefn != nil:
tname := anonLinkName(*member.UnionMemberInlineDefn.TypeDefnLink)
validMember(tname)
if err := validMember(tname); err != nil {
return nil, err
}
table[key] = tname
}
}
repr = schema.SpawnUnionRepresentationKeyed(table)
case typ.Representation.UnionRepresentation_StringPrefix != nil:
prefixes := typ.Representation.UnionRepresentation_StringPrefix.Prefixes
for _, key := range prefixes.Keys {
validMember(prefixes.Values[key])
if err := validMember(prefixes.Values[key]); err != nil {
return nil, err
}
}
repr = schema.SpawnUnionRepresentationStringprefix("", prefixes.Values)
case typ.Representation.UnionRepresentation_Inline != nil:
rp := typ.Representation.UnionRepresentation_Inline
if rp.DiscriminantKey == "" {
return nil, fmt.Errorf("inline union has empty discriminantKey value")
}
if rp.DiscriminantTable.Keys == nil || rp.DiscriminantTable.Values == nil {
return nil, fmt.Errorf("inline union has empty discriminantTable")
}
for _, key := range rp.DiscriminantTable.Keys {
if err := validMember(rp.DiscriminantTable.Values[key]); err != nil {
return nil, err
}
}
repr = schema.SpawnUnionRepresentationInline(rp.DiscriminantKey, rp.DiscriminantTable.Values)
default:
return nil, fmt.Errorf("TODO: support other union repr in schema package")
}
Expand Down
25 changes: 25 additions & 0 deletions schema/dsl/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,31 @@ func (p *parser) typeUnion() (*dmt.TypeDefnUnion, error) {
repr.Prefixes.Values[key] = *defn.Members[i].TypeName
}
defn.Representation.UnionRepresentation_StringPrefix = repr
case "inline":
optMap, err := p.consumeStringMap()
if err != nil {
return nil, err
}
discriminantKey, hasDiscriminantKey := optMap["discriminantKey"]
if !hasDiscriminantKey {
return nil, p.errf("no discriminantKey value provided for inline repr")
}
repr := &dmt.UnionRepresentation_Inline{
DiscriminantKey: discriminantKey,
DiscriminantTable: dmt.Map__String__TypeName{
Values: map[string]string{},
},
}
// TODO: verify member types all have map representation
for i, qkey := range reprKeys {
key, err := strconv.Unquote(qkey)
if err != nil {
return nil, fmt.Errorf("invalid discriminant key %q: %w", key, err)
}
repr.DiscriminantTable.Keys = append(repr.DiscriminantTable.Keys, key)
repr.DiscriminantTable.Values[key] = *defn.Members[i].TypeName
}
defn.Representation.UnionRepresentation_Inline = repr
default:
return nil, p.errf("TODO: union repr %q", reprName)
}
Expand Down
3 changes: 3 additions & 0 deletions schema/tmpBuilders.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ func SpawnUnionRepresentationKinded(table map[datamodel.Kind]TypeName) UnionRepr
func SpawnUnionRepresentationStringprefix(delim string, table map[string]TypeName) UnionRepresentation_Stringprefix {
return UnionRepresentation_Stringprefix{delim, table}
}
func SpawnUnionRepresentationInline(discriminantKey string, table map[string]TypeName) UnionRepresentation_Inline {
return UnionRepresentation_Inline{discriminantKey, table}
}

func SpawnEnum(name TypeName, members []string, repr EnumRepresentation) *TypeEnum {
return &TypeEnum{typeBase{name, nil}, members, repr}
Expand Down

0 comments on commit 65bfa53

Please sign in to comment.