Beispiel #1
0
// 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)
}
Beispiel #2
0
// 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)
}