-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Addtional examples of bindnode usage. #209
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
package bindnode_test | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"os" | ||
|
||
ipld "github.com/ipld/go-ipld-prime" | ||
|
@@ -80,3 +82,104 @@ func ExamplePrototype_onlySchema() { | |
// Output: | ||
// {"Friends":["Sarah","Alex"],"Name":"Michael"} | ||
} | ||
|
||
func ExampleWrap_withSchemaUsingStringjoinStruct() { | ||
ts := schema.TypeSystem{} | ||
ts.Init() | ||
ts.Accumulate(schema.SpawnString("String")) | ||
ts.Accumulate(schema.SpawnStruct("FooBarBaz", | ||
[]schema.StructField{ | ||
schema.SpawnStructField("foo", "String", false, false), | ||
schema.SpawnStructField("bar", "String", false, false), | ||
schema.SpawnStructField("baz", "String", false, false), | ||
}, | ||
schema.SpawnStructRepresentationStringjoin(":"), | ||
)) | ||
schemaType := ts.TypeByName("FooBarBaz") | ||
|
||
type FooBarBaz struct { | ||
Foo string | ||
Bar string | ||
Baz string | ||
} | ||
fbb := &FooBarBaz{ | ||
Foo: "x", | ||
Bar: "y", | ||
Baz: "z", | ||
} | ||
node := bindnode.Wrap(fbb, schemaType) | ||
|
||
// Take the representation of the node, and serialize it. | ||
nodeRepr := node.Representation() | ||
var buf bytes.Buffer | ||
dagjson.Encode(nodeRepr, &buf) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. check error? |
||
|
||
// Output how this was serialized, for the example. | ||
fmt.Fprintf(os.Stdout, "json: %s\n", buf.Bytes()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: for the sake of keeping the example simpler, you could just dagjson.Encode straight to os.Stdout, printing |
||
|
||
// Now unmarshal that again and print that too, to show it working both ways. | ||
np := bindnode.Prototype(&FooBarBaz{}, schemaType) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: you could just do |
||
nb := np.Representation().NewBuilder() | ||
err := dagjson.Decode(nb, &buf) | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Printf("golang: %#v\n", bindnode.Unwrap(nb.Build())) | ||
|
||
// Output: | ||
// json: "x:y:z" | ||
// golang: &bindnode_test.FooBarBaz{Foo:"x", Bar:"y", Baz:"z"} | ||
} | ||
|
||
func ExampleWrap_withSchemaUsingStringprefixUnion() { | ||
ts := schema.TypeSystem{} | ||
ts.Init() | ||
ts.Accumulate(schema.SpawnString("Foo")) | ||
ts.Accumulate(schema.SpawnString("Bar")) | ||
ts.Accumulate(schema.SpawnUnion("FooOrBar", | ||
[]schema.TypeName{ | ||
"Foo", | ||
"Bar", | ||
}, | ||
schema.SpawnUnionRepresentationStringprefix( | ||
":", // n.b. this API will change soon; a schema-schema iteration has removed the distinct joiner string. | ||
map[string]schema.TypeName{ | ||
"foo": "Foo", | ||
"bar": "Bar", | ||
}, | ||
), | ||
)) | ||
schemaType := ts.TypeByName("FooOrBar") | ||
|
||
// The golang structures for unions don't look as simple as one might like. Golang has no native sum types, so we do something interesting here. | ||
type FooOrBar struct { | ||
Index int | ||
Value interface{} | ||
} | ||
mvdan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
fob := &FooOrBar{ | ||
Index: 1, | ||
Value: "oi", | ||
} | ||
node := bindnode.Wrap(fob, schemaType) | ||
|
||
// Take the representation of the node, and serialize it. | ||
nodeRepr := node.Representation() | ||
var buf bytes.Buffer | ||
dagjson.Encode(nodeRepr, &buf) | ||
|
||
// Output how this was serialized, for the example. | ||
fmt.Fprintf(os.Stdout, "json: %s\n", buf.Bytes()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same comments as in the other example: error and buffer :) |
||
|
||
// Now unmarshal that again and print that too, to show it working both ways. | ||
np := bindnode.Prototype((*FooOrBar)(nil), schemaType) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: in one example you use |
||
nb := np.Representation().NewBuilder() | ||
err := dagjson.Decode(nb, &buf) | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Printf("golang: %#v\n", bindnode.Unwrap(nb.Build())) | ||
|
||
// Output: | ||
// json: "bar:oi" | ||
// golang: &bindnode_test.FooOrBar{Index:1, Value:"oi"} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is this mapping working? Does it just use field order to figure out what to assign where? So the schema could have any arbitrary name but the values get assigned to whatever order is there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, when mapping a provided IPLD schema with a provided Go type, it just cares about the "shape" matching, not any names. For a struct, that means that the fields should have matching types in the same order.
Doing the mapping via names or struct field tags would also be an option, though it would require more code and features, so I initially just went for the simplest approach from my point of view.
I haven't documented this, mind you, because I'm not 100% certain that this default behavior is right. I think most users would expect case-insensitive-matching by field name, similar to most other Go libraries. I'm not bothered by this example being public, but the semantics in this case might change.