diff --git a/core/result/ok/datamodel/unit.go b/core/result/ok/datamodel/unit.go new file mode 100644 index 0000000..4e2e836 --- /dev/null +++ b/core/result/ok/datamodel/unit.go @@ -0,0 +1,31 @@ +package datamodel + +import ( + // to use go:embed + _ "embed" + "fmt" + + "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/schema" +) + +//go:embed unit.ipldsch +var unitSchema []byte + +var unitType schema.Type + +func init() { + ts, err := ipld.LoadSchemaBytes(unitSchema) + if err != nil { + panic(fmt.Errorf("loading unit schema: %w", err)) + } + unitType = ts.TypeByName("Unit") +} + +func UnitType() schema.Type { + return unitType +} + +func Schema() []byte { + return unitSchema +} diff --git a/core/result/ok/datamodel/unit.ipldsch b/core/result/ok/datamodel/unit.ipldsch new file mode 100644 index 0000000..5c8ab44 --- /dev/null +++ b/core/result/ok/datamodel/unit.ipldsch @@ -0,0 +1 @@ +type Unit struct {} diff --git a/core/result/ok/unit.go b/core/result/ok/unit.go new file mode 100644 index 0000000..8b8bc6e --- /dev/null +++ b/core/result/ok/unit.go @@ -0,0 +1,21 @@ +package ok + +import ( + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/node/basicnode" +) + +// Unit is a success type that can be used when there is no data to return from +// a capability handler. +type Unit struct{} + +func (u Unit) ToIPLD() (datamodel.Node, error) { + np := basicnode.Prototype.Any + nb := np.NewBuilder() + ma, err := nb.BeginMap(0) + if err != nil { + return nil, err + } + ma.Finish() + return nb.Build(), nil +} diff --git a/core/result/ok/unit_test.go b/core/result/ok/unit_test.go new file mode 100644 index 0000000..860b911 --- /dev/null +++ b/core/result/ok/unit_test.go @@ -0,0 +1,32 @@ +package ok + +import ( + "testing" + + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/storacha/go-ucanto/core/ipld/codec/cbor" + udm "github.com/storacha/go-ucanto/core/result/ok/datamodel" + "github.com/stretchr/testify/require" +) + +func TestUnit(t *testing.T) { + u := Unit{} + nd, err := u.ToIPLD() + require.NoError(t, err) + + // should be represented as a map + require.Equal(t, nd.Kind(), datamodel.Kind_Map) + + // should contain no items + it := nd.MapIterator() + require.True(t, it.Done()) + + bytes, err := cbor.Encode(&u, udm.UnitType()) + require.NoError(t, err) + + u2 := Unit{} + err = cbor.Decode(bytes, &u2, udm.UnitType()) + require.NoError(t, err) + + require.Equal(t, u, u2) +}