Documentation ¶
Overview ¶
Package bindnode provides a datamodel.Node implementation via Go reflection.
This package is EXPERIMENTAL; its behavior and API might change as it's still in development.
Index ¶
- func ProduceGoTypes(w io.Writer, ts *schema.TypeSystem) error
- func Prototype(ptrType interface{}, schemaType schema.Type, options ...Option) schema.TypedPrototype
- func Unwrap(node datamodel.Node) (ptrVal interface{})
- func Wrap(ptrVal interface{}, schemaType schema.Type, options ...Option) schema.TypedNode
- type Option
- func TypedAnyConverter(ptrVal interface{}, from func(datamodel.Node) (interface{}, error), ...) Option
- func TypedBoolConverter(ptrVal interface{}, from func(bool) (interface{}, error), ...) Option
- func TypedBytesConverter(ptrVal interface{}, from func([]byte) (interface{}, error), ...) Option
- func TypedFloatConverter(ptrVal interface{}, from func(float64) (interface{}, error), ...) Option
- func TypedIntConverter(ptrVal interface{}, from func(int64) (interface{}, error), ...) Option
- func TypedLinkConverter(ptrVal interface{}, from func(cid.Cid) (interface{}, error), ...) Option
- func TypedStringConverter(ptrVal interface{}, from func(string) (interface{}, error), ...) Option
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ProduceGoTypes ¶ added in v0.14.0
func ProduceGoTypes(w io.Writer, ts *schema.TypeSystem) error
ProduceGoTypes infers Go types from an IPLD schema in ts and writes their Go source code type declarations to w. Note that just the types are written, without a package declaration nor any imports.
This gives a good starting point when wanting to use bindnode with Go types, but users will generally want to own and modify the types afterward, so they can add documentation or tweak the types as needed.
func Prototype ¶
func Prototype(ptrType interface{}, schemaType schema.Type, options ...Option) schema.TypedPrototype
Prototype implements a schema.TypedPrototype given a Go pointer type and an IPLD schema type. Note that the result is also a datamodel.NodePrototype.
If both the Go type and schema type are supplied, it is assumed that they are compatible with one another.
If either the Go type or schema type are nil, we infer the missing type from the other provided type. For example, we can infer an unnamed Go struct type for a schema struct type, and we can infer a schema Int type for a Go int64 type. The inferring logic is still a work in progress and subject to change. At this time, inferring IPLD Unions and Enums from Go types is not supported.
When supplying a non-nil ptrType, Prototype only obtains the Go pointer type from it, so its underlying value will typically be nil. For example:
proto := bindnode.Prototype((*goType)(nil), schemaType)
Example (OnlySchema) ¶
ts, err := ipld.LoadSchemaBytes([]byte(` type Person struct { Name String Age optional Int Friends [String] } `)) if err != nil { panic(err) } schemaType := ts.TypeByName("Person") proto := bindnode.Prototype(nil, schemaType) node, err := qp.BuildMap(proto, -1, func(ma datamodel.MapAssembler) { qp.MapEntry(ma, "Name", qp.String("Michael")) qp.MapEntry(ma, "Friends", qp.List(-1, func(la datamodel.ListAssembler) { qp.ListEntry(la, qp.String("Sarah")) qp.ListEntry(la, qp.String("Alex")) })) }) if err != nil { panic(err) } nodeRepr := node.(schema.TypedNode).Representation() dagjson.Encode(nodeRepr, os.Stdout)
Output: {"Friends":["Sarah","Alex"],"Name":"Michael"}
Example (Union) ¶
ts, err := ipld.LoadSchemaBytes([]byte(` type StringOrInt union { | String "hasString" | Int "hasInt" } representation keyed `)) if err != nil { panic(err) } schemaType := ts.TypeByName("StringOrInt") type CustomIntType int64 type StringOrInt struct { String *string Int *CustomIntType // We can use custom types, too. } proto := bindnode.Prototype((*StringOrInt)(nil), schemaType) node, err := qp.BuildMap(proto.Representation(), -1, func(ma datamodel.MapAssembler) { qp.MapEntry(ma, "hasInt", qp.Int(123)) }) if err != nil { panic(err) } fmt.Print("Type level DAG-JSON: ") dagjson.Encode(node, os.Stdout) fmt.Println() fmt.Print("Representation level DAG-JSON: ") nodeRepr := node.(schema.TypedNode).Representation() dagjson.Encode(nodeRepr, os.Stdout) fmt.Println() // Inspect what the underlying Go value contains. union := bindnode.Unwrap(node).(*StringOrInt) switch { case union.String != nil: fmt.Printf("Go StringOrInt.String: %v\n", *union.String) case union.Int != nil: fmt.Printf("Go StringOrInt.Int: %v\n", *union.Int) }
Output: Type level DAG-JSON: {"Int":123} Representation level DAG-JSON: {"hasInt":123} Go StringOrInt.Int: 123
func Unwrap ¶
Unwrap takes a datamodel.Node implemented by Prototype or Wrap, and returns a pointer to the inner Go value.
Unwrap returns nil if the node isn't implemented by this package.
func Wrap ¶ added in v0.11.0
Wrap implements a schema.TypedNode given a non-nil pointer to a Go value and an IPLD schema type. Note that the result is also a datamodel.Node.
Wrap is meant to be used when one already has a Go value with data. As such, ptrVal must not be nil.
Similar to Prototype, if schemaType is non-nil it is assumed to be compatible with the Go type, and otherwise it's inferred from the Go type.
Example (NoSchema) ¶
package main import ( "os" "github.com/ipld/go-ipld-prime/codec/dagjson" "github.com/ipld/go-ipld-prime/node/bindnode" ) func main() { type Person struct { Name string Age int64 // TODO: optional to match other examples Friends []string } person := &Person{ Name: "Michael", Friends: []string{"Sarah", "Alex"}, } node := bindnode.Wrap(person, nil) nodeRepr := node.Representation() dagjson.Encode(nodeRepr, os.Stdout) }
Output: {"Age":0,"Friends":["Sarah","Alex"],"Name":"Michael"}
Example (WithSchema) ¶
ts, err := ipld.LoadSchemaBytes([]byte(` type Person struct { Name String Age optional Int Friends optional [String] } `)) if err != nil { panic(err) } schemaType := ts.TypeByName("Person") type Person struct { Name string Age *int64 // optional Friends []string // optional; no need for a pointer as slices are nilable } person := &Person{ Name: "Michael", Friends: []string{"Sarah", "Alex"}, } node := bindnode.Wrap(person, schemaType) nodeRepr := node.Representation() dagjson.Encode(nodeRepr, os.Stdout)
Output: {"Friends":["Sarah","Alex"],"Name":"Michael"}
Types ¶
type Option ¶ added in v0.18.0
type Option func(config)
Option is able to apply custom options to the bindnode API
func TypedAnyConverter ¶ added in v0.18.0
func TypedAnyConverter(ptrVal interface{}, from func(datamodel.Node) (interface{}, error), to func(interface{}) (datamodel.Node, error)) Option
TypedAnyConverter adds custom converter functions for a particular type as identified by a pointer in the first argument. The fromFunc is of the form: func(datamodel.Node) (interface{}, error) and toFunc is of the form: func(interface{}) (datamodel.Node, error) where interface{} is a pointer form of the type we are converting.
This method should be able to deal with all forms of Any and return an error if the expected data forms don't match the expected.
TypedAnyConverter is an EXPERIMENTAL API and may be removed or changed in a future release.
func TypedBoolConverter ¶ added in v0.18.0
func TypedBoolConverter(ptrVal interface{}, from func(bool) (interface{}, error), to func(interface{}) (bool, error)) Option
TypedBoolConverter adds custom converter functions for a particular type as identified by a pointer in the first argument. The fromFunc is of the form: func(bool) (interface{}, error) and toFunc is of the form: func(interface{}) (bool, error) where interface{} is a pointer form of the type we are converting.
TypedBoolConverter is an EXPERIMENTAL API and may be removed or changed in a future release.
func TypedBytesConverter ¶ added in v0.18.0
func TypedBytesConverter(ptrVal interface{}, from func([]byte) (interface{}, error), to func(interface{}) ([]byte, error)) Option
TypedBytesConverter adds custom converter functions for a particular type as identified by a pointer in the first argument. The fromFunc is of the form: func([]byte) (interface{}, error) and toFunc is of the form: func(interface{}) ([]byte, error) where interface{} is a pointer form of the type we are converting.
TypedBytesConverter is an EXPERIMENTAL API and may be removed or changed in a future release.
func TypedFloatConverter ¶ added in v0.18.0
func TypedFloatConverter(ptrVal interface{}, from func(float64) (interface{}, error), to func(interface{}) (float64, error)) Option
TypedFloatConverter adds custom converter functions for a particular type as identified by a pointer in the first argument. The fromFunc is of the form: func(float64) (interface{}, error) and toFunc is of the form: func(interface{}) (float64, error) where interface{} is a pointer form of the type we are converting.
TypedFloatConverter is an EXPERIMENTAL API and may be removed or changed in a future release.
func TypedIntConverter ¶ added in v0.18.0
func TypedIntConverter(ptrVal interface{}, from func(int64) (interface{}, error), to func(interface{}) (int64, error)) Option
TypedIntConverter adds custom converter functions for a particular type as identified by a pointer in the first argument. The fromFunc is of the form: func(int64) (interface{}, error) and toFunc is of the form: func(interface{}) (int64, error) where interface{} is a pointer form of the type we are converting.
TypedIntConverter is an EXPERIMENTAL API and may be removed or changed in a future release.
func TypedLinkConverter ¶ added in v0.18.0
func TypedLinkConverter(ptrVal interface{}, from func(cid.Cid) (interface{}, error), to func(interface{}) (cid.Cid, error)) Option
TypedLinkConverter adds custom converter functions for a particular type as identified by a pointer in the first argument. The fromFunc is of the form: func([]byte) (interface{}, error) and toFunc is of the form: func(interface{}) ([]byte, error) where interface{} is a pointer form of the type we are converting.
Beware that this API is only compatible with cidlink.Link types in the data model and may result in errors if attempting to convert from other datamodel.Link types.
TypedLinkConverter is an EXPERIMENTAL API and may be removed or changed in a future release.
func TypedStringConverter ¶ added in v0.18.0
func TypedStringConverter(ptrVal interface{}, from func(string) (interface{}, error), to func(interface{}) (string, error)) Option
TypedStringConverter adds custom converter functions for a particular type as identified by a pointer in the first argument. The fromFunc is of the form: func(string) (interface{}, error) and toFunc is of the form: func(interface{}) (string, error) where interface{} is a pointer form of the type we are converting.
TypedStringConverter is an EXPERIMENTAL API and may be removed or changed in a future release.