From ec501fa9a83bdf8ea6cc7e0552d5a7f33a97fbff Mon Sep 17 00:00:00 2001 From: Eric Myhre Date: Sat, 14 Aug 2021 14:59:23 +0200 Subject: [PATCH] bindnode: support parsing stringprefix unions that have no explicit delimiter. In this case, the parsing checks each complete prefix. Errors are also returned when data is nonmatching, rather than panicking. --- node/bindnode/repr.go | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/node/bindnode/repr.go b/node/bindnode/repr.go index 1c344f5b..f3498f20 100644 --- a/node/bindnode/repr.go +++ b/node/bindnode/repr.go @@ -578,15 +578,29 @@ func (w *_assemblerRepr) AssignString(s string) error { } panic("TODO: GetMember result is missing?") case schema.UnionRepresentation_Stringprefix: - parts := strings.SplitN(s, stg.GetDelim(), 2) - if len(parts) != 2 { - panic("TODO: bad format") + hasDelim := stg.GetDelim() != "" + + var prefix, remainder string + if hasDelim { + parts := strings.SplitN(s, stg.GetDelim(), 2) + if len(parts) != 2 { + return fmt.Errorf("data doesn't match union type: type %s expects delimiter %q and it was not found in the data", w.schemaType.Name(), stg.GetDelim()) + } + prefix, remainder = parts[0], parts[1] } - name, value := parts[0], parts[1] + members := w.schemaType.(*schema.TypeUnion).Members() for idx, member := range members { - if stg.GetDiscriminant(member) != name { - continue + descrm := stg.GetDiscriminant(member) + if hasDelim { + if stg.GetDiscriminant(member) != prefix { + continue + } + } else { + if !strings.HasPrefix(s, descrm) { + continue + } + remainder = s[len(descrm):] } w2 := *w @@ -603,10 +617,9 @@ func (w *_assemblerRepr) AssignString(s string) error { unionSetMember(w.val, idx, valPtr) return nil } - - return w2.AssignString(value) + return w2.AssignString(remainder) } - panic("TODO: GetMember result is missing?") + return fmt.Errorf("data doesn't match union type: type %s couldn't match any of its prefixes to the data %q", w.schemaType.Name(), s) case nil: return (*_assembler)(w).AssignString(s) default: