Integrate BACKBEAT SDK and resolve KACHING license validation

Major integrations and fixes:
- Added BACKBEAT SDK integration for P2P operation timing
- Implemented beat-aware status tracking for distributed operations
- Added Docker secrets support for secure license management
- Resolved KACHING license validation via HTTPS/TLS
- Updated docker-compose configuration for clean stack deployment
- Disabled rollback policies to prevent deployment failures
- Added license credential storage (CHORUS-DEV-MULTI-001)

Technical improvements:
- BACKBEAT P2P operation tracking with phase management
- Enhanced configuration system with file-based secrets
- Improved error handling for license validation
- Clean separation of KACHING and CHORUS deployment stacks

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
anthonyrawlins
2025-09-06 07:56:26 +10:00
parent 543ab216f9
commit 9bdcbe0447
4730 changed files with 1480093 additions and 1916 deletions

View File

@@ -0,0 +1,146 @@
hackme
======
Design rationale are documented here.
This doc is not necessary reading for users of this package,
but if you're considering submitting patches -- or just trying to understand
why it was written this way, and check for reasoning that might be dated --
then it might be useful reading.
### scalars are just typedefs
This is noteworthy because in codegen, this is typically *not* the case:
in codegen, even scalar types are boxed in a struct, such that it prevents
casting values into those types.
This casting is not a concern for the node implementations in this package, because
- A) we don't have any kind of validation rules to make such casting worrying; and
- B) since our types are unexported, casting is still blocked by this anyway.
### about builders for scalars
The assembler types for scalars (string, int, etc) are pretty funny-looking.
You might wish to make them work without any state at all!
The reason this doesn't fly is that we have to keep the "wip" value in hand
just long enough to return it from the `NodeBuilder.Build` method -- the
`NodeAssembler` contract for `Assign*` methods doesn't permit just returning
their results immediately.
(Another possible reason is if we expected to use these assemblers on
slab-style allocations (say, `[]plainString`)...
however, this is inapplicable at present, because
A) we don't (except places that have special-case internal paths anyway); and
B) the types aren't exported, so users can't either.)
Does this mean that using `NodeBuilder` for scalars has a completely
unnecessary second allocation, which is laughably inefficient? Yes.
It's unfortunate the interfaces constrain us to this.
**But**: one typically doesn't actually use builders for scalars much;
they're just here for completeness.
So this is less of a problem in practice than it might at first seem.
More often, one will use the "any" builder (which is has a whole different set
of design constraints and tradeoffs);
or, if one is writing code and knows which scalar they need, the exported
direct constructor function for that kind
(e.g., `String("foo")` instead of `Prototype__String{}.NewBuilder().AssignString("foo")`)
will do the right thing and do it in one allocation (and it's less to type, too).
### maps and list keyAssembler and valueAssemblers have custom scalar handling
Related to the above heading.
Maps and lists in this package do their own internal handling of scalars,
using unexported features inside the package, because they can more efficient.
### when to invalidate the 'w' pointers
The 'w' pointer -- short for 'wip' node pointer -- has an interesting lifecycle.
In a NodeAssembler, the 'w' pointer should be intialized before the assembler is used.
This means either the matching NodeBuilder type does so; or,
if we're inside recursive structure, the parent assembler did so.
The 'w' pointer is used throughout the life of the assembler.
Setting the 'w' pointer to nil is one of two mechanisms used internally
to mark that assembly has become "finished" (the other mechanism is using
an internal state enum field).
Setting the 'w' pointer to nil has two advantages:
one is that it makes it *impossible* to continue to mutate the target node;
the other is that we need no *additional* memory to track this state change.
However, we can't use the strategy of nilling 'w' in all cases: in particular,
when in the NodeBuilder at the root of some construction,
we need to continue to hold onto the node between when it becomes "finished"
and when Build is called; otherwise we can't actually return the value!
Different stratgies are therefore used in different parts of this package.
Maps and lists use an internal state enum, because they already have one,
and so they might as well; there's no additional cost to this.
Since they can use this state to guard against additional mutations after "finish",
the map and list assemblers don't bother to nil their own 'w' at all.
During recursion to assemble values _inside_ maps and lists, it's interesting:
the child assembler wrapper type takes reponsibility for nilling out
the 'w' pointer in the child assembler's state, doing this at the same time as
it updates the parent's state machine to clear proceeding with the next entry.
In the case of scalars at the root of a build, we took a shortcut:
we actually don't fence against repeat mutations at all.
*You can actually use the assign method more than once*.
We can do this without breaking safety contracts because the scalars
all have a pass-by-value phase somewhere in their lifecycle
(calling `nb.AssignString("x")`, then `n := nb.Build()`, then `nb.AssignString("y")`
won't error if `nb` is a freestanding builder for strings... but it also
won't result in mutating `n` to contain `"y"`, so overall, it's safe).
We could normalize the case with scalars at the root of a tree so that they
error more aggressively... but currently we haven't bothered, since this would
require adding another piece of memory to the scalar builders; and meanwhile
we're not in trouble on compositional correctness.
Note that these remarks are for the `basicnode` package, but may also
apply to other implementations too (e.g., our codegen output follows similar
overall logic).
### NodePrototypes are available through a singleton
Every NodePrototype available from this package is exposed as a field
in a struct of which there's one public exported instance available,
called 'Prototype'.
This means you can use it like this:
```go
nbm := basicnode.Prototype.Map.NewBuilder()
nbs := basicnode.Prototype.String.NewBuilder()
nba := basicnode.Prototype.Any.NewBuilder()
// etc
```
(If you're interested in the performance of this: it's free!
Methods called at the end of the chain are inlinable.
Since all of the types of the structures on the way there are zero-member
structs, the compiler can effectively treat them as constants,
and thus freely elide any memory dereferences that would
otherwise be necessary to get methods on such a value.)
### NodePrototypes are (also) available as exported concrete types
The 'Prototype' singleton is one way to access the NodePrototype in this package;
their exported types are another equivalent way.
```go
basicnode.Prototype.Map = basicnode.Prototype.Map
```
It is recommended to use the singleton style;
they compile to identical assembly, and the singleton is syntactically prettier.
We may make these concrete types unexported in the future.
A decision on this is deferred until some time has passed and
we can accumulate reasonable certainty that there's no need for an exported type
(such as type assertions, etc).

View File

@@ -0,0 +1,197 @@
package basicnode
import (
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/linking"
)
var (
//_ datamodel.Node = &anyNode{}
_ datamodel.NodePrototype = Prototype__Any{}
_ datamodel.NodeBuilder = &anyBuilder{}
//_ datamodel.NodeAssembler = &anyAssembler{}
)
// Note that we don't use a "var _" declaration to assert that Chooser
// implements traversal.LinkTargetNodePrototypeChooser, to keep basicnode's
// dependencies fairly light.
// Chooser implements traversal.LinkTargetNodePrototypeChooser.
//
// It can be used directly when loading links into the "any" prototype,
// or with another chooser layer on top, such as:
//
// prototypeChooser := dagpb.AddSupportToChooser(basicnode.Chooser)
func Chooser(_ datamodel.Link, _ linking.LinkContext) (datamodel.NodePrototype, error) {
return Prototype.Any, nil
}
// -- Node interface methods -->
// Unimplemented at present -- see "REVIEW" comment on anyNode.
// -- NodePrototype -->
type Prototype__Any struct{}
func (Prototype__Any) NewBuilder() datamodel.NodeBuilder {
return &anyBuilder{}
}
// -- NodeBuilder -->
// anyBuilder is a builder for any kind of node.
//
// anyBuilder is a little unusual in its internal workings:
// unlike most builders, it doesn't embed the corresponding assembler,
// nor will it end up using anyNode,
// but instead embeds a builder for each of the kinds it might contain.
// This is because we want a more granular return at the end:
// if we used anyNode, and returned a pointer to just the relevant part of it,
// we'd have all the extra bytes of anyNode still reachable in GC terms
// for as long as that handle to the interior of it remains live.
type anyBuilder struct {
// kind is set on first interaction, and used to select which builder to delegate 'Build' to!
// As soon as it's been set to a value other than zero (being "Invalid"), all other Assign/Begin calls will fail since something is already in progress.
// May also be set to the magic value '99', which means "i dunno, I'm just carrying another node of unknown prototype".
kind datamodel.Kind
// Only one of the following ends up being used...
// but we don't know in advance which one, so all are embeded here.
// This uses excessive space, but amortizes allocations, and all will be
// freed as soon as the builder is done.
// Builders are only used for recursives;
// scalars are simple enough we just do them directly.
// 'scalarNode' may also hold another Node of unknown prototype (possibly not even from this package),
// in which case this is indicated by 'kind==99'.
mapBuilder plainMap__Builder
listBuilder plainList__Builder
scalarNode datamodel.Node
}
func (nb *anyBuilder) Reset() {
*nb = anyBuilder{}
}
func (nb *anyBuilder) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) {
if nb.kind != datamodel.Kind_Invalid {
panic("misuse")
}
nb.kind = datamodel.Kind_Map
nb.mapBuilder.w = &plainMap{}
return nb.mapBuilder.BeginMap(sizeHint)
}
func (nb *anyBuilder) BeginList(sizeHint int64) (datamodel.ListAssembler, error) {
if nb.kind != datamodel.Kind_Invalid {
panic("misuse")
}
nb.kind = datamodel.Kind_List
nb.listBuilder.w = &plainList{}
return nb.listBuilder.BeginList(sizeHint)
}
func (nb *anyBuilder) AssignNull() error {
if nb.kind != datamodel.Kind_Invalid {
panic("misuse")
}
nb.kind = datamodel.Kind_Null
return nil
}
func (nb *anyBuilder) AssignBool(v bool) error {
if nb.kind != datamodel.Kind_Invalid {
panic("misuse")
}
nb.kind = datamodel.Kind_Bool
nb.scalarNode = NewBool(v)
return nil
}
func (nb *anyBuilder) AssignInt(v int64) error {
if nb.kind != datamodel.Kind_Invalid {
panic("misuse")
}
nb.kind = datamodel.Kind_Int
nb.scalarNode = NewInt(v)
return nil
}
func (nb *anyBuilder) AssignFloat(v float64) error {
if nb.kind != datamodel.Kind_Invalid {
panic("misuse")
}
nb.kind = datamodel.Kind_Float
nb.scalarNode = NewFloat(v)
return nil
}
func (nb *anyBuilder) AssignString(v string) error {
if nb.kind != datamodel.Kind_Invalid {
panic("misuse")
}
nb.kind = datamodel.Kind_String
nb.scalarNode = NewString(v)
return nil
}
func (nb *anyBuilder) AssignBytes(v []byte) error {
if nb.kind != datamodel.Kind_Invalid {
panic("misuse")
}
nb.kind = datamodel.Kind_Bytes
nb.scalarNode = NewBytes(v)
return nil
}
func (nb *anyBuilder) AssignLink(v datamodel.Link) error {
if nb.kind != datamodel.Kind_Invalid {
panic("misuse")
}
nb.kind = datamodel.Kind_Link
nb.scalarNode = NewLink(v)
return nil
}
func (nb *anyBuilder) AssignNode(v datamodel.Node) error {
if nb.kind != datamodel.Kind_Invalid {
panic("misuse")
}
nb.kind = 99
nb.scalarNode = v
return nil
}
func (anyBuilder) Prototype() datamodel.NodePrototype {
return Prototype.Any
}
func (nb *anyBuilder) Build() datamodel.Node {
switch nb.kind {
case datamodel.Kind_Invalid:
panic("misuse")
case datamodel.Kind_Map:
return nb.mapBuilder.Build()
case datamodel.Kind_List:
return nb.listBuilder.Build()
case datamodel.Kind_Null:
return datamodel.Null
case datamodel.Kind_Bool:
return nb.scalarNode
case datamodel.Kind_Int:
return nb.scalarNode
case datamodel.Kind_Float:
return nb.scalarNode
case datamodel.Kind_String:
return nb.scalarNode
case datamodel.Kind_Bytes:
return nb.scalarNode
case datamodel.Kind_Link:
return nb.scalarNode
case 99:
return nb.scalarNode
default:
panic("unreachable")
}
}
// -- NodeAssembler -->
// ... oddly enough, we seem to be able to put off implementing this
// until we also implement something that goes full-hog on amortization
// and actually has a slab of `anyNode`. Which so far, nothing does.
// See "REVIEW" comment on anyNode.
// type anyAssembler struct {
// w *anyNode
// }

View File

@@ -0,0 +1,144 @@
package basicnode
import (
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/node/mixins"
)
var (
_ datamodel.Node = plainBool(false)
_ datamodel.NodePrototype = Prototype__Bool{}
_ datamodel.NodeBuilder = &plainBool__Builder{}
_ datamodel.NodeAssembler = &plainBool__Assembler{}
)
func NewBool(value bool) datamodel.Node {
v := plainBool(value)
return &v
}
// plainBool is a simple boxed boolean that complies with datamodel.Node.
type plainBool bool
// -- Node interface methods -->
func (plainBool) Kind() datamodel.Kind {
return datamodel.Kind_Bool
}
func (plainBool) LookupByString(string) (datamodel.Node, error) {
return mixins.Bool{TypeName: "bool"}.LookupByString("")
}
func (plainBool) LookupByNode(key datamodel.Node) (datamodel.Node, error) {
return mixins.Bool{TypeName: "bool"}.LookupByNode(nil)
}
func (plainBool) LookupByIndex(idx int64) (datamodel.Node, error) {
return mixins.Bool{TypeName: "bool"}.LookupByIndex(0)
}
func (plainBool) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) {
return mixins.Bool{TypeName: "bool"}.LookupBySegment(seg)
}
func (plainBool) MapIterator() datamodel.MapIterator {
return nil
}
func (plainBool) ListIterator() datamodel.ListIterator {
return nil
}
func (plainBool) Length() int64 {
return -1
}
func (plainBool) IsAbsent() bool {
return false
}
func (plainBool) IsNull() bool {
return false
}
func (n plainBool) AsBool() (bool, error) {
return bool(n), nil
}
func (plainBool) AsInt() (int64, error) {
return mixins.Bool{TypeName: "bool"}.AsInt()
}
func (plainBool) AsFloat() (float64, error) {
return mixins.Bool{TypeName: "bool"}.AsFloat()
}
func (plainBool) AsString() (string, error) {
return mixins.Bool{TypeName: "bool"}.AsString()
}
func (plainBool) AsBytes() ([]byte, error) {
return mixins.Bool{TypeName: "bool"}.AsBytes()
}
func (plainBool) AsLink() (datamodel.Link, error) {
return mixins.Bool{TypeName: "bool"}.AsLink()
}
func (plainBool) Prototype() datamodel.NodePrototype {
return Prototype__Bool{}
}
// -- NodePrototype -->
type Prototype__Bool struct{}
func (Prototype__Bool) NewBuilder() datamodel.NodeBuilder {
var w plainBool
return &plainBool__Builder{plainBool__Assembler{w: &w}}
}
// -- NodeBuilder -->
type plainBool__Builder struct {
plainBool__Assembler
}
func (nb *plainBool__Builder) Build() datamodel.Node {
return nb.w
}
func (nb *plainBool__Builder) Reset() {
var w plainBool
*nb = plainBool__Builder{plainBool__Assembler{w: &w}}
}
// -- NodeAssembler -->
type plainBool__Assembler struct {
w *plainBool
}
func (plainBool__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) {
return mixins.BoolAssembler{TypeName: "bool"}.BeginMap(0)
}
func (plainBool__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) {
return mixins.BoolAssembler{TypeName: "bool"}.BeginList(0)
}
func (plainBool__Assembler) AssignNull() error {
return mixins.BoolAssembler{TypeName: "bool"}.AssignNull()
}
func (na *plainBool__Assembler) AssignBool(v bool) error {
*na.w = plainBool(v)
return nil
}
func (plainBool__Assembler) AssignInt(int64) error {
return mixins.BoolAssembler{TypeName: "bool"}.AssignInt(0)
}
func (plainBool__Assembler) AssignFloat(float64) error {
return mixins.BoolAssembler{TypeName: "bool"}.AssignFloat(0)
}
func (plainBool__Assembler) AssignString(string) error {
return mixins.BoolAssembler{TypeName: "bool"}.AssignString("")
}
func (plainBool__Assembler) AssignBytes([]byte) error {
return mixins.BoolAssembler{TypeName: "bool"}.AssignBytes(nil)
}
func (plainBool__Assembler) AssignLink(datamodel.Link) error {
return mixins.BoolAssembler{TypeName: "bool"}.AssignLink(nil)
}
func (na *plainBool__Assembler) AssignNode(v datamodel.Node) error {
if v2, err := v.AsBool(); err != nil {
return err
} else {
*na.w = plainBool(v2)
return nil
}
}
func (plainBool__Assembler) Prototype() datamodel.NodePrototype {
return Prototype__Bool{}
}

View File

@@ -0,0 +1,157 @@
package basicnode
import (
"bytes"
"io"
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/node/mixins"
)
var (
_ datamodel.Node = plainBytes(nil)
_ datamodel.NodePrototype = Prototype__Bytes{}
_ datamodel.NodeBuilder = &plainBytes__Builder{}
_ datamodel.NodeAssembler = &plainBytes__Assembler{}
)
func NewBytes(value []byte) datamodel.Node {
v := plainBytes(value)
return &v
}
// plainBytes is a simple boxed byte slice that complies with datamodel.Node.
type plainBytes []byte
// -- Node interface methods -->
func (plainBytes) Kind() datamodel.Kind {
return datamodel.Kind_Bytes
}
func (plainBytes) LookupByString(string) (datamodel.Node, error) {
return mixins.Bytes{TypeName: "bytes"}.LookupByString("")
}
func (plainBytes) LookupByNode(key datamodel.Node) (datamodel.Node, error) {
return mixins.Bytes{TypeName: "bytes"}.LookupByNode(nil)
}
func (plainBytes) LookupByIndex(idx int64) (datamodel.Node, error) {
return mixins.Bytes{TypeName: "bytes"}.LookupByIndex(0)
}
func (plainBytes) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) {
return mixins.Bytes{TypeName: "bytes"}.LookupBySegment(seg)
}
func (plainBytes) MapIterator() datamodel.MapIterator {
return nil
}
func (plainBytes) ListIterator() datamodel.ListIterator {
return nil
}
func (plainBytes) Length() int64 {
return -1
}
func (plainBytes) IsAbsent() bool {
return false
}
func (plainBytes) IsNull() bool {
return false
}
func (plainBytes) AsBool() (bool, error) {
return mixins.Bytes{TypeName: "bytes"}.AsBool()
}
func (plainBytes) AsInt() (int64, error) {
return mixins.Bytes{TypeName: "bytes"}.AsInt()
}
func (plainBytes) AsFloat() (float64, error) {
return mixins.Bytes{TypeName: "bytes"}.AsFloat()
}
func (plainBytes) AsString() (string, error) {
return mixins.Bytes{TypeName: "bytes"}.AsString()
}
func (n plainBytes) AsBytes() ([]byte, error) {
return []byte(n), nil
}
func (plainBytes) AsLink() (datamodel.Link, error) {
return mixins.Bytes{TypeName: "bytes"}.AsLink()
}
func (plainBytes) Prototype() datamodel.NodePrototype {
return Prototype__Bytes{}
}
func (n plainBytes) AsLargeBytes() (io.ReadSeeker, error) {
return bytes.NewReader(n), nil
}
// -- NodePrototype -->
type Prototype__Bytes struct{}
func (Prototype__Bytes) NewBuilder() datamodel.NodeBuilder {
var w plainBytes
return &plainBytes__Builder{plainBytes__Assembler{w: &w}}
}
// -- NodeBuilder -->
type plainBytes__Builder struct {
plainBytes__Assembler
}
func (nb *plainBytes__Builder) Build() datamodel.Node {
return nb.w
}
func (nb *plainBytes__Builder) Reset() {
var w plainBytes
*nb = plainBytes__Builder{plainBytes__Assembler{w: &w}}
}
// -- NodeAssembler -->
type plainBytes__Assembler struct {
w datamodel.Node
}
func (plainBytes__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) {
return mixins.BytesAssembler{TypeName: "bytes"}.BeginMap(0)
}
func (plainBytes__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) {
return mixins.BytesAssembler{TypeName: "bytes"}.BeginList(0)
}
func (plainBytes__Assembler) AssignNull() error {
return mixins.BytesAssembler{TypeName: "bytes"}.AssignNull()
}
func (plainBytes__Assembler) AssignBool(bool) error {
return mixins.BytesAssembler{TypeName: "bytes"}.AssignBool(false)
}
func (plainBytes__Assembler) AssignInt(int64) error {
return mixins.BytesAssembler{TypeName: "bytes"}.AssignInt(0)
}
func (plainBytes__Assembler) AssignFloat(float64) error {
return mixins.BytesAssembler{TypeName: "bytes"}.AssignFloat(0)
}
func (plainBytes__Assembler) AssignString(string) error {
return mixins.BytesAssembler{TypeName: "bytes"}.AssignString("")
}
func (na *plainBytes__Assembler) AssignBytes(v []byte) error {
na.w = datamodel.Node(plainBytes(v))
return nil
}
func (plainBytes__Assembler) AssignLink(datamodel.Link) error {
return mixins.BytesAssembler{TypeName: "bytes"}.AssignLink(nil)
}
func (na *plainBytes__Assembler) AssignNode(v datamodel.Node) error {
if lb, ok := v.(datamodel.LargeBytesNode); ok {
lbn, err := lb.AsLargeBytes()
if err == nil {
na.w = streamBytes{lbn}
return nil
}
}
if v2, err := v.AsBytes(); err != nil {
return err
} else {
na.w = plainBytes(v2)
return nil
}
}
func (plainBytes__Assembler) Prototype() datamodel.NodePrototype {
return Prototype__Bytes{}
}

View File

@@ -0,0 +1,81 @@
package basicnode
import (
"io"
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/node/mixins"
)
var (
_ datamodel.Node = streamBytes{nil}
_ datamodel.NodePrototype = Prototype__Bytes{}
_ datamodel.NodeBuilder = &plainBytes__Builder{}
_ datamodel.NodeAssembler = &plainBytes__Assembler{}
)
func NewBytesFromReader(rs io.ReadSeeker) datamodel.Node {
return streamBytes{rs}
}
// streamBytes is a boxed reader that complies with datamodel.Node.
type streamBytes struct {
io.ReadSeeker
}
// -- Node interface methods -->
func (streamBytes) Kind() datamodel.Kind {
return datamodel.Kind_Bytes
}
func (streamBytes) LookupByString(string) (datamodel.Node, error) {
return mixins.Bytes{TypeName: "bytes"}.LookupByString("")
}
func (streamBytes) LookupByNode(key datamodel.Node) (datamodel.Node, error) {
return mixins.Bytes{TypeName: "bytes"}.LookupByNode(nil)
}
func (streamBytes) LookupByIndex(idx int64) (datamodel.Node, error) {
return mixins.Bytes{TypeName: "bytes"}.LookupByIndex(0)
}
func (streamBytes) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) {
return mixins.Bytes{TypeName: "bytes"}.LookupBySegment(seg)
}
func (streamBytes) MapIterator() datamodel.MapIterator {
return nil
}
func (streamBytes) ListIterator() datamodel.ListIterator {
return nil
}
func (streamBytes) Length() int64 {
return -1
}
func (streamBytes) IsAbsent() bool {
return false
}
func (streamBytes) IsNull() bool {
return false
}
func (streamBytes) AsBool() (bool, error) {
return mixins.Bytes{TypeName: "bytes"}.AsBool()
}
func (streamBytes) AsInt() (int64, error) {
return mixins.Bytes{TypeName: "bytes"}.AsInt()
}
func (streamBytes) AsFloat() (float64, error) {
return mixins.Bytes{TypeName: "bytes"}.AsFloat()
}
func (streamBytes) AsString() (string, error) {
return mixins.Bytes{TypeName: "bytes"}.AsString()
}
func (n streamBytes) AsBytes() ([]byte, error) {
return io.ReadAll(n)
}
func (streamBytes) AsLink() (datamodel.Link, error) {
return mixins.Bytes{TypeName: "bytes"}.AsLink()
}
func (streamBytes) Prototype() datamodel.NodePrototype {
return Prototype__Bytes{}
}
func (n streamBytes) AsLargeBytes() (io.ReadSeeker, error) {
return n.ReadSeeker, nil
}

View File

@@ -0,0 +1,144 @@
package basicnode
import (
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/node/mixins"
)
var (
_ datamodel.Node = plainFloat(0)
_ datamodel.NodePrototype = Prototype__Float{}
_ datamodel.NodeBuilder = &plainFloat__Builder{}
_ datamodel.NodeAssembler = &plainFloat__Assembler{}
)
func NewFloat(value float64) datamodel.Node {
v := plainFloat(value)
return &v
}
// plainFloat is a simple boxed float that complies with datamodel.Node.
type plainFloat float64
// -- Node interface methods -->
func (plainFloat) Kind() datamodel.Kind {
return datamodel.Kind_Float
}
func (plainFloat) LookupByString(string) (datamodel.Node, error) {
return mixins.Float{TypeName: "float"}.LookupByString("")
}
func (plainFloat) LookupByNode(key datamodel.Node) (datamodel.Node, error) {
return mixins.Float{TypeName: "float"}.LookupByNode(nil)
}
func (plainFloat) LookupByIndex(idx int64) (datamodel.Node, error) {
return mixins.Float{TypeName: "float"}.LookupByIndex(0)
}
func (plainFloat) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) {
return mixins.Float{TypeName: "float"}.LookupBySegment(seg)
}
func (plainFloat) MapIterator() datamodel.MapIterator {
return nil
}
func (plainFloat) ListIterator() datamodel.ListIterator {
return nil
}
func (plainFloat) Length() int64 {
return -1
}
func (plainFloat) IsAbsent() bool {
return false
}
func (plainFloat) IsNull() bool {
return false
}
func (plainFloat) AsBool() (bool, error) {
return mixins.Float{TypeName: "float"}.AsBool()
}
func (plainFloat) AsInt() (int64, error) {
return mixins.Float{TypeName: "float"}.AsInt()
}
func (n plainFloat) AsFloat() (float64, error) {
return float64(n), nil
}
func (plainFloat) AsString() (string, error) {
return mixins.Float{TypeName: "float"}.AsString()
}
func (plainFloat) AsBytes() ([]byte, error) {
return mixins.Float{TypeName: "float"}.AsBytes()
}
func (plainFloat) AsLink() (datamodel.Link, error) {
return mixins.Float{TypeName: "float"}.AsLink()
}
func (plainFloat) Prototype() datamodel.NodePrototype {
return Prototype__Float{}
}
// -- NodePrototype -->
type Prototype__Float struct{}
func (Prototype__Float) NewBuilder() datamodel.NodeBuilder {
var w plainFloat
return &plainFloat__Builder{plainFloat__Assembler{w: &w}}
}
// -- NodeBuilder -->
type plainFloat__Builder struct {
plainFloat__Assembler
}
func (nb *plainFloat__Builder) Build() datamodel.Node {
return nb.w
}
func (nb *plainFloat__Builder) Reset() {
var w plainFloat
*nb = plainFloat__Builder{plainFloat__Assembler{w: &w}}
}
// -- NodeAssembler -->
type plainFloat__Assembler struct {
w *plainFloat
}
func (plainFloat__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) {
return mixins.FloatAssembler{TypeName: "float"}.BeginMap(0)
}
func (plainFloat__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) {
return mixins.FloatAssembler{TypeName: "float"}.BeginList(0)
}
func (plainFloat__Assembler) AssignNull() error {
return mixins.FloatAssembler{TypeName: "float"}.AssignNull()
}
func (plainFloat__Assembler) AssignBool(bool) error {
return mixins.FloatAssembler{TypeName: "float"}.AssignBool(false)
}
func (plainFloat__Assembler) AssignInt(int64) error {
return mixins.FloatAssembler{TypeName: "float"}.AssignInt(0)
}
func (na *plainFloat__Assembler) AssignFloat(v float64) error {
*na.w = plainFloat(v)
return nil
}
func (plainFloat__Assembler) AssignString(string) error {
return mixins.FloatAssembler{TypeName: "float"}.AssignString("")
}
func (plainFloat__Assembler) AssignBytes([]byte) error {
return mixins.FloatAssembler{TypeName: "float"}.AssignBytes(nil)
}
func (plainFloat__Assembler) AssignLink(datamodel.Link) error {
return mixins.FloatAssembler{TypeName: "float"}.AssignLink(nil)
}
func (na *plainFloat__Assembler) AssignNode(v datamodel.Node) error {
if v2, err := v.AsFloat(); err != nil {
return err
} else {
*na.w = plainFloat(v2)
return nil
}
}
func (plainFloat__Assembler) Prototype() datamodel.NodePrototype {
return Prototype__Float{}
}

View File

@@ -0,0 +1,226 @@
package basicnode
import (
"fmt"
"math"
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/node/mixins"
)
var (
_ datamodel.Node = plainInt(0)
_ datamodel.Node = plainUint(0)
_ datamodel.UintNode = plainUint(0)
_ datamodel.NodePrototype = Prototype__Int{}
_ datamodel.NodeBuilder = &plainInt__Builder{}
_ datamodel.NodeAssembler = &plainInt__Assembler{}
)
func NewInt(value int64) datamodel.Node {
return plainInt(value)
}
// NewUint creates a new uint64-backed Node which will behave as a plain Int
// node but also conforms to the datamodel.UintNode interface which can access
// the full uint64 range.
//
// EXPERIMENTAL: this API is experimental and may be changed or removed in a
// future release.
func NewUint(value uint64) datamodel.Node {
return plainUint(value)
}
// plainInt is a simple boxed int that complies with datamodel.Node.
type plainInt int64
// -- Node interface methods for plainInt -->
func (plainInt) Kind() datamodel.Kind {
return datamodel.Kind_Int
}
func (plainInt) LookupByString(string) (datamodel.Node, error) {
return mixins.Int{TypeName: "int"}.LookupByString("")
}
func (plainInt) LookupByNode(key datamodel.Node) (datamodel.Node, error) {
return mixins.Int{TypeName: "int"}.LookupByNode(nil)
}
func (plainInt) LookupByIndex(idx int64) (datamodel.Node, error) {
return mixins.Int{TypeName: "int"}.LookupByIndex(0)
}
func (plainInt) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) {
return mixins.Int{TypeName: "int"}.LookupBySegment(seg)
}
func (plainInt) MapIterator() datamodel.MapIterator {
return nil
}
func (plainInt) ListIterator() datamodel.ListIterator {
return nil
}
func (plainInt) Length() int64 {
return -1
}
func (plainInt) IsAbsent() bool {
return false
}
func (plainInt) IsNull() bool {
return false
}
func (plainInt) AsBool() (bool, error) {
return mixins.Int{TypeName: "int"}.AsBool()
}
func (n plainInt) AsInt() (int64, error) {
return int64(n), nil
}
func (plainInt) AsFloat() (float64, error) {
return mixins.Int{TypeName: "int"}.AsFloat()
}
func (plainInt) AsString() (string, error) {
return mixins.Int{TypeName: "int"}.AsString()
}
func (plainInt) AsBytes() ([]byte, error) {
return mixins.Int{TypeName: "int"}.AsBytes()
}
func (plainInt) AsLink() (datamodel.Link, error) {
return mixins.Int{TypeName: "int"}.AsLink()
}
func (plainInt) Prototype() datamodel.NodePrototype {
return Prototype__Int{}
}
// plainUint is a simple boxed uint64 that complies with datamodel.Node,
// allowing representation of the uint64 range above the int64 maximum via the
// UintNode interface
type plainUint uint64
// -- Node interface methods for plainUint -->
func (plainUint) Kind() datamodel.Kind {
return datamodel.Kind_Int
}
func (plainUint) LookupByString(string) (datamodel.Node, error) {
return mixins.Int{TypeName: "int"}.LookupByString("")
}
func (plainUint) LookupByNode(key datamodel.Node) (datamodel.Node, error) {
return mixins.Int{TypeName: "int"}.LookupByNode(nil)
}
func (plainUint) LookupByIndex(idx int64) (datamodel.Node, error) {
return mixins.Int{TypeName: "int"}.LookupByIndex(0)
}
func (plainUint) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) {
return mixins.Int{TypeName: "int"}.LookupBySegment(seg)
}
func (plainUint) MapIterator() datamodel.MapIterator {
return nil
}
func (plainUint) ListIterator() datamodel.ListIterator {
return nil
}
func (plainUint) Length() int64 {
return -1
}
func (plainUint) IsAbsent() bool {
return false
}
func (plainUint) IsNull() bool {
return false
}
func (plainUint) AsBool() (bool, error) {
return mixins.Int{TypeName: "int"}.AsBool()
}
func (n plainUint) AsInt() (int64, error) {
if uint64(n) > uint64(math.MaxInt64) {
return -1, fmt.Errorf("unsigned integer out of range of int64 type")
}
return int64(n), nil
}
func (plainUint) AsFloat() (float64, error) {
return mixins.Int{TypeName: "int"}.AsFloat()
}
func (plainUint) AsString() (string, error) {
return mixins.Int{TypeName: "int"}.AsString()
}
func (plainUint) AsBytes() ([]byte, error) {
return mixins.Int{TypeName: "int"}.AsBytes()
}
func (plainUint) AsLink() (datamodel.Link, error) {
return mixins.Int{TypeName: "int"}.AsLink()
}
func (plainUint) Prototype() datamodel.NodePrototype {
return Prototype__Int{}
}
// allows plainUint to conform to the plainUint interface
func (n plainUint) AsUint() (uint64, error) {
return uint64(n), nil
}
// -- NodePrototype -->
type Prototype__Int struct{}
func (Prototype__Int) NewBuilder() datamodel.NodeBuilder {
var w plainInt
return &plainInt__Builder{plainInt__Assembler{w: &w}}
}
// -- NodeBuilder -->
type plainInt__Builder struct {
plainInt__Assembler
}
func (nb *plainInt__Builder) Build() datamodel.Node {
return nb.w
}
func (nb *plainInt__Builder) Reset() {
var w plainInt
*nb = plainInt__Builder{plainInt__Assembler{w: &w}}
}
// -- NodeAssembler -->
type plainInt__Assembler struct {
w *plainInt
}
func (plainInt__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) {
return mixins.IntAssembler{TypeName: "int"}.BeginMap(0)
}
func (plainInt__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) {
return mixins.IntAssembler{TypeName: "int"}.BeginList(0)
}
func (plainInt__Assembler) AssignNull() error {
return mixins.IntAssembler{TypeName: "int"}.AssignNull()
}
func (plainInt__Assembler) AssignBool(bool) error {
return mixins.IntAssembler{TypeName: "int"}.AssignBool(false)
}
func (na *plainInt__Assembler) AssignInt(v int64) error {
*na.w = plainInt(v)
return nil
}
func (plainInt__Assembler) AssignFloat(float64) error {
return mixins.IntAssembler{TypeName: "int"}.AssignFloat(0)
}
func (plainInt__Assembler) AssignString(string) error {
return mixins.IntAssembler{TypeName: "int"}.AssignString("")
}
func (plainInt__Assembler) AssignBytes([]byte) error {
return mixins.IntAssembler{TypeName: "int"}.AssignBytes(nil)
}
func (plainInt__Assembler) AssignLink(datamodel.Link) error {
return mixins.IntAssembler{TypeName: "int"}.AssignLink(nil)
}
func (na *plainInt__Assembler) AssignNode(v datamodel.Node) error {
if v2, err := v.AsInt(); err != nil {
return err
} else {
*na.w = plainInt(v2)
return nil
}
}
func (plainInt__Assembler) Prototype() datamodel.NodePrototype {
return Prototype__Int{}
}

View File

@@ -0,0 +1,145 @@
package basicnode
import (
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/node/mixins"
)
var (
_ datamodel.Node = &plainLink{}
_ datamodel.NodePrototype = Prototype__Link{}
_ datamodel.NodeBuilder = &plainLink__Builder{}
_ datamodel.NodeAssembler = &plainLink__Assembler{}
)
func NewLink(value datamodel.Link) datamodel.Node {
return &plainLink{value}
}
// plainLink is a simple box around a Link that complies with datamodel.Node.
type plainLink struct {
x datamodel.Link
}
// -- Node interface methods -->
func (plainLink) Kind() datamodel.Kind {
return datamodel.Kind_Link
}
func (plainLink) LookupByString(string) (datamodel.Node, error) {
return mixins.Link{TypeName: "link"}.LookupByString("")
}
func (plainLink) LookupByNode(key datamodel.Node) (datamodel.Node, error) {
return mixins.Link{TypeName: "link"}.LookupByNode(nil)
}
func (plainLink) LookupByIndex(idx int64) (datamodel.Node, error) {
return mixins.Link{TypeName: "link"}.LookupByIndex(0)
}
func (plainLink) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) {
return mixins.Link{TypeName: "link"}.LookupBySegment(seg)
}
func (plainLink) MapIterator() datamodel.MapIterator {
return nil
}
func (plainLink) ListIterator() datamodel.ListIterator {
return nil
}
func (plainLink) Length() int64 {
return -1
}
func (plainLink) IsAbsent() bool {
return false
}
func (plainLink) IsNull() bool {
return false
}
func (plainLink) AsBool() (bool, error) {
return mixins.Link{TypeName: "link"}.AsBool()
}
func (plainLink) AsInt() (int64, error) {
return mixins.Link{TypeName: "link"}.AsInt()
}
func (plainLink) AsFloat() (float64, error) {
return mixins.Link{TypeName: "link"}.AsFloat()
}
func (plainLink) AsString() (string, error) {
return mixins.Link{TypeName: "link"}.AsString()
}
func (plainLink) AsBytes() ([]byte, error) {
return mixins.Link{TypeName: "link"}.AsBytes()
}
func (n *plainLink) AsLink() (datamodel.Link, error) {
return n.x, nil
}
func (plainLink) Prototype() datamodel.NodePrototype {
return Prototype__Link{}
}
// -- NodePrototype -->
type Prototype__Link struct{}
func (Prototype__Link) NewBuilder() datamodel.NodeBuilder {
var w plainLink
return &plainLink__Builder{plainLink__Assembler{w: &w}}
}
// -- NodeBuilder -->
type plainLink__Builder struct {
plainLink__Assembler
}
func (nb *plainLink__Builder) Build() datamodel.Node {
return nb.w
}
func (nb *plainLink__Builder) Reset() {
var w plainLink
*nb = plainLink__Builder{plainLink__Assembler{w: &w}}
}
// -- NodeAssembler -->
type plainLink__Assembler struct {
w *plainLink
}
func (plainLink__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) {
return mixins.LinkAssembler{TypeName: "link"}.BeginMap(0)
}
func (plainLink__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) {
return mixins.LinkAssembler{TypeName: "link"}.BeginList(0)
}
func (plainLink__Assembler) AssignNull() error {
return mixins.LinkAssembler{TypeName: "link"}.AssignNull()
}
func (plainLink__Assembler) AssignBool(bool) error {
return mixins.LinkAssembler{TypeName: "link"}.AssignBool(false)
}
func (plainLink__Assembler) AssignInt(int64) error {
return mixins.LinkAssembler{TypeName: "link"}.AssignInt(0)
}
func (plainLink__Assembler) AssignFloat(float64) error {
return mixins.LinkAssembler{TypeName: "link"}.AssignFloat(0)
}
func (plainLink__Assembler) AssignString(string) error {
return mixins.LinkAssembler{TypeName: "link"}.AssignString("")
}
func (plainLink__Assembler) AssignBytes([]byte) error {
return mixins.LinkAssembler{TypeName: "link"}.AssignBytes(nil)
}
func (na *plainLink__Assembler) AssignLink(v datamodel.Link) error {
na.w.x = v
return nil
}
func (na *plainLink__Assembler) AssignNode(v datamodel.Node) error {
if v2, err := v.AsLink(); err != nil {
return err
} else {
na.w.x = v2
return nil
}
}
func (plainLink__Assembler) Prototype() datamodel.NodePrototype {
return Prototype__Link{}
}

View File

@@ -0,0 +1,360 @@
package basicnode
import (
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/node/mixins"
)
var (
_ datamodel.Node = &plainList{}
_ datamodel.NodePrototype = Prototype__List{}
_ datamodel.NodeBuilder = &plainList__Builder{}
_ datamodel.NodeAssembler = &plainList__Assembler{}
)
// plainList is a concrete type that provides a list-kind datamodel.Node.
// It can contain any kind of value.
// plainList is also embedded in the 'any' struct and usable from there.
type plainList struct {
x []datamodel.Node
}
// -- Node interface methods -->
func (plainList) Kind() datamodel.Kind {
return datamodel.Kind_List
}
func (plainList) LookupByString(string) (datamodel.Node, error) {
return mixins.List{TypeName: "list"}.LookupByString("")
}
func (plainList) LookupByNode(datamodel.Node) (datamodel.Node, error) {
return mixins.List{TypeName: "list"}.LookupByNode(nil)
}
func (n *plainList) LookupByIndex(idx int64) (datamodel.Node, error) {
if n.Length() <= idx {
return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfInt(idx)}
}
return n.x[idx], nil
}
func (n *plainList) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) {
idx, err := seg.Index()
if err != nil {
return nil, datamodel.ErrInvalidSegmentForList{TroubleSegment: seg, Reason: err}
}
return n.LookupByIndex(idx)
}
func (plainList) MapIterator() datamodel.MapIterator {
return nil
}
func (n *plainList) ListIterator() datamodel.ListIterator {
return &plainList_ListIterator{n, 0}
}
func (n *plainList) Length() int64 {
return int64(len(n.x))
}
func (plainList) IsAbsent() bool {
return false
}
func (plainList) IsNull() bool {
return false
}
func (plainList) AsBool() (bool, error) {
return mixins.List{TypeName: "list"}.AsBool()
}
func (plainList) AsInt() (int64, error) {
return mixins.List{TypeName: "list"}.AsInt()
}
func (plainList) AsFloat() (float64, error) {
return mixins.List{TypeName: "list"}.AsFloat()
}
func (plainList) AsString() (string, error) {
return mixins.List{TypeName: "list"}.AsString()
}
func (plainList) AsBytes() ([]byte, error) {
return mixins.List{TypeName: "list"}.AsBytes()
}
func (plainList) AsLink() (datamodel.Link, error) {
return mixins.List{TypeName: "list"}.AsLink()
}
func (plainList) Prototype() datamodel.NodePrototype {
return Prototype.List
}
type plainList_ListIterator struct {
n *plainList
idx int
}
func (itr *plainList_ListIterator) Next() (idx int64, v datamodel.Node, _ error) {
if itr.Done() {
return -1, nil, datamodel.ErrIteratorOverread{}
}
v = itr.n.x[itr.idx]
idx = int64(itr.idx)
itr.idx++
return
}
func (itr *plainList_ListIterator) Done() bool {
return itr.idx >= len(itr.n.x)
}
// -- NodePrototype -->
type Prototype__List struct{}
func (Prototype__List) NewBuilder() datamodel.NodeBuilder {
return &plainList__Builder{plainList__Assembler{w: &plainList{}}}
}
// -- NodeBuilder -->
type plainList__Builder struct {
plainList__Assembler
}
func (nb *plainList__Builder) Build() datamodel.Node {
if nb.state != laState_finished {
panic("invalid state: assembler must be 'finished' before Build can be called!")
}
return nb.w
}
func (nb *plainList__Builder) Reset() {
*nb = plainList__Builder{}
nb.w = &plainList{}
}
// -- NodeAssembler -->
type plainList__Assembler struct {
w *plainList
va plainList__ValueAssembler
state laState
}
type plainList__ValueAssembler struct {
la *plainList__Assembler
}
// laState is an enum of the state machine for a list assembler.
// (this might be something to export reusably, but it's also very much an impl detail that need not be seen, so, dubious.)
// it's similar to maState for maps, but has fewer states because we never have keys to assemble.
type laState uint8
const (
laState_initial laState = iota // also the 'expect value or finish' state
laState_midValue // waiting for a 'finished' state in the ValueAssembler.
laState_finished // 'w' will also be nil, but this is a politer statement
)
func (plainList__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) {
return mixins.ListAssembler{TypeName: "list"}.BeginMap(0)
}
func (na *plainList__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) {
if sizeHint < 0 {
sizeHint = 0
}
// Allocate storage space.
na.w.x = make([]datamodel.Node, 0, sizeHint)
// That's it; return self as the ListAssembler. We already have all the right methods on this structure.
return na, nil
}
func (plainList__Assembler) AssignNull() error {
return mixins.ListAssembler{TypeName: "list"}.AssignNull()
}
func (plainList__Assembler) AssignBool(bool) error {
return mixins.ListAssembler{TypeName: "list"}.AssignBool(false)
}
func (plainList__Assembler) AssignInt(int64) error {
return mixins.ListAssembler{TypeName: "list"}.AssignInt(0)
}
func (plainList__Assembler) AssignFloat(float64) error {
return mixins.ListAssembler{TypeName: "list"}.AssignFloat(0)
}
func (plainList__Assembler) AssignString(string) error {
return mixins.ListAssembler{TypeName: "list"}.AssignString("")
}
func (plainList__Assembler) AssignBytes([]byte) error {
return mixins.ListAssembler{TypeName: "list"}.AssignBytes(nil)
}
func (plainList__Assembler) AssignLink(datamodel.Link) error {
return mixins.ListAssembler{TypeName: "list"}.AssignLink(nil)
}
func (na *plainList__Assembler) AssignNode(v datamodel.Node) error {
// Sanity check, then update, assembler state.
// Update of state to 'finished' comes later; where exactly depends on if shortcuts apply.
if na.state != laState_initial {
panic("misuse")
}
// Copy the content.
if v2, ok := v.(*plainList); ok { // if our own type: shortcut.
// Copy the structure by value.
// This means we'll have pointers into the same internal maps and slices;
// this is okay, because the Node type promises it's immutable, and we are going to instantly finish ourselves to also maintain that.
// FIXME: the shortcut behaves differently than the long way: it discards any existing progress. Doesn't violate immut, but is odd.
*na.w = *v2
na.state = laState_finished
return nil
}
// If the above shortcut didn't work, resort to a generic copy.
// We call AssignNode for all the child values, giving them a chance to hit shortcuts even if we didn't.
if v.Kind() != datamodel.Kind_List {
return datamodel.ErrWrongKind{TypeName: "list", MethodName: "AssignNode", AppropriateKind: datamodel.KindSet_JustList, ActualKind: v.Kind()}
}
itr := v.ListIterator()
for !itr.Done() {
_, v, err := itr.Next()
if err != nil {
return err
}
if err := na.AssembleValue().AssignNode(v); err != nil {
return err
}
}
return na.Finish()
}
func (plainList__Assembler) Prototype() datamodel.NodePrototype {
return Prototype.List
}
// -- ListAssembler -->
// AssembleValue is part of conforming to ListAssembler, which we do on
// plainList__Assembler so that BeginList can just return a retyped pointer rather than new object.
func (la *plainList__Assembler) AssembleValue() datamodel.NodeAssembler {
// Sanity check, then update, assembler state.
if la.state != laState_initial {
panic("misuse")
}
la.state = laState_midValue
// Make value assembler valid by giving it pointer back to whole 'la'; yield it.
la.va.la = la
return &la.va
}
// Finish is part of conforming to ListAssembler, which we do on
// plainList__Assembler so that BeginList can just return a retyped pointer rather than new object.
func (la *plainList__Assembler) Finish() error {
// Sanity check, then update, assembler state.
if la.state != laState_initial {
panic("misuse")
}
la.state = laState_finished
// validators could run and report errors promptly, if this type had any.
return nil
}
func (plainList__Assembler) ValuePrototype(_ int64) datamodel.NodePrototype {
return Prototype.Any
}
// -- ListAssembler.ValueAssembler -->
func (lva *plainList__ValueAssembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) {
ma := plainList__ValueAssemblerMap{}
ma.ca.w = &plainMap{}
ma.p = lva.la
_, err := ma.ca.BeginMap(sizeHint)
return &ma, err
}
func (lva *plainList__ValueAssembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) {
la := plainList__ValueAssemblerList{}
la.ca.w = &plainList{}
la.p = lva.la
_, err := la.ca.BeginList(sizeHint)
return &la, err
}
func (lva *plainList__ValueAssembler) AssignNull() error {
return lva.AssignNode(datamodel.Null)
}
func (lva *plainList__ValueAssembler) AssignBool(v bool) error {
vb := plainBool(v)
return lva.AssignNode(&vb)
}
func (lva *plainList__ValueAssembler) AssignInt(v int64) error {
vb := plainInt(v)
return lva.AssignNode(&vb)
}
func (lva *plainList__ValueAssembler) AssignFloat(v float64) error {
vb := plainFloat(v)
return lva.AssignNode(&vb)
}
func (lva *plainList__ValueAssembler) AssignString(v string) error {
vb := plainString(v)
return lva.AssignNode(&vb)
}
func (lva *plainList__ValueAssembler) AssignBytes(v []byte) error {
vb := plainBytes(v)
return lva.AssignNode(&vb)
}
func (lva *plainList__ValueAssembler) AssignLink(v datamodel.Link) error {
vb := plainLink{v}
return lva.AssignNode(&vb)
}
func (lva *plainList__ValueAssembler) AssignNode(v datamodel.Node) error {
lva.la.w.x = append(lva.la.w.x, v)
lva.la.state = laState_initial
lva.la = nil // invalidate self to prevent further incorrect use.
return nil
}
func (plainList__ValueAssembler) Prototype() datamodel.NodePrototype {
return Prototype.Any
}
type plainList__ValueAssemblerMap struct {
ca plainMap__Assembler
p *plainList__Assembler // pointer back to parent, for final insert and state bump
}
// we briefly state only the methods we need to delegate here.
// just embedding plainMap__Assembler also behaves correctly,
// but causes a lot of unnecessary autogenerated functions in the final binary.
func (ma *plainList__ValueAssemblerMap) AssembleEntry(k string) (datamodel.NodeAssembler, error) {
return ma.ca.AssembleEntry(k)
}
func (ma *plainList__ValueAssemblerMap) AssembleKey() datamodel.NodeAssembler {
return ma.ca.AssembleKey()
}
func (ma *plainList__ValueAssemblerMap) AssembleValue() datamodel.NodeAssembler {
return ma.ca.AssembleValue()
}
func (plainList__ValueAssemblerMap) KeyPrototype() datamodel.NodePrototype {
return Prototype__String{}
}
func (plainList__ValueAssemblerMap) ValuePrototype(_ string) datamodel.NodePrototype {
return Prototype.Any
}
func (ma *plainList__ValueAssemblerMap) Finish() error {
if err := ma.ca.Finish(); err != nil {
return err
}
w := ma.ca.w
ma.ca.w = nil
return ma.p.va.AssignNode(w)
}
type plainList__ValueAssemblerList struct {
ca plainList__Assembler
p *plainList__Assembler // pointer back to parent, for final insert and state bump
}
// we briefly state only the methods we need to delegate here.
// just embedding plainList__Assembler also behaves correctly,
// but causes a lot of unnecessary autogenerated functions in the final binary.
func (la *plainList__ValueAssemblerList) AssembleValue() datamodel.NodeAssembler {
return la.ca.AssembleValue()
}
func (plainList__ValueAssemblerList) ValuePrototype(_ int64) datamodel.NodePrototype {
return Prototype.Any
}
func (la *plainList__ValueAssemblerList) Finish() error {
if err := la.ca.Finish(); err != nil {
return err
}
w := la.ca.w
la.ca.w = nil
return la.p.va.AssignNode(w)
}

View File

@@ -0,0 +1,474 @@
package basicnode
import (
"fmt"
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/node/mixins"
)
var (
_ datamodel.Node = &plainMap{}
_ datamodel.NodePrototype = Prototype__Map{}
_ datamodel.NodeBuilder = &plainMap__Builder{}
_ datamodel.NodeAssembler = &plainMap__Assembler{}
)
// plainMap is a concrete type that provides a map-kind datamodel.Node.
// It can contain any kind of value.
// plainMap is also embedded in the 'any' struct and usable from there.
type plainMap struct {
m map[string]datamodel.Node // string key -- even if a runtime schema wrapper is using us for storage, we must have a comparable type here, and string is all we know.
t []plainMap__Entry // table for fast iteration, order keeping, and yielding pointers to enable alloc/conv amortization.
}
type plainMap__Entry struct {
k plainString // address of this used when we return keys as nodes, such as in iterators. Need in one place to amortize shifts to heap when ptr'ing for iface.
v datamodel.Node // identical to map values. keeping them here simplifies iteration. (in codegen'd maps, this position is also part of amortization, but in this implementation, that's less useful.)
// note on alternate implementations: 'v' could also use the 'any' type, and thus amortize value allocations. the memory size trade would be large however, so we don't, here.
}
// -- Node interface methods -->
func (plainMap) Kind() datamodel.Kind {
return datamodel.Kind_Map
}
func (n *plainMap) LookupByString(key string) (datamodel.Node, error) {
v, exists := n.m[key]
if !exists {
return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfString(key)}
}
return v, nil
}
func (n *plainMap) LookupByNode(key datamodel.Node) (datamodel.Node, error) {
ks, err := key.AsString()
if err != nil {
return nil, err
}
return n.LookupByString(ks)
}
func (plainMap) LookupByIndex(idx int64) (datamodel.Node, error) {
return mixins.Map{TypeName: "map"}.LookupByIndex(0)
}
func (n *plainMap) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) {
return n.LookupByString(seg.String())
}
func (n *plainMap) MapIterator() datamodel.MapIterator {
return &plainMap_MapIterator{n, 0}
}
func (plainMap) ListIterator() datamodel.ListIterator {
return nil
}
func (n *plainMap) Length() int64 {
return int64(len(n.t))
}
func (plainMap) IsAbsent() bool {
return false
}
func (plainMap) IsNull() bool {
return false
}
func (plainMap) AsBool() (bool, error) {
return mixins.Map{TypeName: "map"}.AsBool()
}
func (plainMap) AsInt() (int64, error) {
return mixins.Map{TypeName: "map"}.AsInt()
}
func (plainMap) AsFloat() (float64, error) {
return mixins.Map{TypeName: "map"}.AsFloat()
}
func (plainMap) AsString() (string, error) {
return mixins.Map{TypeName: "map"}.AsString()
}
func (plainMap) AsBytes() ([]byte, error) {
return mixins.Map{TypeName: "map"}.AsBytes()
}
func (plainMap) AsLink() (datamodel.Link, error) {
return mixins.Map{TypeName: "map"}.AsLink()
}
func (plainMap) Prototype() datamodel.NodePrototype {
return Prototype.Map
}
type plainMap_MapIterator struct {
n *plainMap
idx int
}
func (itr *plainMap_MapIterator) Next() (k datamodel.Node, v datamodel.Node, _ error) {
if itr.Done() {
return nil, nil, datamodel.ErrIteratorOverread{}
}
k = &itr.n.t[itr.idx].k
v = itr.n.t[itr.idx].v
itr.idx++
return
}
func (itr *plainMap_MapIterator) Done() bool {
return itr.idx >= len(itr.n.t)
}
// -- NodePrototype -->
type Prototype__Map struct{}
func (Prototype__Map) NewBuilder() datamodel.NodeBuilder {
return &plainMap__Builder{plainMap__Assembler{w: &plainMap{}}}
}
// -- NodeBuilder -->
type plainMap__Builder struct {
plainMap__Assembler
}
func (nb *plainMap__Builder) Build() datamodel.Node {
if nb.state != maState_finished {
panic("invalid state: assembler must be 'finished' before Build can be called!")
}
return nb.w
}
func (nb *plainMap__Builder) Reset() {
*nb = plainMap__Builder{}
nb.w = &plainMap{}
}
// -- NodeAssembler -->
type plainMap__Assembler struct {
w *plainMap
ka plainMap__KeyAssembler
va plainMap__ValueAssembler
state maState
}
type plainMap__KeyAssembler struct {
ma *plainMap__Assembler
}
type plainMap__ValueAssembler struct {
ma *plainMap__Assembler
}
// maState is an enum of the state machine for a map assembler.
// (this might be something to export reusably, but it's also very much an impl detail that need not be seen, so, dubious.)
type maState uint8
const (
maState_initial maState = iota // also the 'expect key or finish' state
maState_midKey // waiting for a 'finished' state in the KeyAssembler.
maState_expectValue // 'AssembleValue' is the only valid next step
maState_midValue // waiting for a 'finished' state in the ValueAssembler.
maState_finished // 'w' will also be nil, but this is a politer statement
)
func (na *plainMap__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) {
if sizeHint < 0 {
sizeHint = 0
}
// Allocate storage space.
na.w.t = make([]plainMap__Entry, 0, sizeHint)
na.w.m = make(map[string]datamodel.Node, sizeHint)
// That's it; return self as the MapAssembler. We already have all the right methods on this structure.
return na, nil
}
func (plainMap__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) {
return mixins.MapAssembler{TypeName: "map"}.BeginList(0)
}
func (plainMap__Assembler) AssignNull() error {
return mixins.MapAssembler{TypeName: "map"}.AssignNull()
}
func (plainMap__Assembler) AssignBool(bool) error {
return mixins.MapAssembler{TypeName: "map"}.AssignBool(false)
}
func (plainMap__Assembler) AssignInt(int64) error {
return mixins.MapAssembler{TypeName: "map"}.AssignInt(0)
}
func (plainMap__Assembler) AssignFloat(float64) error {
return mixins.MapAssembler{TypeName: "map"}.AssignFloat(0)
}
func (plainMap__Assembler) AssignString(string) error {
return mixins.MapAssembler{TypeName: "map"}.AssignString("")
}
func (plainMap__Assembler) AssignBytes([]byte) error {
return mixins.MapAssembler{TypeName: "map"}.AssignBytes(nil)
}
func (plainMap__Assembler) AssignLink(datamodel.Link) error {
return mixins.MapAssembler{TypeName: "map"}.AssignLink(nil)
}
func (na *plainMap__Assembler) AssignNode(v datamodel.Node) error {
// Sanity check assembler state.
// Update of state to 'finished' comes later; where exactly depends on if shortcuts apply.
if na.state != maState_initial {
panic("misuse")
}
// Copy the content.
if v2, ok := v.(*plainMap); ok { // if our own type: shortcut.
// Copy the structure by value.
// This means we'll have pointers into the same internal maps and slices;
// this is okay, because the Node type promises it's immutable, and we are going to instantly finish ourselves to also maintain that.
// FIXME: the shortcut behaves differently than the long way: it discards any existing progress. Doesn't violate immut, but is odd.
*na.w = *v2
na.state = maState_finished
return nil
}
// If the above shortcut didn't work, resort to a generic copy.
// We call AssignNode for all the child values, giving them a chance to hit shortcuts even if we didn't.
if v.Kind() != datamodel.Kind_Map {
return datamodel.ErrWrongKind{TypeName: "map", MethodName: "AssignNode", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: v.Kind()}
}
itr := v.MapIterator()
for !itr.Done() {
k, v, err := itr.Next()
if err != nil {
return err
}
if err := na.AssembleKey().AssignNode(k); err != nil {
return err
}
if err := na.AssembleValue().AssignNode(v); err != nil {
return err
}
}
return na.Finish()
}
func (plainMap__Assembler) Prototype() datamodel.NodePrototype {
return Prototype.Map
}
// -- MapAssembler -->
// AssembleEntry is part of conforming to MapAssembler, which we do on
// plainMap__Assembler so that BeginMap can just return a retyped pointer rather than new object.
func (ma *plainMap__Assembler) AssembleEntry(k string) (datamodel.NodeAssembler, error) {
// Sanity check assembler state.
// Update of state comes after possible key rejection.
if ma.state != maState_initial {
panic("misuse")
}
// Check for dup keys; error if so.
_, exists := ma.w.m[k]
if exists {
return nil, datamodel.ErrRepeatedMapKey{Key: plainString(k)}
}
ma.state = maState_midValue
ma.w.t = append(ma.w.t, plainMap__Entry{k: plainString(k)})
// Make value assembler valid by giving it pointer back to whole 'ma'; yield it.
ma.va.ma = ma
return &ma.va, nil
}
// AssembleKey is part of conforming to MapAssembler, which we do on
// plainMap__Assembler so that BeginMap can just return a retyped pointer rather than new object.
func (ma *plainMap__Assembler) AssembleKey() datamodel.NodeAssembler {
// Sanity check, then update, assembler state.
if ma.state != maState_initial {
panic("misuse")
}
ma.state = maState_midKey
// Make key assembler valid by giving it pointer back to whole 'ma'; yield it.
ma.ka.ma = ma
return &ma.ka
}
// AssembleValue is part of conforming to MapAssembler, which we do on
// plainMap__Assembler so that BeginMap can just return a retyped pointer rather than new object.
func (ma *plainMap__Assembler) AssembleValue() datamodel.NodeAssembler {
// Sanity check, then update, assembler state.
if ma.state != maState_expectValue {
panic("misuse")
}
ma.state = maState_midValue
// Make value assembler valid by giving it pointer back to whole 'ma'; yield it.
ma.va.ma = ma
return &ma.va
}
// Finish is part of conforming to MapAssembler, which we do on
// plainMap__Assembler so that BeginMap can just return a retyped pointer rather than new object.
func (ma *plainMap__Assembler) Finish() error {
// Sanity check, then update, assembler state.
if ma.state != maState_initial {
panic("misuse")
}
ma.state = maState_finished
// validators could run and report errors promptly, if this type had any.
return nil
}
func (plainMap__Assembler) KeyPrototype() datamodel.NodePrototype {
return Prototype__String{}
}
func (plainMap__Assembler) ValuePrototype(_ string) datamodel.NodePrototype {
return Prototype.Any
}
// -- MapAssembler.KeyAssembler -->
func (plainMap__KeyAssembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) {
return mixins.StringAssembler{TypeName: "string"}.BeginMap(0)
}
func (plainMap__KeyAssembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) {
return mixins.StringAssembler{TypeName: "string"}.BeginList(0)
}
func (plainMap__KeyAssembler) AssignNull() error {
return mixins.StringAssembler{TypeName: "string"}.AssignNull()
}
func (plainMap__KeyAssembler) AssignBool(bool) error {
return mixins.StringAssembler{TypeName: "string"}.AssignBool(false)
}
func (plainMap__KeyAssembler) AssignInt(int64) error {
return mixins.StringAssembler{TypeName: "string"}.AssignInt(0)
}
func (plainMap__KeyAssembler) AssignFloat(float64) error {
return mixins.StringAssembler{TypeName: "string"}.AssignFloat(0)
}
func (mka *plainMap__KeyAssembler) AssignString(v string) error {
// Check for dup keys; error if so.
// (And, backtrack state to accepting keys again so we don't get eternally wedged here.)
_, exists := mka.ma.w.m[v]
if exists {
mka.ma.state = maState_initial
mka.ma = nil // invalidate self to prevent further incorrect use.
return datamodel.ErrRepeatedMapKey{Key: plainString(v)}
}
// Assign the key into the end of the entry table;
// we'll be doing map insertions after we get the value in hand.
// (There's no need to delegate to another assembler for the key type,
// because we're just at Data Model level here, which only regards plain strings.)
mka.ma.w.t = append(mka.ma.w.t, plainMap__Entry{})
mka.ma.w.t[len(mka.ma.w.t)-1].k = plainString(v)
// Update parent assembler state: clear to proceed.
mka.ma.state = maState_expectValue
mka.ma = nil // invalidate self to prevent further incorrect use.
return nil
}
func (plainMap__KeyAssembler) AssignBytes([]byte) error {
return mixins.StringAssembler{TypeName: "string"}.AssignBytes(nil)
}
func (plainMap__KeyAssembler) AssignLink(datamodel.Link) error {
return mixins.StringAssembler{TypeName: "string"}.AssignLink(nil)
}
func (mka *plainMap__KeyAssembler) AssignNode(v datamodel.Node) error {
vs, err := v.AsString()
if err != nil {
return fmt.Errorf("cannot assign non-string node into map key assembler") // FIXME:errors: this doesn't quite fit in ErrWrongKind cleanly; new error type?
}
return mka.AssignString(vs)
}
func (plainMap__KeyAssembler) Prototype() datamodel.NodePrototype {
return Prototype__String{}
}
// -- MapAssembler.ValueAssembler -->
func (mva *plainMap__ValueAssembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) {
ma := plainMap__ValueAssemblerMap{}
ma.ca.w = &plainMap{}
ma.p = mva.ma
_, err := ma.ca.BeginMap(sizeHint)
return &ma, err
}
func (mva *plainMap__ValueAssembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) {
la := plainMap__ValueAssemblerList{}
la.ca.w = &plainList{}
la.p = mva.ma
_, err := la.ca.BeginList(sizeHint)
return &la, err
}
func (mva *plainMap__ValueAssembler) AssignNull() error {
return mva.AssignNode(datamodel.Null)
}
func (mva *plainMap__ValueAssembler) AssignBool(v bool) error {
vb := plainBool(v)
return mva.AssignNode(&vb)
}
func (mva *plainMap__ValueAssembler) AssignInt(v int64) error {
vb := plainInt(v)
return mva.AssignNode(&vb)
}
func (mva *plainMap__ValueAssembler) AssignFloat(v float64) error {
vb := plainFloat(v)
return mva.AssignNode(&vb)
}
func (mva *plainMap__ValueAssembler) AssignString(v string) error {
vb := plainString(v)
return mva.AssignNode(&vb)
}
func (mva *plainMap__ValueAssembler) AssignBytes(v []byte) error {
vb := plainBytes(v)
return mva.AssignNode(&vb)
}
func (mva *plainMap__ValueAssembler) AssignLink(v datamodel.Link) error {
vb := plainLink{v}
return mva.AssignNode(&vb)
}
func (mva *plainMap__ValueAssembler) AssignNode(v datamodel.Node) error {
l := len(mva.ma.w.t) - 1
mva.ma.w.t[l].v = v
mva.ma.w.m[string(mva.ma.w.t[l].k)] = v
mva.ma.state = maState_initial
mva.ma = nil // invalidate self to prevent further incorrect use.
return nil
}
func (plainMap__ValueAssembler) Prototype() datamodel.NodePrototype {
return Prototype.Any
}
type plainMap__ValueAssemblerMap struct {
ca plainMap__Assembler
p *plainMap__Assembler // pointer back to parent, for final insert and state bump
}
// we briefly state only the methods we need to delegate here.
// just embedding plainMap__Assembler also behaves correctly,
// but causes a lot of unnecessary autogenerated functions in the final binary.
func (ma *plainMap__ValueAssemblerMap) AssembleEntry(k string) (datamodel.NodeAssembler, error) {
return ma.ca.AssembleEntry(k)
}
func (ma *plainMap__ValueAssemblerMap) AssembleKey() datamodel.NodeAssembler {
return ma.ca.AssembleKey()
}
func (ma *plainMap__ValueAssemblerMap) AssembleValue() datamodel.NodeAssembler {
return ma.ca.AssembleValue()
}
func (plainMap__ValueAssemblerMap) KeyPrototype() datamodel.NodePrototype {
return Prototype__String{}
}
func (plainMap__ValueAssemblerMap) ValuePrototype(_ string) datamodel.NodePrototype {
return Prototype.Any
}
func (ma *plainMap__ValueAssemblerMap) Finish() error {
if err := ma.ca.Finish(); err != nil {
return err
}
w := ma.ca.w
ma.ca.w = nil
return ma.p.va.AssignNode(w)
}
type plainMap__ValueAssemblerList struct {
ca plainList__Assembler
p *plainMap__Assembler // pointer back to parent, for final insert and state bump
}
// we briefly state only the methods we need to delegate here.
// just embedding plainList__Assembler also behaves correctly,
// but causes a lot of unnecessary autogenerated functions in the final binary.
func (la *plainMap__ValueAssemblerList) AssembleValue() datamodel.NodeAssembler {
return la.ca.AssembleValue()
}
func (plainMap__ValueAssemblerList) ValuePrototype(_ int64) datamodel.NodePrototype {
return Prototype.Any
}
func (la *plainMap__ValueAssemblerList) Finish() error {
if err := la.ca.Finish(); err != nil {
return err
}
w := la.ca.w
la.ca.w = nil
return la.p.va.AssignNode(w)
}

View File

@@ -0,0 +1,26 @@
package basicnode
// Prototype embeds a NodePrototype for every kind of Node implementation in this package.
// You can use it like this:
//
// basicnode.Prototype.Map.NewBuilder().BeginMap() //...
//
// and:
//
// basicnode.Prototype.String.NewBuilder().AssignString("x") // ...
//
// Most of the prototypes are for one particular Kind of node (e.g. string, int, etc);
// you can use the "Any" style if you want a builder that can accept any kind of data.
var Prototype prototype
type prototype struct {
Any Prototype__Any
Map Prototype__Map
List Prototype__List
Bool Prototype__Bool
Int Prototype__Int
Float Prototype__Float
String Prototype__String
Bytes Prototype__Bytes
Link Prototype__Link
}

View File

@@ -0,0 +1,149 @@
package basicnode
import (
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/node/mixins"
)
var (
_ datamodel.Node = plainString("")
_ datamodel.NodePrototype = Prototype__String{}
_ datamodel.NodeBuilder = &plainString__Builder{}
_ datamodel.NodeAssembler = &plainString__Assembler{}
)
func NewString(value string) datamodel.Node {
v := plainString(value)
return &v
}
// plainString is a simple boxed string that complies with datamodel.Node.
// It's useful for many things, such as boxing map keys.
//
// The implementation is a simple typedef of a string;
// handling it as a Node incurs 'runtime.convTstring',
// which is about the best we can do.
type plainString string
// -- Node interface methods -->
func (plainString) Kind() datamodel.Kind {
return datamodel.Kind_String
}
func (plainString) LookupByString(string) (datamodel.Node, error) {
return mixins.String{TypeName: "string"}.LookupByString("")
}
func (plainString) LookupByNode(key datamodel.Node) (datamodel.Node, error) {
return mixins.String{TypeName: "string"}.LookupByNode(nil)
}
func (plainString) LookupByIndex(idx int64) (datamodel.Node, error) {
return mixins.String{TypeName: "string"}.LookupByIndex(0)
}
func (plainString) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) {
return mixins.String{TypeName: "string"}.LookupBySegment(seg)
}
func (plainString) MapIterator() datamodel.MapIterator {
return nil
}
func (plainString) ListIterator() datamodel.ListIterator {
return nil
}
func (plainString) Length() int64 {
return -1
}
func (plainString) IsAbsent() bool {
return false
}
func (plainString) IsNull() bool {
return false
}
func (plainString) AsBool() (bool, error) {
return mixins.String{TypeName: "string"}.AsBool()
}
func (plainString) AsInt() (int64, error) {
return mixins.String{TypeName: "string"}.AsInt()
}
func (plainString) AsFloat() (float64, error) {
return mixins.String{TypeName: "string"}.AsFloat()
}
func (x plainString) AsString() (string, error) {
return string(x), nil
}
func (plainString) AsBytes() ([]byte, error) {
return mixins.String{TypeName: "string"}.AsBytes()
}
func (plainString) AsLink() (datamodel.Link, error) {
return mixins.String{TypeName: "string"}.AsLink()
}
func (plainString) Prototype() datamodel.NodePrototype {
return Prototype__String{}
}
// -- NodePrototype -->
type Prototype__String struct{}
func (Prototype__String) NewBuilder() datamodel.NodeBuilder {
var w plainString
return &plainString__Builder{plainString__Assembler{w: &w}}
}
// -- NodeBuilder -->
type plainString__Builder struct {
plainString__Assembler
}
func (nb *plainString__Builder) Build() datamodel.Node {
return nb.w
}
func (nb *plainString__Builder) Reset() {
var w plainString
*nb = plainString__Builder{plainString__Assembler{w: &w}}
}
// -- NodeAssembler -->
type plainString__Assembler struct {
w *plainString
}
func (plainString__Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) {
return mixins.StringAssembler{TypeName: "string"}.BeginMap(0)
}
func (plainString__Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) {
return mixins.StringAssembler{TypeName: "string"}.BeginList(0)
}
func (plainString__Assembler) AssignNull() error {
return mixins.StringAssembler{TypeName: "string"}.AssignNull()
}
func (plainString__Assembler) AssignBool(bool) error {
return mixins.StringAssembler{TypeName: "string"}.AssignBool(false)
}
func (plainString__Assembler) AssignInt(int64) error {
return mixins.StringAssembler{TypeName: "string"}.AssignInt(0)
}
func (plainString__Assembler) AssignFloat(float64) error {
return mixins.StringAssembler{TypeName: "string"}.AssignFloat(0)
}
func (na *plainString__Assembler) AssignString(v string) error {
*na.w = plainString(v)
return nil
}
func (plainString__Assembler) AssignBytes([]byte) error {
return mixins.StringAssembler{TypeName: "string"}.AssignBytes(nil)
}
func (plainString__Assembler) AssignLink(datamodel.Link) error {
return mixins.StringAssembler{TypeName: "string"}.AssignLink(nil)
}
func (na *plainString__Assembler) AssignNode(v datamodel.Node) error {
if v2, err := v.AsString(); err != nil {
return err
} else {
*na.w = plainString(v2)
return nil
}
}
func (plainString__Assembler) Prototype() datamodel.NodePrototype {
return Prototype__String{}
}