// ValueList generates a new ValueList type alias for the given list. // // The following is generated: // // type $valueListName []$valueType // // func (v $valueListName) ForEach(f func(wire.Value) error) error { ... } // // func (v $valueListName) Close() { ... } // // And $valueListName is returned. This may be used where a ValueList of the // given type is expected. func (l *listGenerator) ValueList(g Generator, spec *compile.ListSpec) (string, error) { name := "_" + valueName(spec) + "_ValueList" if l.HasLazyList(name) { return name, nil } err := g.DeclareFromTemplate( ` <$wire := import "go.uber.org/thriftrw/wire"> type <.Name> <typeReference .Spec> <$i := newVar "i"> <$v := newVar "v"> <$x := newVar "x"> <$f := newVar "f"> <$w := newVar "w"> func (<$v> <.Name>) ForEach(<$f> func(<$wire>.Value) error) error { <if isPrimitiveType .Spec.ValueSpec> for _, <$x> := range <$v> { <else> for <$i>, <$x> := range <$v> { if <$x> == nil { return <import "fmt">.Errorf("invalid [%v]: value is nil", <$i>) } <end> <$w>, err := <toWire .Spec.ValueSpec $x> if err != nil { // TODO(abg): nested error "invalid [%v]: %v" return err } err = <$f>(<$w>) if err != nil { return err } } return nil } func (<$v> <.Name>) Size() int { return len(<$v>) } func (<.Name>) ValueType() <$wire>.Type { return <typeCode .Spec.ValueSpec> } func (<.Name>) Close() {} `, struct { Name string Spec *compile.ListSpec }{Name: name, Spec: spec}, ) return name, wrapGenerateError(spec.ThriftName(), err) }
// Reader generates a function to read a list of the given type from a // wire.List. // // func $name(l wire.List) ($listType, error) { // ... // } // // And returns its name. func (l *listGenerator) Reader(g Generator, spec *compile.ListSpec) (string, error) { name := "_" + valueName(spec) + "_Read" if l.HasReader(name) { return name, nil } err := g.DeclareFromTemplate( ` <$wire := import "go.uber.org/thriftrw/wire"> <$listType := typeReference .Spec> <$l := newVar "l"> <$i := newVar "i"> <$o := newVar "o"> <$x := newVar "x"> func <.Name>(<$l> <$wire>.ValueList) (<$listType>, error) { if <$l>.ValueType() != <typeCode .Spec.ValueSpec> { return nil, nil } <$o> := make(<$listType>, 0, <$l>.Size()) err := <$l>.ForEach(func(<$x> <$wire>.Value) error { <$i>, err := <fromWire .Spec.ValueSpec $x> if err != nil { return err } <$o> = append(<$o>, <$i>) return nil }) <$l>.Close() return <$o>, err } `, struct { Name string Spec *compile.ListSpec }{Name: name, Spec: spec}, ) return name, wrapGenerateError(spec.ThriftName(), err) }