diff --git a/README.md b/README.md index d2ff04c..b3ec293 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -
- libracha logo -

libforge

-

Common libraries and tools for Forge Network UCAN 1.0 projects.

-
+# libforge + +Common libraries and tools for Forge Network UCAN 1.0 projects. diff --git a/bytemap/bytemap.go b/bytemap/bytemap.go new file mode 100644 index 0000000..0d00fcd --- /dev/null +++ b/bytemap/bytemap.go @@ -0,0 +1,80 @@ +package bytemap + +import ( + "iter" + "maps" +) + +type byteMap[K ~[]byte, T any] struct { + data map[string]T +} + +// ByteMap is a generic for mapping byte array like types to arbitrary data types +type ByteMap[K ~[]byte, T any] interface { + Get(K) T + Has(K) bool + Set(K, T) + Delete(K) bool + Size() int + Iterator() iter.Seq2[K, T] + Keys() iter.Seq[K] + Values() iter.Seq[T] +} + +// NewByteMap returns a new map of multihash to a data type +func NewByteMap[K ~[]byte, T any](sizeHint int) ByteMap[K, T] { + var stringMap map[string]T + if sizeHint == -1 { + stringMap = make(map[string]T) + } else { + stringMap = make(map[string]T, sizeHint) + } + return &byteMap[K, T]{stringMap} +} + +func (bm *byteMap[K, T]) Get(b K) T { + return bm.data[string(b)] +} + +func (bm *byteMap[K, T]) Has(b K) bool { + _, ok := bm.data[string(b)] + return ok +} + +func (bm *byteMap[K, T]) Set(b K, t T) { + bm.data[string(b)] = t +} + +func (bm *byteMap[K, T]) Delete(b K) bool { + _, ok := bm.data[string(b)] + delete(bm.data, string(b)) + return ok +} + +func (bm *byteMap[K, T]) Size() int { + return len(bm.data) +} + +func (bm *byteMap[K, T]) Iterator() iter.Seq2[K, T] { + return func(yield func(K, T) bool) { + for k, v := range bm.data { + if !yield(K(k), v) { + return + } + } + } +} + +func (bm *byteMap[K, T]) Keys() iter.Seq[K] { + return func(yield func(K) bool) { + for k := range bm.data { + if !yield(K(k)) { + return + } + } + } +} + +func (bm *byteMap[K, T]) Values() iter.Seq[T] { + return maps.Values(bm.data) +} diff --git a/bytemap/bytemap_test.go b/bytemap/bytemap_test.go new file mode 100644 index 0000000..67d59ac --- /dev/null +++ b/bytemap/bytemap_test.go @@ -0,0 +1,48 @@ +package bytemap_test + +import ( + "testing" + + "github.com/fil-forge/libforge/bytemap" + "github.com/multiformats/go-multihash" + "github.com/stretchr/testify/require" +) + +func TestKeys(t *testing.T) { + bm := bytemap.NewByteMap[multihash.Multihash, struct{}](-1) + + d0, err := multihash.Sum([]byte{1, 2, 3}, multihash.SHA2_256, -1) + require.NoError(t, err) + d1, err := multihash.Sum([]byte{4, 5, 6}, multihash.SHA2_256, -1) + require.NoError(t, err) + d2, err := multihash.Sum([]byte{7, 8, 9}, multihash.SHA2_256, -1) + require.NoError(t, err) + + digests := []multihash.Multihash{d0, d1, d2} + for _, d := range digests { + bm.Set(d, struct{}{}) + } + + var keys []multihash.Multihash + for d := range bm.Keys() { + keys = append(keys, d) + } + + require.ElementsMatch(t, digests, keys) +} + +func TestValues(t *testing.T) { + bm := bytemap.NewByteMap[multihash.Multihash, string](-1) + + strings := []string{"this", "is", "fine"} + for _, v := range strings { + bm.Set([]byte("key"+v), v) + } + + var values []string + for d := range bm.Values() { + values = append(values, d) + } + + require.ElementsMatch(t, strings, values) +} diff --git a/capabilities/access/confirm.go b/capabilities/access/confirm.go index 230ff54..e3f61d3 100644 --- a/capabilities/access/confirm.go +++ b/capabilities/access/confirm.go @@ -2,6 +2,7 @@ package access import ( adm "github.com/fil-forge/libforge/capabilities/access/datamodel" + "github.com/fil-forge/ucantone/errors" "github.com/fil-forge/ucantone/validator/bindcap" ) @@ -19,3 +20,13 @@ const ConfirmCommand = "/access/confirm" // Confirm can be invoked by an agent to confirm an access request. var Confirm, _ = bindcap.New[*ConfirmArguments](ConfirmCommand) + +const ( + InvalidAccessConfirmSubjectErrorName = "InvalidAccessConfirmSubject" + InvalidAccessConfirmIssuerErrorName = "InvalidAccessConfirmIssuer" +) + +var ( + ErrInvalidAccessConfirmSubject = errors.New(InvalidAccessConfirmSubjectErrorName, "the subject of an access confirm invocation must be the service itself") + ErrInvalidAccessConfirmIssuer = errors.New(InvalidAccessConfirmIssuerErrorName, "the issuer of an access confirm invocation must be a valid mailto DID") +) diff --git a/capabilities/access/datamodel/json_gen.go b/capabilities/access/datamodel/json_gen.go index a43dd5f..6b110cc 100644 --- a/capabilities/access/datamodel/json_gen.go +++ b/capabilities/access/datamodel/json_gen.go @@ -32,33 +32,33 @@ func (t *RequestArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Attenuations ([]datamodel.CapabilityRequestModel) (slice) if len("att") > 8192 { - return fmt.Errorf("String in field \"att\" was too long") + return fmt.Errorf("string in field \"att\" was too long") } if err := jw.WriteString(string("att")); err != nil { - return fmt.Errorf("\"att\": %w", err) + return fmt.Errorf("writing string for field \"att\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if len(t.Attenuations) > 8192 { - return fmt.Errorf("Slice value in field t.Attenuations was too long") + return fmt.Errorf("slice value in field t.Attenuations was too long") } if err := jw.WriteArrayOpen(); err != nil { - return fmt.Errorf("t.Attenuations: %w", err) + return fmt.Errorf("writing array open for field t.Attenuations: %w", err) } for i, v := range t.Attenuations { if i > 0 { if err := jw.WriteComma(); err != nil { - return fmt.Errorf("t.Attenuations: %w", err) + return fmt.Errorf("writing comma for field t.Attenuations: %w", err) } } if err := v.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("v: %w", err) + return fmt.Errorf("marshaling field v: %w", err) } } if err := jw.WriteArrayClose(); err != nil { - return fmt.Errorf("t.Attenuations: %w", err) + return fmt.Errorf("writing array close for field t.Attenuations: %w", err) } written++ @@ -70,16 +70,16 @@ func (t *RequestArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Issuer (did.DID) (struct) if len("iss") > 8192 { - return fmt.Errorf("String in field \"iss\" was too long") + return fmt.Errorf("string in field \"iss\" was too long") } if err := jw.WriteString(string("iss")); err != nil { - return fmt.Errorf("\"iss\": %w", err) + return fmt.Errorf("writing string for field \"iss\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Issuer.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Issuer: %w", err) + return fmt.Errorf("marshaling field t.Issuer: %w", err) } written++ if err := jw.WriteObjectClose(); err != nil { @@ -97,27 +97,27 @@ func (t *RequestArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("RequestArgumentsModel: %w", err) + return fmt.Errorf("reading object open for RequestArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("RequestArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for RequestArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("RequestArgumentsModel: %w", err) + return fmt.Errorf("reading object close for RequestArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("RequestArgumentsModel: string too large") + return fmt.Errorf("reading string for field RequestArgumentsModel: string too large") } - return fmt.Errorf("RequestArgumentsModel: %w", err) + return fmt.Errorf("reading string for field RequestArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("RequestArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field RequestArgumentsModel: %w", err) } switch name { @@ -126,16 +126,16 @@ func (t *RequestArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { { if err := jr.ReadArrayOpen(); err != nil { - return fmt.Errorf("t.Attenuations: %w", err) + return fmt.Errorf("reading array open for field t.Attenuations: %w", err) } close, err := jr.PeekArrayClose() if err != nil { - return fmt.Errorf("t.Attenuations: %w", err) + return fmt.Errorf("peeking array close for field t.Attenuations: %w", err) } if close { if err := jr.ReadArrayClose(); err != nil { - return fmt.Errorf("t.Attenuations: %w", err) + return fmt.Errorf("reading array close for field t.Attenuations: %w", err) } } else { @@ -150,13 +150,13 @@ func (t *RequestArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { close, err := jr.ReadArrayCloseOrComma() if err != nil { - return fmt.Errorf("t.Attenuations: %w", err) + return fmt.Errorf("reading array close or comma for field t.Attenuations: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("t.Attenuations: slice too large") + return fmt.Errorf("reading array for field t.Attenuations: slice too large") } } } @@ -173,19 +173,19 @@ func (t *RequestArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("RequestArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for RequestArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("RequestArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field RequestArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("RequestArgumentsModel: map too large") + return fmt.Errorf("map too large for RequestArgumentsModel") } } } @@ -204,19 +204,19 @@ func (t *CapabilityRequestModel) MarshalDagJSON(w io.Writer) error { // t.Command (command.Command) (string) if len("cmd") > 8192 { - return fmt.Errorf("String in field \"cmd\" was too long") + return fmt.Errorf("string in field \"cmd\" was too long") } if err := jw.WriteString(string("cmd")); err != nil { - return fmt.Errorf("\"cmd\": %w", err) + return fmt.Errorf("writing string for field \"cmd\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if len(t.Command) > 8192 { - return fmt.Errorf("String in field t.Command was too long") + return fmt.Errorf("string in field t.Command was too long") } if err := jw.WriteString(string(t.Command)); err != nil { - return fmt.Errorf("t.Command: %w", err) + return fmt.Errorf("writing string for field t.Command: %w", err) } if err := jw.WriteObjectClose(); err != nil { return err @@ -233,27 +233,27 @@ func (t *CapabilityRequestModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("CapabilityRequestModel: %w", err) + return fmt.Errorf("reading object open for CapabilityRequestModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("CapabilityRequestModel: %w", err) + return fmt.Errorf("peeking object close for CapabilityRequestModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("CapabilityRequestModel: %w", err) + return fmt.Errorf("reading object close for CapabilityRequestModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("CapabilityRequestModel: string too large") + return fmt.Errorf("reading string for field CapabilityRequestModel: string too large") } - return fmt.Errorf("CapabilityRequestModel: %w", err) + return fmt.Errorf("reading string for field CapabilityRequestModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("CapabilityRequestModel: %w", err) + return fmt.Errorf("reading object colon for field CapabilityRequestModel: %w", err) } switch name { @@ -263,28 +263,28 @@ func (t *CapabilityRequestModel) UnmarshalDagJSON(r io.Reader) (err error) { sval, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("t.Command: string too long") + return fmt.Errorf("reading string for field t.Command: string too long") } - return fmt.Errorf("t.Command: %w", err) + return fmt.Errorf("reading string for field t.Command: %w", err) } t.Command = command.Command(sval) } default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("CapabilityRequestModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for CapabilityRequestModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("CapabilityRequestModel: %w", err) + return fmt.Errorf("reading object close or comma for field CapabilityRequestModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("CapabilityRequestModel: map too large") + return fmt.Errorf("map too large for CapabilityRequestModel") } } } @@ -304,16 +304,16 @@ func (t *RequestOKModel) MarshalDagJSON(w io.Writer) error { // t.Confirm (promise.AwaitOK) (struct) if len("confirm") > 8192 { - return fmt.Errorf("String in field \"confirm\" was too long") + return fmt.Errorf("string in field \"confirm\" was too long") } if err := jw.WriteString(string("confirm")); err != nil { - return fmt.Errorf("\"confirm\": %w", err) + return fmt.Errorf("writing string for field \"confirm\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Confirm.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Confirm: %w", err) + return fmt.Errorf("marshaling field t.Confirm: %w", err) } written++ if written > 0 { @@ -324,17 +324,17 @@ func (t *RequestOKModel) MarshalDagJSON(w io.Writer) error { // t.Expiration (int64) (int64) if len("exp") > 8192 { - return fmt.Errorf("String in field \"exp\" was too long") + return fmt.Errorf("string in field \"exp\" was too long") } if err := jw.WriteString(string("exp")); err != nil { - return fmt.Errorf("\"exp\": %w", err) + return fmt.Errorf("writing string for field \"exp\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteInt64(int64(t.Expiration)); err != nil { - return fmt.Errorf("t.Expiration: %w", err) + return fmt.Errorf("writing int64 for field t.Expiration: %w", err) } written++ @@ -346,17 +346,17 @@ func (t *RequestOKModel) MarshalDagJSON(w io.Writer) error { // t.Request (cid.Cid) (struct) if len("req") > 8192 { - return fmt.Errorf("String in field \"req\" was too long") + return fmt.Errorf("string in field \"req\" was too long") } if err := jw.WriteString(string("req")); err != nil { - return fmt.Errorf("\"req\": %w", err) + return fmt.Errorf("writing string for field \"req\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteCid(t.Request); err != nil { - return fmt.Errorf("t.Request: %w", err) + return fmt.Errorf("writing CID for field t.Request: %w", err) } written++ @@ -375,27 +375,27 @@ func (t *RequestOKModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("RequestOKModel: %w", err) + return fmt.Errorf("reading object open for RequestOKModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("RequestOKModel: %w", err) + return fmt.Errorf("peeking object close for RequestOKModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("RequestOKModel: %w", err) + return fmt.Errorf("reading object close for RequestOKModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("RequestOKModel: string too large") + return fmt.Errorf("reading string for field RequestOKModel: string too large") } - return fmt.Errorf("RequestOKModel: %w", err) + return fmt.Errorf("reading string for field RequestOKModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("RequestOKModel: %w", err) + return fmt.Errorf("reading object colon for field RequestOKModel: %w", err) } switch name { @@ -412,7 +412,7 @@ func (t *RequestOKModel) UnmarshalDagJSON(r io.Reader) (err error) { nval, err := jr.ReadNumberAsInt64() if err != nil { - return fmt.Errorf("t.Expiration: %w", err) + return fmt.Errorf("reading int64 for field t.Expiration: %w", err) } t.Expiration = int64(nval) @@ -424,7 +424,7 @@ func (t *RequestOKModel) UnmarshalDagJSON(r io.Reader) (err error) { c, err := jr.ReadCid() if err != nil { - return fmt.Errorf("t.Request: %w", err) + return fmt.Errorf("reading CID for field t.Request: %w", err) } t.Request = c @@ -432,19 +432,19 @@ func (t *RequestOKModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("RequestOKModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for RequestOKModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("RequestOKModel: %w", err) + return fmt.Errorf("reading object close or comma for field RequestOKModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("RequestOKModel: map too large") + return fmt.Errorf("map too large for RequestOKModel") } } } @@ -463,35 +463,35 @@ func (t *ClaimOKModel) MarshalDagJSON(w io.Writer) error { // t.Delegations ([]cid.Cid) (slice) if len("delegations") > 8192 { - return fmt.Errorf("String in field \"delegations\" was too long") + return fmt.Errorf("string in field \"delegations\" was too long") } if err := jw.WriteString(string("delegations")); err != nil { - return fmt.Errorf("\"delegations\": %w", err) + return fmt.Errorf("writing string for field \"delegations\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if len(t.Delegations) > 8192 { - return fmt.Errorf("Slice value in field t.Delegations was too long") + return fmt.Errorf("slice value in field t.Delegations was too long") } if err := jw.WriteArrayOpen(); err != nil { - return fmt.Errorf("t.Delegations: %w", err) + return fmt.Errorf("writing array open for field t.Delegations: %w", err) } for i, v := range t.Delegations { if i > 0 { if err := jw.WriteComma(); err != nil { - return fmt.Errorf("t.Delegations: %w", err) + return fmt.Errorf("writing comma for field t.Delegations: %w", err) } } if err := jw.WriteCid(v); err != nil { - return fmt.Errorf("v: %w", err) + return fmt.Errorf("writing CID for field v: %w", err) } } if err := jw.WriteArrayClose(); err != nil { - return fmt.Errorf("t.Delegations: %w", err) + return fmt.Errorf("writing array close for field t.Delegations: %w", err) } if err := jw.WriteObjectClose(); err != nil { @@ -509,27 +509,27 @@ func (t *ClaimOKModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("ClaimOKModel: %w", err) + return fmt.Errorf("reading object open for ClaimOKModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("ClaimOKModel: %w", err) + return fmt.Errorf("peeking object close for ClaimOKModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("ClaimOKModel: %w", err) + return fmt.Errorf("reading object close for ClaimOKModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("ClaimOKModel: string too large") + return fmt.Errorf("reading string for field ClaimOKModel: string too large") } - return fmt.Errorf("ClaimOKModel: %w", err) + return fmt.Errorf("reading string for field ClaimOKModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("ClaimOKModel: %w", err) + return fmt.Errorf("reading object colon for field ClaimOKModel: %w", err) } switch name { @@ -538,16 +538,16 @@ func (t *ClaimOKModel) UnmarshalDagJSON(r io.Reader) (err error) { { if err := jr.ReadArrayOpen(); err != nil { - return fmt.Errorf("t.Delegations: %w", err) + return fmt.Errorf("reading array open for field t.Delegations: %w", err) } close, err := jr.PeekArrayClose() if err != nil { - return fmt.Errorf("t.Delegations: %w", err) + return fmt.Errorf("peeking array close for field t.Delegations: %w", err) } if close { if err := jr.ReadArrayClose(); err != nil { - return fmt.Errorf("t.Delegations: %w", err) + return fmt.Errorf("reading array close for field t.Delegations: %w", err) } } else { @@ -557,7 +557,7 @@ func (t *ClaimOKModel) UnmarshalDagJSON(r io.Reader) (err error) { c, err := jr.ReadCid() if err != nil { - return fmt.Errorf("item[0]: %w", err) + return fmt.Errorf("reading CID for field item[0]: %w", err) } item[0] = c @@ -566,13 +566,13 @@ func (t *ClaimOKModel) UnmarshalDagJSON(r io.Reader) (err error) { close, err := jr.ReadArrayCloseOrComma() if err != nil { - return fmt.Errorf("t.Delegations: %w", err) + return fmt.Errorf("reading array close or comma for field t.Delegations: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("t.Delegations: slice too large") + return fmt.Errorf("reading array for field t.Delegations: slice too large") } } } @@ -581,19 +581,19 @@ func (t *ClaimOKModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("ClaimOKModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for ClaimOKModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("ClaimOKModel: %w", err) + return fmt.Errorf("reading object close or comma for field ClaimOKModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("ClaimOKModel: map too large") + return fmt.Errorf("map too large for ClaimOKModel") } } } @@ -613,33 +613,33 @@ func (t *ConfirmArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Attenuations ([]datamodel.CapabilityRequestModel) (slice) if len("att") > 8192 { - return fmt.Errorf("String in field \"att\" was too long") + return fmt.Errorf("string in field \"att\" was too long") } if err := jw.WriteString(string("att")); err != nil { - return fmt.Errorf("\"att\": %w", err) + return fmt.Errorf("writing string for field \"att\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if len(t.Attenuations) > 8192 { - return fmt.Errorf("Slice value in field t.Attenuations was too long") + return fmt.Errorf("slice value in field t.Attenuations was too long") } if err := jw.WriteArrayOpen(); err != nil { - return fmt.Errorf("t.Attenuations: %w", err) + return fmt.Errorf("writing array open for field t.Attenuations: %w", err) } for i, v := range t.Attenuations { if i > 0 { if err := jw.WriteComma(); err != nil { - return fmt.Errorf("t.Attenuations: %w", err) + return fmt.Errorf("writing comma for field t.Attenuations: %w", err) } } if err := v.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("v: %w", err) + return fmt.Errorf("marshaling field v: %w", err) } } if err := jw.WriteArrayClose(); err != nil { - return fmt.Errorf("t.Attenuations: %w", err) + return fmt.Errorf("writing array close for field t.Attenuations: %w", err) } written++ @@ -651,16 +651,16 @@ func (t *ConfirmArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Audience (did.DID) (struct) if len("aud") > 8192 { - return fmt.Errorf("String in field \"aud\" was too long") + return fmt.Errorf("string in field \"aud\" was too long") } if err := jw.WriteString(string("aud")); err != nil { - return fmt.Errorf("\"aud\": %w", err) + return fmt.Errorf("writing string for field \"aud\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Audience.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Audience: %w", err) + return fmt.Errorf("marshaling field t.Audience: %w", err) } written++ if written > 0 { @@ -671,17 +671,17 @@ func (t *ConfirmArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Cause (cid.Cid) (struct) if len("cause") > 8192 { - return fmt.Errorf("String in field \"cause\" was too long") + return fmt.Errorf("string in field \"cause\" was too long") } if err := jw.WriteString(string("cause")); err != nil { - return fmt.Errorf("\"cause\": %w", err) + return fmt.Errorf("writing string for field \"cause\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteCid(t.Cause); err != nil { - return fmt.Errorf("t.Cause: %w", err) + return fmt.Errorf("writing CID for field t.Cause: %w", err) } written++ @@ -693,16 +693,16 @@ func (t *ConfirmArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Issuer (did.DID) (struct) if len("iss") > 8192 { - return fmt.Errorf("String in field \"iss\" was too long") + return fmt.Errorf("string in field \"iss\" was too long") } if err := jw.WriteString(string("iss")); err != nil { - return fmt.Errorf("\"iss\": %w", err) + return fmt.Errorf("writing string for field \"iss\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Issuer.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Issuer: %w", err) + return fmt.Errorf("marshaling field t.Issuer: %w", err) } written++ if err := jw.WriteObjectClose(); err != nil { @@ -720,27 +720,27 @@ func (t *ConfirmArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("ConfirmArgumentsModel: %w", err) + return fmt.Errorf("reading object open for ConfirmArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("ConfirmArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for ConfirmArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("ConfirmArgumentsModel: %w", err) + return fmt.Errorf("reading object close for ConfirmArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("ConfirmArgumentsModel: string too large") + return fmt.Errorf("reading string for field ConfirmArgumentsModel: string too large") } - return fmt.Errorf("ConfirmArgumentsModel: %w", err) + return fmt.Errorf("reading string for field ConfirmArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("ConfirmArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field ConfirmArgumentsModel: %w", err) } switch name { @@ -749,16 +749,16 @@ func (t *ConfirmArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { { if err := jr.ReadArrayOpen(); err != nil { - return fmt.Errorf("t.Attenuations: %w", err) + return fmt.Errorf("reading array open for field t.Attenuations: %w", err) } close, err := jr.PeekArrayClose() if err != nil { - return fmt.Errorf("t.Attenuations: %w", err) + return fmt.Errorf("peeking array close for field t.Attenuations: %w", err) } if close { if err := jr.ReadArrayClose(); err != nil { - return fmt.Errorf("t.Attenuations: %w", err) + return fmt.Errorf("reading array close for field t.Attenuations: %w", err) } } else { @@ -773,13 +773,13 @@ func (t *ConfirmArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { close, err := jr.ReadArrayCloseOrComma() if err != nil { - return fmt.Errorf("t.Attenuations: %w", err) + return fmt.Errorf("reading array close or comma for field t.Attenuations: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("t.Attenuations: slice too large") + return fmt.Errorf("reading array for field t.Attenuations: slice too large") } } } @@ -799,7 +799,7 @@ func (t *ConfirmArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { c, err := jr.ReadCid() if err != nil { - return fmt.Errorf("t.Cause: %w", err) + return fmt.Errorf("reading CID for field t.Cause: %w", err) } t.Cause = c @@ -815,19 +815,19 @@ func (t *ConfirmArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("ConfirmArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for ConfirmArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("ConfirmArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field ConfirmArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("ConfirmArgumentsModel: map too large") + return fmt.Errorf("map too large for ConfirmArgumentsModel") } } } @@ -846,35 +846,35 @@ func (t *DelegateArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Delegations ([]cid.Cid) (slice) if len("delegations") > 8192 { - return fmt.Errorf("String in field \"delegations\" was too long") + return fmt.Errorf("string in field \"delegations\" was too long") } if err := jw.WriteString(string("delegations")); err != nil { - return fmt.Errorf("\"delegations\": %w", err) + return fmt.Errorf("writing string for field \"delegations\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if len(t.Delegations) > 8192 { - return fmt.Errorf("Slice value in field t.Delegations was too long") + return fmt.Errorf("slice value in field t.Delegations was too long") } if err := jw.WriteArrayOpen(); err != nil { - return fmt.Errorf("t.Delegations: %w", err) + return fmt.Errorf("writing array open for field t.Delegations: %w", err) } for i, v := range t.Delegations { if i > 0 { if err := jw.WriteComma(); err != nil { - return fmt.Errorf("t.Delegations: %w", err) + return fmt.Errorf("writing comma for field t.Delegations: %w", err) } } if err := jw.WriteCid(v); err != nil { - return fmt.Errorf("v: %w", err) + return fmt.Errorf("writing CID for field v: %w", err) } } if err := jw.WriteArrayClose(); err != nil { - return fmt.Errorf("t.Delegations: %w", err) + return fmt.Errorf("writing array close for field t.Delegations: %w", err) } if err := jw.WriteObjectClose(); err != nil { @@ -892,27 +892,27 @@ func (t *DelegateArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("DelegateArgumentsModel: %w", err) + return fmt.Errorf("reading object open for DelegateArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("DelegateArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for DelegateArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("DelegateArgumentsModel: %w", err) + return fmt.Errorf("reading object close for DelegateArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("DelegateArgumentsModel: string too large") + return fmt.Errorf("reading string for field DelegateArgumentsModel: string too large") } - return fmt.Errorf("DelegateArgumentsModel: %w", err) + return fmt.Errorf("reading string for field DelegateArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("DelegateArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field DelegateArgumentsModel: %w", err) } switch name { @@ -921,16 +921,16 @@ func (t *DelegateArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { { if err := jr.ReadArrayOpen(); err != nil { - return fmt.Errorf("t.Delegations: %w", err) + return fmt.Errorf("reading array open for field t.Delegations: %w", err) } close, err := jr.PeekArrayClose() if err != nil { - return fmt.Errorf("t.Delegations: %w", err) + return fmt.Errorf("peeking array close for field t.Delegations: %w", err) } if close { if err := jr.ReadArrayClose(); err != nil { - return fmt.Errorf("t.Delegations: %w", err) + return fmt.Errorf("reading array close for field t.Delegations: %w", err) } } else { @@ -940,7 +940,7 @@ func (t *DelegateArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { c, err := jr.ReadCid() if err != nil { - return fmt.Errorf("item[0]: %w", err) + return fmt.Errorf("reading CID for field item[0]: %w", err) } item[0] = c @@ -949,13 +949,13 @@ func (t *DelegateArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { close, err := jr.ReadArrayCloseOrComma() if err != nil { - return fmt.Errorf("t.Delegations: %w", err) + return fmt.Errorf("reading array close or comma for field t.Delegations: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("t.Delegations: slice too large") + return fmt.Errorf("reading array for field t.Delegations: slice too large") } } } @@ -964,19 +964,19 @@ func (t *DelegateArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("DelegateArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for DelegateArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("DelegateArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field DelegateArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("DelegateArgumentsModel: map too large") + return fmt.Errorf("map too large for DelegateArgumentsModel") } } } diff --git a/capabilities/access/delegate.go b/capabilities/access/delegate.go index c060f17..41a65ef 100644 --- a/capabilities/access/delegate.go +++ b/capabilities/access/delegate.go @@ -16,3 +16,8 @@ const DelegateCommand = "/access/delegate" // Delegate can be invoked by an agent to delegate a set of capabilities that // may be subsequently claimed by another agent. var Delegate, _ = bindcap.New[*DelegateArguments](DelegateCommand) + +const ( + DelegationNotFoundErrorName = "DelegationNotFound" + InsufficientStorageErrorName = "InsufficientStorage" +) diff --git a/capabilities/access/request.go b/capabilities/access/request.go index a00a3b8..32b8327 100644 --- a/capabilities/access/request.go +++ b/capabilities/access/request.go @@ -21,3 +21,8 @@ const RequestCommand = "/access/request" // Request can be invoked by an agent to request set of capabilities from the // account. var Request, _ = bindcap.New[*RequestArguments](RequestCommand) + +const ( + InvalidAuthorizationAccountErrorName = "InvalidAuthorizationAccount" + InvalidAuthorizationAudienceErrorName = "InvalidAuthorizationAudience" +) diff --git a/capabilities/assert/datamodel/cbor_gen.go b/capabilities/assert/datamodel/cbor_gen.go index e510d6e..e1f110b 100644 --- a/capabilities/assert/datamodel/cbor_gen.go +++ b/capabilities/assert/datamodel/cbor_gen.go @@ -27,7 +27,7 @@ func (t *IndexArgumentsModel) MarshalCBOR(w io.Writer) error { cw := cbg.NewCborWriter(w) - if _, err := cw.Write([]byte{162}); err != nil { + if _, err := cw.Write([]byte{161}); err != nil { return err } @@ -47,22 +47,6 @@ func (t *IndexArgumentsModel) MarshalCBOR(w io.Writer) error { return xerrors.Errorf("failed to write cid field t.Index: %w", err) } - // t.Content (cid.Cid) (struct) - if len("content") > 8192 { - return xerrors.Errorf("Value in field \"content\" was too long") - } - - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("content"))); err != nil { - return err - } - if _, err := cw.WriteString(string("content")); err != nil { - return err - } - - if err := cbg.WriteCid(cw, t.Content); err != nil { - return xerrors.Errorf("failed to write cid field t.Content: %w", err) - } - return nil } @@ -91,7 +75,7 @@ func (t *IndexArgumentsModel) UnmarshalCBOR(r io.Reader) (err error) { n := extra - nameBuf := make([]byte, 7) + nameBuf := make([]byte, 5) for i := uint64(0); i < n; i++ { nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) if err != nil { @@ -120,19 +104,6 @@ func (t *IndexArgumentsModel) UnmarshalCBOR(r io.Reader) (err error) { t.Index = c } - // t.Content (cid.Cid) (struct) - case "content": - - { - - c, err := cbg.ReadCid(cr) - if err != nil { - return xerrors.Errorf("failed to read cid field t.Content: %w", err) - } - - t.Content = c - - } default: // Field doesn't exist on this type, so ignore it diff --git a/capabilities/assert/datamodel/index.go b/capabilities/assert/datamodel/index.go index d563b68..fc99a05 100644 --- a/capabilities/assert/datamodel/index.go +++ b/capabilities/assert/datamodel/index.go @@ -3,6 +3,5 @@ package datamodel import "github.com/ipfs/go-cid" type IndexArgumentsModel struct { - Content cid.Cid `cborgen:"content" dagjsongen:"content"` - Index cid.Cid `cborgen:"index" dagjsongen:"index"` + Index cid.Cid `cborgen:"index" dagjsongen:"index"` } diff --git a/capabilities/assert/datamodel/json_gen.go b/capabilities/assert/datamodel/json_gen.go index 6c699c3..c9ec133 100644 --- a/capabilities/assert/datamodel/json_gen.go +++ b/capabilities/assert/datamodel/json_gen.go @@ -28,46 +28,22 @@ func (t *IndexArgumentsModel) MarshalDagJSON(w io.Writer) error { if err := jw.WriteObjectOpen(); err != nil { return err } - written := 0 - - // t.Content (cid.Cid) (struct) - if len("content") > 8192 { - return fmt.Errorf("String in field \"content\" was too long") - } - if err := jw.WriteString(string("content")); err != nil { - return fmt.Errorf("\"content\": %w", err) - } - if err := jw.WriteObjectColon(); err != nil { - return err - } - - if err := jw.WriteCid(t.Content); err != nil { - return fmt.Errorf("t.Content: %w", err) - } - - written++ - if written > 0 { - if err := jw.WriteComma(); err != nil { - return err - } - } // t.Index (cid.Cid) (struct) if len("index") > 8192 { - return fmt.Errorf("String in field \"index\" was too long") + return fmt.Errorf("string in field \"index\" was too long") } if err := jw.WriteString(string("index")); err != nil { - return fmt.Errorf("\"index\": %w", err) + return fmt.Errorf("writing string for field \"index\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteCid(t.Index); err != nil { - return fmt.Errorf("t.Index: %w", err) + return fmt.Errorf("writing CID for field t.Index: %w", err) } - written++ if err := jw.WriteObjectClose(); err != nil { return err } @@ -83,49 +59,37 @@ func (t *IndexArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("IndexArgumentsModel: %w", err) + return fmt.Errorf("reading object open for IndexArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("IndexArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for IndexArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("IndexArgumentsModel: %w", err) + return fmt.Errorf("reading object close for IndexArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("IndexArgumentsModel: string too large") + return fmt.Errorf("reading string for field IndexArgumentsModel: string too large") } - return fmt.Errorf("IndexArgumentsModel: %w", err) + return fmt.Errorf("reading string for field IndexArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("IndexArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field IndexArgumentsModel: %w", err) } switch name { - // t.Content (cid.Cid) (struct) - case "content": - { - - c, err := jr.ReadCid() - if err != nil { - return fmt.Errorf("t.Content: %w", err) - } - t.Content = c - - } - - // t.Index (cid.Cid) (struct) + // t.Index (cid.Cid) (struct) case "index": { c, err := jr.ReadCid() if err != nil { - return fmt.Errorf("t.Index: %w", err) + return fmt.Errorf("reading CID for field t.Index: %w", err) } t.Index = c @@ -133,19 +97,19 @@ func (t *IndexArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("IndexArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for IndexArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("IndexArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field IndexArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("IndexArgumentsModel: map too large") + return fmt.Errorf("map too large for IndexArgumentsModel") } } } @@ -165,20 +129,20 @@ func (t *LocationArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Content (multihash.Multihash) (slice) if len("content") > 8192 { - return fmt.Errorf("String in field \"content\" was too long") + return fmt.Errorf("string in field \"content\" was too long") } if err := jw.WriteString(string("content")); err != nil { - return fmt.Errorf("\"content\": %w", err) + return fmt.Errorf("writing string for field \"content\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if len(t.Content) > 2097152 { - return fmt.Errorf("Byte array in field t.Content was too long") + return fmt.Errorf("byte array in field t.Content was too long") } if err := jw.WriteBytes(t.Content); err != nil { - return fmt.Errorf("t.Content: %w", err) + return fmt.Errorf("writing bytes for field t.Content: %w", err) } written++ @@ -190,33 +154,33 @@ func (t *LocationArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Location ([]capabilities.CborURL) (slice) if len("location") > 8192 { - return fmt.Errorf("String in field \"location\" was too long") + return fmt.Errorf("string in field \"location\" was too long") } if err := jw.WriteString(string("location")); err != nil { - return fmt.Errorf("\"location\": %w", err) + return fmt.Errorf("writing string for field \"location\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if len(t.Location) > 8192 { - return fmt.Errorf("Slice value in field t.Location was too long") + return fmt.Errorf("slice value in field t.Location was too long") } if err := jw.WriteArrayOpen(); err != nil { - return fmt.Errorf("t.Location: %w", err) + return fmt.Errorf("writing array open for field t.Location: %w", err) } for i, v := range t.Location { if i > 0 { if err := jw.WriteComma(); err != nil { - return fmt.Errorf("t.Location: %w", err) + return fmt.Errorf("writing comma for field t.Location: %w", err) } } if err := v.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("v: %w", err) + return fmt.Errorf("marshaling field v: %w", err) } } if err := jw.WriteArrayClose(); err != nil { - return fmt.Errorf("t.Location: %w", err) + return fmt.Errorf("writing array close for field t.Location: %w", err) } written++ @@ -231,16 +195,16 @@ func (t *LocationArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Range (datamodel.RangeModel) (struct) if t.Range != nil { if len("range") > 8192 { - return fmt.Errorf("String in field \"range\" was too long") + return fmt.Errorf("string in field \"range\" was too long") } if err := jw.WriteString(string("range")); err != nil { - return fmt.Errorf("\"range\": %w", err) + return fmt.Errorf("writing string for field \"range\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Range.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Range: %w", err) + return fmt.Errorf("marshaling field t.Range: %w", err) } written++ } @@ -252,16 +216,16 @@ func (t *LocationArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Space (did.DID) (struct) if len("space") > 8192 { - return fmt.Errorf("String in field \"space\" was too long") + return fmt.Errorf("string in field \"space\" was too long") } if err := jw.WriteString(string("space")); err != nil { - return fmt.Errorf("\"space\": %w", err) + return fmt.Errorf("writing string for field \"space\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Space.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Space: %w", err) + return fmt.Errorf("marshaling field t.Space: %w", err) } written++ if err := jw.WriteObjectClose(); err != nil { @@ -279,27 +243,27 @@ func (t *LocationArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("LocationArgumentsModel: %w", err) + return fmt.Errorf("reading object open for LocationArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("LocationArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for LocationArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("LocationArgumentsModel: %w", err) + return fmt.Errorf("reading object close for LocationArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("LocationArgumentsModel: string too large") + return fmt.Errorf("reading string for field LocationArgumentsModel: string too large") } - return fmt.Errorf("LocationArgumentsModel: %w", err) + return fmt.Errorf("reading string for field LocationArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("LocationArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field LocationArgumentsModel: %w", err) } switch name { @@ -310,9 +274,9 @@ func (t *LocationArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { bval, err := jr.ReadBytes(2097152) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("t.Content: byte array too large") + return fmt.Errorf("reading bytes for field t.Content: byte array too large") } - return fmt.Errorf("t.Content: %w", err) + return fmt.Errorf("reading bytes for field t.Content: %w", err) } if len(bval) > 0 { t.Content = []uint8(bval) @@ -324,16 +288,16 @@ func (t *LocationArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { { if err := jr.ReadArrayOpen(); err != nil { - return fmt.Errorf("t.Location: %w", err) + return fmt.Errorf("reading array open for field t.Location: %w", err) } close, err := jr.PeekArrayClose() if err != nil { - return fmt.Errorf("t.Location: %w", err) + return fmt.Errorf("peeking array close for field t.Location: %w", err) } if close { if err := jr.ReadArrayClose(); err != nil { - return fmt.Errorf("t.Location: %w", err) + return fmt.Errorf("reading array close for field t.Location: %w", err) } } else { @@ -348,13 +312,13 @@ func (t *LocationArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { close, err := jr.ReadArrayCloseOrComma() if err != nil { - return fmt.Errorf("t.Location: %w", err) + return fmt.Errorf("reading array close or comma for field t.Location: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("t.Location: slice too large") + return fmt.Errorf("reading array for field t.Location: slice too large") } } } @@ -367,11 +331,11 @@ func (t *LocationArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { { null, err := jr.PeekNull() if err != nil { - return fmt.Errorf("t.Range: %w", err) + return fmt.Errorf("peeking null for field t.Range: %w", err) } if null { if err := jr.ReadNull(); err != nil { - return fmt.Errorf("t.Range: %w", err) + return fmt.Errorf("reading null for field t.Range: %w", err) } } else { t.Range = new(RangeModel) @@ -391,19 +355,19 @@ func (t *LocationArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("LocationArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for LocationArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("LocationArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field LocationArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("LocationArgumentsModel: map too large") + return fmt.Errorf("map too large for LocationArgumentsModel") } } } @@ -424,10 +388,10 @@ func (t *RangeModel) MarshalDagJSON(w io.Writer) error { // t.Length (uint64) (uint64) if t.Length != nil { if len("length") > 8192 { - return fmt.Errorf("String in field \"length\" was too long") + return fmt.Errorf("string in field \"length\" was too long") } if err := jw.WriteString(string("length")); err != nil { - return fmt.Errorf("\"length\": %w", err) + return fmt.Errorf("writing string for field \"length\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err @@ -435,11 +399,11 @@ func (t *RangeModel) MarshalDagJSON(w io.Writer) error { if t.Length == nil { if err := jw.WriteNull(); err != nil { - return fmt.Errorf("t.Length: %w", err) + return fmt.Errorf("writing null for field t.Length: %w", err) } } else { if err := jw.WriteUint64(uint64(*t.Length)); err != nil { - return fmt.Errorf("t.Length: %w", err) + return fmt.Errorf("writing uint64 for field t.Length: %w", err) } } @@ -453,17 +417,17 @@ func (t *RangeModel) MarshalDagJSON(w io.Writer) error { // t.Offset (uint64) (uint64) if len("offset") > 8192 { - return fmt.Errorf("String in field \"offset\" was too long") + return fmt.Errorf("string in field \"offset\" was too long") } if err := jw.WriteString(string("offset")); err != nil { - return fmt.Errorf("\"offset\": %w", err) + return fmt.Errorf("writing string for field \"offset\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteUint64(uint64(t.Offset)); err != nil { - return fmt.Errorf("t.Offset: %w", err) + return fmt.Errorf("writing uint64 for field t.Offset: %w", err) } written++ @@ -482,27 +446,27 @@ func (t *RangeModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("RangeModel: %w", err) + return fmt.Errorf("reading object open for RangeModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("RangeModel: %w", err) + return fmt.Errorf("peeking object close for RangeModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("RangeModel: %w", err) + return fmt.Errorf("reading object close for RangeModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("RangeModel: string too large") + return fmt.Errorf("reading string for field RangeModel: string too large") } - return fmt.Errorf("RangeModel: %w", err) + return fmt.Errorf("reading string for field RangeModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("RangeModel: %w", err) + return fmt.Errorf("reading object colon for field RangeModel: %w", err) } switch name { @@ -512,7 +476,7 @@ func (t *RangeModel) UnmarshalDagJSON(r io.Reader) (err error) { nval, err := jr.ReadNumberAsUint64OrNull() if err != nil { - return fmt.Errorf("t.Length: %w", err) + return fmt.Errorf("reading uint64 or null for field t.Length: %w", err) } if nval != nil { typed := uint64(*nval) @@ -527,7 +491,7 @@ func (t *RangeModel) UnmarshalDagJSON(r io.Reader) (err error) { nval, err := jr.ReadNumberAsUint64() if err != nil { - return fmt.Errorf("t.Offset: %w", err) + return fmt.Errorf("reading uint64 for field t.Offset: %w", err) } t.Offset = uint64(nval) @@ -535,19 +499,19 @@ func (t *RangeModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("RangeModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for RangeModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("RangeModel: %w", err) + return fmt.Errorf("reading object close or comma for field RangeModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("RangeModel: map too large") + return fmt.Errorf("map too large for RangeModel") } } } diff --git a/capabilities/blob/datamodel/add.go b/capabilities/blob/datamodel/add.go index 614496b..7f34f18 100644 --- a/capabilities/blob/datamodel/add.go +++ b/capabilities/blob/datamodel/add.go @@ -15,5 +15,7 @@ type AddArgumentsModel struct { } type AddOKModel struct { + // Site is a promise of the `/blob/accept` task result, which contains a + // location claim for the blob, describing where it can be retrieved from. Site promise.AwaitOK `cborgen:"site" dagjsongen:"site"` } diff --git a/capabilities/blob/datamodel/allocate.go b/capabilities/blob/datamodel/allocate.go index bc678a6..4747a38 100644 --- a/capabilities/blob/datamodel/allocate.go +++ b/capabilities/blob/datamodel/allocate.go @@ -16,7 +16,7 @@ type AllocateOKModel struct { } type BlobAddressModel struct { - URL capabilities.CborURL `cborgen:"url" dagjsongen:"url"` - Headers map[string]string `cborgen:"headers" dagjsongen:"headers"` - Expires capabilities.CborTime `cborgen:"expires" dagjsongen:"expires"` + URL capabilities.CborURL `cborgen:"url" dagjsongen:"url"` + Headers map[string]string `cborgen:"headers" dagjsongen:"headers"` + Expires int64 `cborgen:"expires" dagjsongen:"expires"` } diff --git a/capabilities/blob/datamodel/cbor_gen.go b/capabilities/blob/datamodel/cbor_gen.go index 06694d5..6595338 100644 --- a/capabilities/blob/datamodel/cbor_gen.go +++ b/capabilities/blob/datamodel/cbor_gen.go @@ -454,7 +454,7 @@ func (t *BlobAddressModel) MarshalCBOR(w io.Writer) error { return err } - // t.Expires (capabilities.CborTime) (struct) + // t.Expires (int64) (int64) if len("expires") > 8192 { return xerrors.Errorf("Value in field \"expires\" was too long") } @@ -466,8 +466,14 @@ func (t *BlobAddressModel) MarshalCBOR(w io.Writer) error { return err } - if err := t.Expires.MarshalCBOR(cw); err != nil { - return err + if t.Expires >= 0 { + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Expires)); err != nil { + return err + } + } else { + if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.Expires-1)); err != nil { + return err + } } // t.Headers (map[string]string) (map) @@ -577,15 +583,31 @@ func (t *BlobAddressModel) UnmarshalCBOR(r io.Reader) (err error) { } } - // t.Expires (capabilities.CborTime) (struct) + // t.Expires (int64) (int64) case "expires": - { - - if err := t.Expires.UnmarshalCBOR(cr); err != nil { - return xerrors.Errorf("unmarshaling t.Expires: %w", err) + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + var extraI int64 + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative overflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) } + t.Expires = int64(extraI) } // t.Headers (map[string]string) (map) case "headers": @@ -1436,3 +1458,577 @@ func (t *ReplicateOKModel) UnmarshalCBOR(r io.Reader) (err error) { return nil } +func (t *ListArgumentsModel) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + fieldCount := 2 + + if t.Cursor == nil { + fieldCount-- + } + + if t.Size == nil { + fieldCount-- + } + + if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil { + return err + } + + // t.Size (int64) (int64) + if t.Size != nil { + + if len("size") > 8192 { + return xerrors.Errorf("Value in field \"size\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("size"))); err != nil { + return err + } + if _, err := cw.WriteString(string("size")); err != nil { + return err + } + + if t.Size == nil { + if _, err := cw.Write(cbg.CborNull); err != nil { + return err + } + } else { + if *t.Size >= 0 { + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(*t.Size)); err != nil { + return err + } + } else { + if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-*t.Size-1)); err != nil { + return err + } + } + } + + } + + // t.Cursor (string) (string) + if t.Cursor != nil { + + if len("cursor") > 8192 { + return xerrors.Errorf("Value in field \"cursor\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("cursor"))); err != nil { + return err + } + if _, err := cw.WriteString(string("cursor")); err != nil { + return err + } + + if t.Cursor == nil { + if _, err := cw.Write(cbg.CborNull); err != nil { + return err + } + } else { + if len(*t.Cursor) > 8192 { + return xerrors.Errorf("Value in field t.Cursor was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Cursor))); err != nil { + return err + } + if _, err := cw.WriteString(string(*t.Cursor)); err != nil { + return err + } + } + } + return nil +} + +func (t *ListArgumentsModel) UnmarshalCBOR(r io.Reader) (err error) { + *t = ListArgumentsModel{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("ListArgumentsModel: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 6) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Size (int64) (int64) + case "size": + { + + b, err := cr.ReadByte() + if err != nil { + return err + } + if b != cbg.CborNull[0] { + if err := cr.UnreadByte(); err != nil { + return err + } + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + var extraI int64 + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative overflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.Size = (*int64)(&extraI) + } + } + // t.Cursor (string) (string) + case "cursor": + + { + b, err := cr.ReadByte() + if err != nil { + return err + } + if b != cbg.CborNull[0] { + if err := cr.UnreadByte(); err != nil { + return err + } + + sval, err := cbg.ReadStringWithMax(cr, 8192) + if err != nil { + return err + } + + t.Cursor = (*string)(&sval) + } + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *ListOKModel) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + fieldCount := 3 + + if t.Cursor == nil { + fieldCount-- + } + + if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil { + return err + } + + // t.Size (int64) (int64) + if len("size") > 8192 { + return xerrors.Errorf("Value in field \"size\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("size"))); err != nil { + return err + } + if _, err := cw.WriteString(string("size")); err != nil { + return err + } + + if t.Size >= 0 { + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Size)); err != nil { + return err + } + } else { + if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.Size-1)); err != nil { + return err + } + } + + // t.Cursor (string) (string) + if t.Cursor != nil { + + if len("cursor") > 8192 { + return xerrors.Errorf("Value in field \"cursor\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("cursor"))); err != nil { + return err + } + if _, err := cw.WriteString(string("cursor")); err != nil { + return err + } + + if t.Cursor == nil { + if _, err := cw.Write(cbg.CborNull); err != nil { + return err + } + } else { + if len(*t.Cursor) > 8192 { + return xerrors.Errorf("Value in field t.Cursor was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Cursor))); err != nil { + return err + } + if _, err := cw.WriteString(string(*t.Cursor)); err != nil { + return err + } + } + } + + // t.Results ([]datamodel.ListBlobItem) (slice) + if len("results") > 8192 { + return xerrors.Errorf("Value in field \"results\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("results"))); err != nil { + return err + } + if _, err := cw.WriteString(string("results")); err != nil { + return err + } + + if len(t.Results) > 8192 { + return xerrors.Errorf("Slice value in field t.Results was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Results))); err != nil { + return err + } + for _, v := range t.Results { + if err := v.MarshalCBOR(cw); err != nil { + return err + } + + } + return nil +} + +func (t *ListOKModel) UnmarshalCBOR(r io.Reader) (err error) { + *t = ListOKModel{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("ListOKModel: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 7) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Size (int64) (int64) + case "size": + { + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + var extraI int64 + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative overflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.Size = int64(extraI) + } + // t.Cursor (string) (string) + case "cursor": + + { + b, err := cr.ReadByte() + if err != nil { + return err + } + if b != cbg.CborNull[0] { + if err := cr.UnreadByte(); err != nil { + return err + } + + sval, err := cbg.ReadStringWithMax(cr, 8192) + if err != nil { + return err + } + + t.Cursor = (*string)(&sval) + } + } + // t.Results ([]datamodel.ListBlobItem) (slice) + case "results": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 8192 { + return fmt.Errorf("t.Results: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.Results = make([]ListBlobItem, extra) + } + + for i := 0; i < int(extra); i++ { + { + var maj byte + var extra uint64 + var err error + _ = maj + _ = extra + _ = err + + { + + if err := t.Results[i].UnmarshalCBOR(cr); err != nil { + return xerrors.Errorf("unmarshaling t.Results[i]: %w", err) + } + + } + + } + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *ListBlobItem) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{162}); err != nil { + return err + } + + // t.Blob (datamodel.BlobModel) (struct) + if len("blob") > 8192 { + return xerrors.Errorf("Value in field \"blob\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("blob"))); err != nil { + return err + } + if _, err := cw.WriteString(string("blob")); err != nil { + return err + } + + if err := t.Blob.MarshalCBOR(cw); err != nil { + return err + } + + // t.InsertedAt (int64) (int64) + if len("insertedAt") > 8192 { + return xerrors.Errorf("Value in field \"insertedAt\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("insertedAt"))); err != nil { + return err + } + if _, err := cw.WriteString(string("insertedAt")); err != nil { + return err + } + + if t.InsertedAt >= 0 { + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.InsertedAt)); err != nil { + return err + } + } else { + if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.InsertedAt-1)); err != nil { + return err + } + } + + return nil +} + +func (t *ListBlobItem) UnmarshalCBOR(r io.Reader) (err error) { + *t = ListBlobItem{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("ListBlobItem: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 10) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Blob (datamodel.BlobModel) (struct) + case "blob": + + { + + if err := t.Blob.UnmarshalCBOR(cr); err != nil { + return xerrors.Errorf("unmarshaling t.Blob: %w", err) + } + + } + // t.InsertedAt (int64) (int64) + case "insertedAt": + { + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + var extraI int64 + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative overflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.InsertedAt = int64(extraI) + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} diff --git a/capabilities/blob/datamodel/gen/main.go b/capabilities/blob/datamodel/gen/main.go index 4e98208..77c1e13 100644 --- a/capabilities/blob/datamodel/gen/main.go +++ b/capabilities/blob/datamodel/gen/main.go @@ -21,6 +21,9 @@ func main() { bdm.RemoveArgumentsModel{}, bdm.ReplicateArgumentsModel{}, bdm.ReplicateOKModel{}, + bdm.ListArgumentsModel{}, + bdm.ListOKModel{}, + bdm.ListBlobItem{}, } if err := cbg.WriteMapEncodersToFile("../cbor_gen.go", "datamodel", models...); err != nil { panic(err) diff --git a/capabilities/blob/datamodel/json_gen.go b/capabilities/blob/datamodel/json_gen.go index a7cab34..cd1f79c 100644 --- a/capabilities/blob/datamodel/json_gen.go +++ b/capabilities/blob/datamodel/json_gen.go @@ -32,16 +32,16 @@ func (t *AllocateArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Blob (datamodel.BlobModel) (struct) if len("blob") > 8192 { - return fmt.Errorf("String in field \"blob\" was too long") + return fmt.Errorf("string in field \"blob\" was too long") } if err := jw.WriteString(string("blob")); err != nil { - return fmt.Errorf("\"blob\": %w", err) + return fmt.Errorf("writing string for field \"blob\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Blob.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Blob: %w", err) + return fmt.Errorf("marshaling field t.Blob: %w", err) } written++ if written > 0 { @@ -52,17 +52,17 @@ func (t *AllocateArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Cause (cid.Cid) (struct) if len("cause") > 8192 { - return fmt.Errorf("String in field \"cause\" was too long") + return fmt.Errorf("string in field \"cause\" was too long") } if err := jw.WriteString(string("cause")); err != nil { - return fmt.Errorf("\"cause\": %w", err) + return fmt.Errorf("writing string for field \"cause\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteCid(t.Cause); err != nil { - return fmt.Errorf("t.Cause: %w", err) + return fmt.Errorf("writing CID for field t.Cause: %w", err) } written++ @@ -81,27 +81,27 @@ func (t *AllocateArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("AllocateArgumentsModel: %w", err) + return fmt.Errorf("reading object open for AllocateArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("AllocateArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for AllocateArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("AllocateArgumentsModel: %w", err) + return fmt.Errorf("reading object close for AllocateArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("AllocateArgumentsModel: string too large") + return fmt.Errorf("reading string for field AllocateArgumentsModel: string too large") } - return fmt.Errorf("AllocateArgumentsModel: %w", err) + return fmt.Errorf("reading string for field AllocateArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("AllocateArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field AllocateArgumentsModel: %w", err) } switch name { @@ -118,7 +118,7 @@ func (t *AllocateArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { c, err := jr.ReadCid() if err != nil { - return fmt.Errorf("t.Cause: %w", err) + return fmt.Errorf("reading CID for field t.Cause: %w", err) } t.Cause = c @@ -126,19 +126,19 @@ func (t *AllocateArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("AllocateArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for AllocateArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("AllocateArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field AllocateArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("AllocateArgumentsModel: map too large") + return fmt.Errorf("map too large for AllocateArgumentsModel") } } } @@ -158,20 +158,20 @@ func (t *BlobModel) MarshalDagJSON(w io.Writer) error { // t.Digest (multihash.Multihash) (slice) if len("digest") > 8192 { - return fmt.Errorf("String in field \"digest\" was too long") + return fmt.Errorf("string in field \"digest\" was too long") } if err := jw.WriteString(string("digest")); err != nil { - return fmt.Errorf("\"digest\": %w", err) + return fmt.Errorf("writing string for field \"digest\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if len(t.Digest) > 2097152 { - return fmt.Errorf("Byte array in field t.Digest was too long") + return fmt.Errorf("byte array in field t.Digest was too long") } if err := jw.WriteBytes(t.Digest); err != nil { - return fmt.Errorf("t.Digest: %w", err) + return fmt.Errorf("writing bytes for field t.Digest: %w", err) } written++ @@ -183,17 +183,17 @@ func (t *BlobModel) MarshalDagJSON(w io.Writer) error { // t.Size (uint64) (uint64) if len("size") > 8192 { - return fmt.Errorf("String in field \"size\" was too long") + return fmt.Errorf("string in field \"size\" was too long") } if err := jw.WriteString(string("size")); err != nil { - return fmt.Errorf("\"size\": %w", err) + return fmt.Errorf("writing string for field \"size\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteUint64(uint64(t.Size)); err != nil { - return fmt.Errorf("t.Size: %w", err) + return fmt.Errorf("writing uint64 for field t.Size: %w", err) } written++ @@ -212,27 +212,27 @@ func (t *BlobModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("BlobModel: %w", err) + return fmt.Errorf("reading object open for BlobModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("BlobModel: %w", err) + return fmt.Errorf("peeking object close for BlobModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("BlobModel: %w", err) + return fmt.Errorf("reading object close for BlobModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("BlobModel: string too large") + return fmt.Errorf("reading string for field BlobModel: string too large") } - return fmt.Errorf("BlobModel: %w", err) + return fmt.Errorf("reading string for field BlobModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("BlobModel: %w", err) + return fmt.Errorf("reading object colon for field BlobModel: %w", err) } switch name { @@ -243,9 +243,9 @@ func (t *BlobModel) UnmarshalDagJSON(r io.Reader) (err error) { bval, err := jr.ReadBytes(2097152) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("t.Digest: byte array too large") + return fmt.Errorf("reading bytes for field t.Digest: byte array too large") } - return fmt.Errorf("t.Digest: %w", err) + return fmt.Errorf("reading bytes for field t.Digest: %w", err) } if len(bval) > 0 { t.Digest = []uint8(bval) @@ -258,7 +258,7 @@ func (t *BlobModel) UnmarshalDagJSON(r io.Reader) (err error) { nval, err := jr.ReadNumberAsUint64() if err != nil { - return fmt.Errorf("t.Size: %w", err) + return fmt.Errorf("reading uint64 for field t.Size: %w", err) } t.Size = uint64(nval) @@ -266,19 +266,19 @@ func (t *BlobModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("BlobModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for BlobModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("BlobModel: %w", err) + return fmt.Errorf("reading object close or comma for field BlobModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("BlobModel: map too large") + return fmt.Errorf("map too large for BlobModel") } } } @@ -299,16 +299,16 @@ func (t *AllocateOKModel) MarshalDagJSON(w io.Writer) error { // t.Address (datamodel.BlobAddressModel) (struct) if t.Address != nil { if len("address") > 8192 { - return fmt.Errorf("String in field \"address\" was too long") + return fmt.Errorf("string in field \"address\" was too long") } if err := jw.WriteString(string("address")); err != nil { - return fmt.Errorf("\"address\": %w", err) + return fmt.Errorf("writing string for field \"address\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Address.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Address: %w", err) + return fmt.Errorf("marshaling field t.Address: %w", err) } written++ } @@ -320,17 +320,17 @@ func (t *AllocateOKModel) MarshalDagJSON(w io.Writer) error { // t.Size (uint64) (uint64) if len("size") > 8192 { - return fmt.Errorf("String in field \"size\" was too long") + return fmt.Errorf("string in field \"size\" was too long") } if err := jw.WriteString(string("size")); err != nil { - return fmt.Errorf("\"size\": %w", err) + return fmt.Errorf("writing string for field \"size\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteUint64(uint64(t.Size)); err != nil { - return fmt.Errorf("t.Size: %w", err) + return fmt.Errorf("writing uint64 for field t.Size: %w", err) } written++ @@ -349,27 +349,27 @@ func (t *AllocateOKModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("AllocateOKModel: %w", err) + return fmt.Errorf("reading object open for AllocateOKModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("AllocateOKModel: %w", err) + return fmt.Errorf("peeking object close for AllocateOKModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("AllocateOKModel: %w", err) + return fmt.Errorf("reading object close for AllocateOKModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("AllocateOKModel: string too large") + return fmt.Errorf("reading string for field AllocateOKModel: string too large") } - return fmt.Errorf("AllocateOKModel: %w", err) + return fmt.Errorf("reading string for field AllocateOKModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("AllocateOKModel: %w", err) + return fmt.Errorf("reading object colon for field AllocateOKModel: %w", err) } switch name { @@ -379,11 +379,11 @@ func (t *AllocateOKModel) UnmarshalDagJSON(r io.Reader) (err error) { { null, err := jr.PeekNull() if err != nil { - return fmt.Errorf("t.Address: %w", err) + return fmt.Errorf("peeking null for field t.Address: %w", err) } if null { if err := jr.ReadNull(); err != nil { - return fmt.Errorf("t.Address: %w", err) + return fmt.Errorf("reading null for field t.Address: %w", err) } } else { t.Address = new(BlobAddressModel) @@ -399,7 +399,7 @@ func (t *AllocateOKModel) UnmarshalDagJSON(r io.Reader) (err error) { nval, err := jr.ReadNumberAsUint64() if err != nil { - return fmt.Errorf("t.Size: %w", err) + return fmt.Errorf("reading uint64 for field t.Size: %w", err) } t.Size = uint64(nval) @@ -407,19 +407,19 @@ func (t *AllocateOKModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("AllocateOKModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for AllocateOKModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("AllocateOKModel: %w", err) + return fmt.Errorf("reading object close or comma for field AllocateOKModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("AllocateOKModel: map too large") + return fmt.Errorf("map too large for AllocateOKModel") } } } @@ -437,19 +437,21 @@ func (t *BlobAddressModel) MarshalDagJSON(w io.Writer) error { } written := 0 - // t.Expires (capabilities.CborTime) (struct) + // t.Expires (int64) (int64) if len("expires") > 8192 { - return fmt.Errorf("String in field \"expires\" was too long") + return fmt.Errorf("string in field \"expires\" was too long") } if err := jw.WriteString(string("expires")); err != nil { - return fmt.Errorf("\"expires\": %w", err) + return fmt.Errorf("writing string for field \"expires\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } - if err := t.Expires.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Expires: %w", err) + + if err := jw.WriteInt64(int64(t.Expires)); err != nil { + return fmt.Errorf("writing int64 for field t.Expires: %w", err) } + written++ if written > 0 { if err := jw.WriteComma(); err != nil { @@ -459,10 +461,10 @@ func (t *BlobAddressModel) MarshalDagJSON(w io.Writer) error { // t.Headers (map[string]string) (map) if len("headers") > 8192 { - return fmt.Errorf("String in field \"headers\" was too long") + return fmt.Errorf("string in field \"headers\" was too long") } if err := jw.WriteString(string("headers")); err != nil { - return fmt.Errorf("\"headers\": %w", err) + return fmt.Errorf("writing string for field \"headers\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err @@ -473,7 +475,7 @@ func (t *BlobAddressModel) MarshalDagJSON(w io.Writer) error { } if err := jw.WriteObjectOpen(); err != nil { - return fmt.Errorf("t.Headers: %w", err) + return fmt.Errorf("writing object open for field t.Headers: %w", err) } keys := make([]string, 0, len(t.Headers)) @@ -484,29 +486,29 @@ func (t *BlobAddressModel) MarshalDagJSON(w io.Writer) error { for i, k := range keys { if i > 0 { if err := jw.WriteComma(); err != nil { - return fmt.Errorf("t.Headers: %w", err) + return fmt.Errorf("writing comma for field t.Headers: %w", err) } } v := t.Headers[k] if len(k) > 8192 { - return fmt.Errorf("String in field k was too long") + return fmt.Errorf("string in field k was too long") } if err := jw.WriteString(string(k)); err != nil { - return fmt.Errorf("k: %w", err) + return fmt.Errorf("writing string for field k: %w", err) } if err := jw.WriteObjectColon(); err != nil { - return fmt.Errorf("t.Headers: %w", err) + return fmt.Errorf("writing colon for field t.Headers: %w", err) } if len(v) > 8192 { - return fmt.Errorf("String in field v was too long") + return fmt.Errorf("string in field v was too long") } if err := jw.WriteString(string(v)); err != nil { - return fmt.Errorf("v: %w", err) + return fmt.Errorf("writing string for field v: %w", err) } } if err := jw.WriteObjectClose(); err != nil { - return fmt.Errorf("t.Headers: %w", err) + return fmt.Errorf("writing object close for field t.Headers: %w", err) } } @@ -519,16 +521,16 @@ func (t *BlobAddressModel) MarshalDagJSON(w io.Writer) error { // t.URL (capabilities.CborURL) (struct) if len("url") > 8192 { - return fmt.Errorf("String in field \"url\" was too long") + return fmt.Errorf("string in field \"url\" was too long") } if err := jw.WriteString(string("url")); err != nil { - return fmt.Errorf("\"url\": %w", err) + return fmt.Errorf("writing string for field \"url\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.URL.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.URL: %w", err) + return fmt.Errorf("marshaling field t.URL: %w", err) } written++ if err := jw.WriteObjectClose(); err != nil { @@ -546,52 +548,57 @@ func (t *BlobAddressModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("BlobAddressModel: %w", err) + return fmt.Errorf("reading object open for BlobAddressModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("BlobAddressModel: %w", err) + return fmt.Errorf("peeking object close for BlobAddressModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("BlobAddressModel: %w", err) + return fmt.Errorf("reading object close for BlobAddressModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("BlobAddressModel: string too large") + return fmt.Errorf("reading string for field BlobAddressModel: string too large") } - return fmt.Errorf("BlobAddressModel: %w", err) + return fmt.Errorf("reading string for field BlobAddressModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("BlobAddressModel: %w", err) + return fmt.Errorf("reading object colon for field BlobAddressModel: %w", err) } switch name { - // t.Expires (capabilities.CborTime) (struct) + // t.Expires (int64) (int64) case "expires": + { + + nval, err := jr.ReadNumberAsInt64() + if err != nil { + return fmt.Errorf("reading int64 for field t.Expires: %w", err) + } + t.Expires = int64(nval) - if err := t.Expires.UnmarshalDagJSON(jr); err != nil { - return fmt.Errorf("unmarshaling t.Expires: %w", err) } // t.Headers (map[string]string) (map) case "headers": if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("t.Headers: %w", err) + return fmt.Errorf("reading object open for field t.Headers: %w", err) } t.Headers = map[string]string{} close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("t.Headers: %w", err) + return fmt.Errorf("peeking object close for field t.Headers: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("t.Headers: %w", err) + return fmt.Errorf("reading object close for field t.Headers: %w", err) } } else { for i, l := 0, 8192; i < l; i++ { @@ -600,30 +607,30 @@ func (t *BlobAddressModel) UnmarshalDagJSON(r io.Reader) (err error) { sval, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("k: string too long") + return fmt.Errorf("reading string for field k: string too long") } - return fmt.Errorf("k: %w", err) + return fmt.Errorf("reading string for field k: %w", err) } k = string(sval) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("t.Headers: %w", err) + return fmt.Errorf("reading object colon for field t.Headers: %w", err) } var v string { sval, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("v: string too long") + return fmt.Errorf("reading string for field v: string too long") } - return fmt.Errorf("v: %w", err) + return fmt.Errorf("reading string for field v: %w", err) } v = string(sval) } t.Headers[k] = v close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("t.Headers: %w", err) + return fmt.Errorf("reading object close or comma for field t.Headers: %w", err) } if close { break @@ -641,19 +648,19 @@ func (t *BlobAddressModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("BlobAddressModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for BlobAddressModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("BlobAddressModel: %w", err) + return fmt.Errorf("reading object close or comma for field BlobAddressModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("BlobAddressModel: map too large") + return fmt.Errorf("map too large for BlobAddressModel") } } } @@ -673,16 +680,16 @@ func (t *AcceptArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Put (promise.AwaitOK) (struct) if len("_put") > 8192 { - return fmt.Errorf("String in field \"_put\" was too long") + return fmt.Errorf("string in field \"_put\" was too long") } if err := jw.WriteString(string("_put")); err != nil { - return fmt.Errorf("\"_put\": %w", err) + return fmt.Errorf("writing string for field \"_put\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Put.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Put: %w", err) + return fmt.Errorf("marshaling field t.Put: %w", err) } written++ if written > 0 { @@ -693,16 +700,16 @@ func (t *AcceptArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Blob (datamodel.BlobModel) (struct) if len("blob") > 8192 { - return fmt.Errorf("String in field \"blob\" was too long") + return fmt.Errorf("string in field \"blob\" was too long") } if err := jw.WriteString(string("blob")); err != nil { - return fmt.Errorf("\"blob\": %w", err) + return fmt.Errorf("writing string for field \"blob\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Blob.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Blob: %w", err) + return fmt.Errorf("marshaling field t.Blob: %w", err) } written++ if err := jw.WriteObjectClose(); err != nil { @@ -720,27 +727,27 @@ func (t *AcceptArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("AcceptArgumentsModel: %w", err) + return fmt.Errorf("reading object open for AcceptArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("AcceptArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for AcceptArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("AcceptArgumentsModel: %w", err) + return fmt.Errorf("reading object close for AcceptArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("AcceptArgumentsModel: string too large") + return fmt.Errorf("reading string for field AcceptArgumentsModel: string too large") } - return fmt.Errorf("AcceptArgumentsModel: %w", err) + return fmt.Errorf("reading string for field AcceptArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("AcceptArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field AcceptArgumentsModel: %w", err) } switch name { @@ -761,19 +768,19 @@ func (t *AcceptArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("AcceptArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for AcceptArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("AcceptArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field AcceptArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("AcceptArgumentsModel: map too large") + return fmt.Errorf("map too large for AcceptArgumentsModel") } } } @@ -792,17 +799,17 @@ func (t *AcceptOKModel) MarshalDagJSON(w io.Writer) error { // t.Site (cid.Cid) (struct) if len("site") > 8192 { - return fmt.Errorf("String in field \"site\" was too long") + return fmt.Errorf("string in field \"site\" was too long") } if err := jw.WriteString(string("site")); err != nil { - return fmt.Errorf("\"site\": %w", err) + return fmt.Errorf("writing string for field \"site\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteCid(t.Site); err != nil { - return fmt.Errorf("t.Site: %w", err) + return fmt.Errorf("writing CID for field t.Site: %w", err) } if err := jw.WriteObjectClose(); err != nil { @@ -820,27 +827,27 @@ func (t *AcceptOKModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("AcceptOKModel: %w", err) + return fmt.Errorf("reading object open for AcceptOKModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("AcceptOKModel: %w", err) + return fmt.Errorf("peeking object close for AcceptOKModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("AcceptOKModel: %w", err) + return fmt.Errorf("reading object close for AcceptOKModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("AcceptOKModel: string too large") + return fmt.Errorf("reading string for field AcceptOKModel: string too large") } - return fmt.Errorf("AcceptOKModel: %w", err) + return fmt.Errorf("reading string for field AcceptOKModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("AcceptOKModel: %w", err) + return fmt.Errorf("reading object colon for field AcceptOKModel: %w", err) } switch name { @@ -850,7 +857,7 @@ func (t *AcceptOKModel) UnmarshalDagJSON(r io.Reader) (err error) { c, err := jr.ReadCid() if err != nil { - return fmt.Errorf("t.Site: %w", err) + return fmt.Errorf("reading CID for field t.Site: %w", err) } t.Site = c @@ -858,19 +865,19 @@ func (t *AcceptOKModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("AcceptOKModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for AcceptOKModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("AcceptOKModel: %w", err) + return fmt.Errorf("reading object close or comma for field AcceptOKModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("AcceptOKModel: map too large") + return fmt.Errorf("map too large for AcceptOKModel") } } } @@ -889,16 +896,16 @@ func (t *AddArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Blob (datamodel.BlobModel) (struct) if len("blob") > 8192 { - return fmt.Errorf("String in field \"blob\" was too long") + return fmt.Errorf("string in field \"blob\" was too long") } if err := jw.WriteString(string("blob")); err != nil { - return fmt.Errorf("\"blob\": %w", err) + return fmt.Errorf("writing string for field \"blob\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Blob.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Blob: %w", err) + return fmt.Errorf("marshaling field t.Blob: %w", err) } if err := jw.WriteObjectClose(); err != nil { return err @@ -915,27 +922,27 @@ func (t *AddArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("AddArgumentsModel: %w", err) + return fmt.Errorf("reading object open for AddArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("AddArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for AddArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("AddArgumentsModel: %w", err) + return fmt.Errorf("reading object close for AddArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("AddArgumentsModel: string too large") + return fmt.Errorf("reading string for field AddArgumentsModel: string too large") } - return fmt.Errorf("AddArgumentsModel: %w", err) + return fmt.Errorf("reading string for field AddArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("AddArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field AddArgumentsModel: %w", err) } switch name { @@ -949,19 +956,19 @@ func (t *AddArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("AddArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for AddArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("AddArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field AddArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("AddArgumentsModel: map too large") + return fmt.Errorf("map too large for AddArgumentsModel") } } } @@ -980,16 +987,16 @@ func (t *AddOKModel) MarshalDagJSON(w io.Writer) error { // t.Site (promise.AwaitOK) (struct) if len("site") > 8192 { - return fmt.Errorf("String in field \"site\" was too long") + return fmt.Errorf("string in field \"site\" was too long") } if err := jw.WriteString(string("site")); err != nil { - return fmt.Errorf("\"site\": %w", err) + return fmt.Errorf("writing string for field \"site\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Site.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Site: %w", err) + return fmt.Errorf("marshaling field t.Site: %w", err) } if err := jw.WriteObjectClose(); err != nil { return err @@ -1006,27 +1013,27 @@ func (t *AddOKModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("AddOKModel: %w", err) + return fmt.Errorf("reading object open for AddOKModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("AddOKModel: %w", err) + return fmt.Errorf("peeking object close for AddOKModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("AddOKModel: %w", err) + return fmt.Errorf("reading object close for AddOKModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("AddOKModel: string too large") + return fmt.Errorf("reading string for field AddOKModel: string too large") } - return fmt.Errorf("AddOKModel: %w", err) + return fmt.Errorf("reading string for field AddOKModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("AddOKModel: %w", err) + return fmt.Errorf("reading object colon for field AddOKModel: %w", err) } switch name { @@ -1040,19 +1047,19 @@ func (t *AddOKModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("AddOKModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for AddOKModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("AddOKModel: %w", err) + return fmt.Errorf("reading object close or comma for field AddOKModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("AddOKModel: map too large") + return fmt.Errorf("map too large for AddOKModel") } } } @@ -1071,20 +1078,20 @@ func (t *RemoveArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Digest (multihash.Multihash) (slice) if len("digest") > 8192 { - return fmt.Errorf("String in field \"digest\" was too long") + return fmt.Errorf("string in field \"digest\" was too long") } if err := jw.WriteString(string("digest")); err != nil { - return fmt.Errorf("\"digest\": %w", err) + return fmt.Errorf("writing string for field \"digest\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if len(t.Digest) > 2097152 { - return fmt.Errorf("Byte array in field t.Digest was too long") + return fmt.Errorf("byte array in field t.Digest was too long") } if err := jw.WriteBytes(t.Digest); err != nil { - return fmt.Errorf("t.Digest: %w", err) + return fmt.Errorf("writing bytes for field t.Digest: %w", err) } if err := jw.WriteObjectClose(); err != nil { @@ -1102,27 +1109,27 @@ func (t *RemoveArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("RemoveArgumentsModel: %w", err) + return fmt.Errorf("reading object open for RemoveArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("RemoveArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for RemoveArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("RemoveArgumentsModel: %w", err) + return fmt.Errorf("reading object close for RemoveArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("RemoveArgumentsModel: string too large") + return fmt.Errorf("reading string for field RemoveArgumentsModel: string too large") } - return fmt.Errorf("RemoveArgumentsModel: %w", err) + return fmt.Errorf("reading string for field RemoveArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("RemoveArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field RemoveArgumentsModel: %w", err) } switch name { @@ -1133,9 +1140,9 @@ func (t *RemoveArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { bval, err := jr.ReadBytes(2097152) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("t.Digest: byte array too large") + return fmt.Errorf("reading bytes for field t.Digest: byte array too large") } - return fmt.Errorf("t.Digest: %w", err) + return fmt.Errorf("reading bytes for field t.Digest: %w", err) } if len(bval) > 0 { t.Digest = []uint8(bval) @@ -1145,19 +1152,19 @@ func (t *RemoveArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("RemoveArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for RemoveArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("RemoveArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field RemoveArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("RemoveArgumentsModel: map too large") + return fmt.Errorf("map too large for RemoveArgumentsModel") } } } @@ -1177,16 +1184,16 @@ func (t *ReplicateArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Blob (datamodel.BlobModel) (struct) if len("blob") > 8192 { - return fmt.Errorf("String in field \"blob\" was too long") + return fmt.Errorf("string in field \"blob\" was too long") } if err := jw.WriteString(string("blob")); err != nil { - return fmt.Errorf("\"blob\": %w", err) + return fmt.Errorf("writing string for field \"blob\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Blob.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Blob: %w", err) + return fmt.Errorf("marshaling field t.Blob: %w", err) } written++ if written > 0 { @@ -1197,17 +1204,17 @@ func (t *ReplicateArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Replicas (uint64) (uint64) if len("replicas") > 8192 { - return fmt.Errorf("String in field \"replicas\" was too long") + return fmt.Errorf("string in field \"replicas\" was too long") } if err := jw.WriteString(string("replicas")); err != nil { - return fmt.Errorf("\"replicas\": %w", err) + return fmt.Errorf("writing string for field \"replicas\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteUint64(uint64(t.Replicas)); err != nil { - return fmt.Errorf("t.Replicas: %w", err) + return fmt.Errorf("writing uint64 for field t.Replicas: %w", err) } written++ @@ -1219,17 +1226,17 @@ func (t *ReplicateArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Site (cid.Cid) (struct) if len("site") > 8192 { - return fmt.Errorf("String in field \"site\" was too long") + return fmt.Errorf("string in field \"site\" was too long") } if err := jw.WriteString(string("site")); err != nil { - return fmt.Errorf("\"site\": %w", err) + return fmt.Errorf("writing string for field \"site\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteCid(t.Site); err != nil { - return fmt.Errorf("t.Site: %w", err) + return fmt.Errorf("writing CID for field t.Site: %w", err) } written++ @@ -1248,27 +1255,27 @@ func (t *ReplicateArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("ReplicateArgumentsModel: %w", err) + return fmt.Errorf("reading object open for ReplicateArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("ReplicateArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for ReplicateArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("ReplicateArgumentsModel: %w", err) + return fmt.Errorf("reading object close for ReplicateArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("ReplicateArgumentsModel: string too large") + return fmt.Errorf("reading string for field ReplicateArgumentsModel: string too large") } - return fmt.Errorf("ReplicateArgumentsModel: %w", err) + return fmt.Errorf("reading string for field ReplicateArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("ReplicateArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field ReplicateArgumentsModel: %w", err) } switch name { @@ -1285,7 +1292,7 @@ func (t *ReplicateArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { nval, err := jr.ReadNumberAsUint64() if err != nil { - return fmt.Errorf("t.Replicas: %w", err) + return fmt.Errorf("reading uint64 for field t.Replicas: %w", err) } t.Replicas = uint64(nval) @@ -1297,7 +1304,7 @@ func (t *ReplicateArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { c, err := jr.ReadCid() if err != nil { - return fmt.Errorf("t.Site: %w", err) + return fmt.Errorf("reading CID for field t.Site: %w", err) } t.Site = c @@ -1305,19 +1312,19 @@ func (t *ReplicateArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("ReplicateArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for ReplicateArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("ReplicateArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field ReplicateArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("ReplicateArgumentsModel: map too large") + return fmt.Errorf("map too large for ReplicateArgumentsModel") } } } @@ -1336,33 +1343,33 @@ func (t *ReplicateOKModel) MarshalDagJSON(w io.Writer) error { // t.Site ([]promise.AwaitOK) (slice) if len("site") > 8192 { - return fmt.Errorf("String in field \"site\" was too long") + return fmt.Errorf("string in field \"site\" was too long") } if err := jw.WriteString(string("site")); err != nil { - return fmt.Errorf("\"site\": %w", err) + return fmt.Errorf("writing string for field \"site\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if len(t.Site) > 8192 { - return fmt.Errorf("Slice value in field t.Site was too long") + return fmt.Errorf("slice value in field t.Site was too long") } if err := jw.WriteArrayOpen(); err != nil { - return fmt.Errorf("t.Site: %w", err) + return fmt.Errorf("writing array open for field t.Site: %w", err) } for i, v := range t.Site { if i > 0 { if err := jw.WriteComma(); err != nil { - return fmt.Errorf("t.Site: %w", err) + return fmt.Errorf("writing comma for field t.Site: %w", err) } } if err := v.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("v: %w", err) + return fmt.Errorf("marshaling field v: %w", err) } } if err := jw.WriteArrayClose(); err != nil { - return fmt.Errorf("t.Site: %w", err) + return fmt.Errorf("writing array close for field t.Site: %w", err) } if err := jw.WriteObjectClose(); err != nil { @@ -1380,27 +1387,27 @@ func (t *ReplicateOKModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("ReplicateOKModel: %w", err) + return fmt.Errorf("reading object open for ReplicateOKModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("ReplicateOKModel: %w", err) + return fmt.Errorf("peeking object close for ReplicateOKModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("ReplicateOKModel: %w", err) + return fmt.Errorf("reading object close for ReplicateOKModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("ReplicateOKModel: string too large") + return fmt.Errorf("reading string for field ReplicateOKModel: string too large") } - return fmt.Errorf("ReplicateOKModel: %w", err) + return fmt.Errorf("reading string for field ReplicateOKModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("ReplicateOKModel: %w", err) + return fmt.Errorf("reading object colon for field ReplicateOKModel: %w", err) } switch name { @@ -1409,16 +1416,16 @@ func (t *ReplicateOKModel) UnmarshalDagJSON(r io.Reader) (err error) { { if err := jr.ReadArrayOpen(); err != nil { - return fmt.Errorf("t.Site: %w", err) + return fmt.Errorf("reading array open for field t.Site: %w", err) } close, err := jr.PeekArrayClose() if err != nil { - return fmt.Errorf("t.Site: %w", err) + return fmt.Errorf("peeking array close for field t.Site: %w", err) } if close { if err := jr.ReadArrayClose(); err != nil { - return fmt.Errorf("t.Site: %w", err) + return fmt.Errorf("reading array close for field t.Site: %w", err) } } else { @@ -1433,13 +1440,13 @@ func (t *ReplicateOKModel) UnmarshalDagJSON(r io.Reader) (err error) { close, err := jr.ReadArrayCloseOrComma() if err != nil { - return fmt.Errorf("t.Site: %w", err) + return fmt.Errorf("reading array close or comma for field t.Site: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("t.Site: slice too large") + return fmt.Errorf("reading array for field t.Site: slice too large") } } } @@ -1448,19 +1455,528 @@ func (t *ReplicateOKModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("ReplicateOKModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for ReplicateOKModel: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field ReplicateOKModel: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for ReplicateOKModel") + } + } + } + + return nil +} +func (t *ListArgumentsModel) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.Cursor (string) (string) + if t.Cursor != nil { + if len("cursor") > 8192 { + return fmt.Errorf("string in field \"cursor\" was too long") + } + if err := jw.WriteString(string("cursor")); err != nil { + return fmt.Errorf("writing string for field \"cursor\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if t.Cursor == nil { + if err := jw.WriteNull(); err != nil { + return fmt.Errorf("writing null for field t.Cursor: %w", err) + } + } else { + if len(*t.Cursor) > 8192 { + return fmt.Errorf("string in field t.Cursor was too long") + } + if err := jw.WriteString(string(*t.Cursor)); err != nil { + return fmt.Errorf("writing string for field t.Cursor: %w", err) + } + } + written++ + } + if t.Size != nil { + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + } + + // t.Size (int64) (int64) + if t.Size != nil { + if len("size") > 8192 { + return fmt.Errorf("string in field \"size\" was too long") + } + if err := jw.WriteString(string("size")); err != nil { + return fmt.Errorf("writing string for field \"size\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if t.Size == nil { + if err := jw.WriteNull(); err != nil { + return fmt.Errorf("writing null for field t.Size: %w", err) + } + } else { + if err := jw.WriteInt64(int64(*t.Size)); err != nil { + return fmt.Errorf("writing int64 for field t.Size: %w", err) + } + } + + written++ + } + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *ListArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { + *t = ListArgumentsModel{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for ListArgumentsModel: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for ListArgumentsModel: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for ListArgumentsModel: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field ListArgumentsModel: string too large") + } + return fmt.Errorf("reading string for field ListArgumentsModel: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field ListArgumentsModel: %w", err) + } + switch name { + + // t.Cursor (string) (string) + case "cursor": + { + sval, err := jr.ReadStringOrNull(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string or null for field t.Cursor: string too long") + } + return fmt.Errorf("reading string or null for field t.Cursor: %w", err) + } + if sval != nil { + t.Cursor = (*string)(sval) + } + } + + // t.Size (int64) (int64) + case "size": + { + + nval, err := jr.ReadNumberAsInt64OrNull() + if err != nil { + return fmt.Errorf("reading int64 or null for field t.Size: %w", err) + } + if nval != nil { + typed := int64(*nval) + t.Size = &typed + } + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for ListArgumentsModel: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field ListArgumentsModel: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for ListArgumentsModel") + } + } + } + + return nil +} +func (t *ListOKModel) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.Cursor (string) (string) + if t.Cursor != nil { + if len("cursor") > 8192 { + return fmt.Errorf("string in field \"cursor\" was too long") + } + if err := jw.WriteString(string("cursor")); err != nil { + return fmt.Errorf("writing string for field \"cursor\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if t.Cursor == nil { + if err := jw.WriteNull(); err != nil { + return fmt.Errorf("writing null for field t.Cursor: %w", err) + } + } else { + if len(*t.Cursor) > 8192 { + return fmt.Errorf("string in field t.Cursor was too long") + } + if err := jw.WriteString(string(*t.Cursor)); err != nil { + return fmt.Errorf("writing string for field t.Cursor: %w", err) + } + } + written++ + } + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Results ([]datamodel.ListBlobItem) (slice) + if len("results") > 8192 { + return fmt.Errorf("string in field \"results\" was too long") + } + if err := jw.WriteString(string("results")); err != nil { + return fmt.Errorf("writing string for field \"results\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Results) > 8192 { + return fmt.Errorf("slice value in field t.Results was too long") + } + + if err := jw.WriteArrayOpen(); err != nil { + return fmt.Errorf("writing array open for field t.Results: %w", err) + } + for i, v := range t.Results { + if i > 0 { + if err := jw.WriteComma(); err != nil { + return fmt.Errorf("writing comma for field t.Results: %w", err) + } + } + if err := v.MarshalDagJSON(jw); err != nil { + return fmt.Errorf("marshaling field v: %w", err) + } + } + if err := jw.WriteArrayClose(); err != nil { + return fmt.Errorf("writing array close for field t.Results: %w", err) + } + + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Size (int64) (int64) + if len("size") > 8192 { + return fmt.Errorf("string in field \"size\" was too long") + } + if err := jw.WriteString(string("size")); err != nil { + return fmt.Errorf("writing string for field \"size\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if err := jw.WriteInt64(int64(t.Size)); err != nil { + return fmt.Errorf("writing int64 for field t.Size: %w", err) + } + + written++ + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *ListOKModel) UnmarshalDagJSON(r io.Reader) (err error) { + *t = ListOKModel{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for ListOKModel: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for ListOKModel: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for ListOKModel: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field ListOKModel: string too large") + } + return fmt.Errorf("reading string for field ListOKModel: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field ListOKModel: %w", err) + } + switch name { + + // t.Cursor (string) (string) + case "cursor": + { + sval, err := jr.ReadStringOrNull(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string or null for field t.Cursor: string too long") + } + return fmt.Errorf("reading string or null for field t.Cursor: %w", err) + } + if sval != nil { + t.Cursor = (*string)(sval) + } + } + + // t.Results ([]datamodel.ListBlobItem) (slice) + case "results": + { + + if err := jr.ReadArrayOpen(); err != nil { + return fmt.Errorf("reading array open for field t.Results: %w", err) + } + + close, err := jr.PeekArrayClose() + if err != nil { + return fmt.Errorf("peeking array close for field t.Results: %w", err) + } + if close { + if err := jr.ReadArrayClose(); err != nil { + return fmt.Errorf("reading array close for field t.Results: %w", err) + } + + } else { + for i := 0; i < 8192; i++ { + item := make([]ListBlobItem, 1) + + if err := item[0].UnmarshalDagJSON(jr); err != nil { + return fmt.Errorf("unmarshaling item[0]: %w", err) + } + + t.Results = append(t.Results, item[0]) + + close, err := jr.ReadArrayCloseOrComma() + if err != nil { + return fmt.Errorf("reading array close or comma for field t.Results: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("reading array for field t.Results: slice too large") + } + } + } + + } + + // t.Size (int64) (int64) + case "size": + { + + nval, err := jr.ReadNumberAsInt64() + if err != nil { + return fmt.Errorf("reading int64 for field t.Size: %w", err) + } + t.Size = int64(nval) + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for ListOKModel: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field ListOKModel: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for ListOKModel") + } + } + } + + return nil +} +func (t *ListBlobItem) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.Blob (datamodel.BlobModel) (struct) + if len("blob") > 8192 { + return fmt.Errorf("string in field \"blob\" was too long") + } + if err := jw.WriteString(string("blob")); err != nil { + return fmt.Errorf("writing string for field \"blob\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if err := t.Blob.MarshalDagJSON(jw); err != nil { + return fmt.Errorf("marshaling field t.Blob: %w", err) + } + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.InsertedAt (int64) (int64) + if len("insertedAt") > 8192 { + return fmt.Errorf("string in field \"insertedAt\" was too long") + } + if err := jw.WriteString(string("insertedAt")); err != nil { + return fmt.Errorf("writing string for field \"insertedAt\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if err := jw.WriteInt64(int64(t.InsertedAt)); err != nil { + return fmt.Errorf("writing int64 for field t.InsertedAt: %w", err) + } + + written++ + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *ListBlobItem) UnmarshalDagJSON(r io.Reader) (err error) { + *t = ListBlobItem{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for ListBlobItem: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for ListBlobItem: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for ListBlobItem: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field ListBlobItem: string too large") + } + return fmt.Errorf("reading string for field ListBlobItem: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field ListBlobItem: %w", err) + } + switch name { + + // t.Blob (datamodel.BlobModel) (struct) + case "blob": + + if err := t.Blob.UnmarshalDagJSON(jr); err != nil { + return fmt.Errorf("unmarshaling t.Blob: %w", err) + } + + // t.InsertedAt (int64) (int64) + case "insertedAt": + { + + nval, err := jr.ReadNumberAsInt64() + if err != nil { + return fmt.Errorf("reading int64 for field t.InsertedAt: %w", err) + } + t.InsertedAt = int64(nval) + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for ListBlobItem: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("ReplicateOKModel: %w", err) + return fmt.Errorf("reading object close or comma for field ListBlobItem: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("ReplicateOKModel: map too large") + return fmt.Errorf("map too large for ListBlobItem") } } } diff --git a/capabilities/blob/datamodel/list.go b/capabilities/blob/datamodel/list.go new file mode 100644 index 0000000..052ae86 --- /dev/null +++ b/capabilities/blob/datamodel/list.go @@ -0,0 +1,17 @@ +package datamodel + +type ListArgumentsModel struct { + Cursor *string `cborgen:"cursor,omitempty" dagjsongen:"cursor,omitempty"` + Size *int64 `cborgen:"size,omitempty" dagjsongen:"size,omitempty"` +} + +type ListOKModel struct { + Cursor *string `cborgen:"cursor,omitempty" dagjsongen:"cursor,omitempty"` + Size int64 `cborgen:"size" dagjsongen:"size"` + Results []ListBlobItem `cborgen:"results" dagjsongen:"results"` +} + +type ListBlobItem struct { + Blob BlobModel `cborgen:"blob" dagjsongen:"blob"` + InsertedAt int64 `cborgen:"insertedAt" dagjsongen:"insertedAt"` +} diff --git a/capabilities/blob/list.go b/capabilities/blob/list.go new file mode 100644 index 0000000..06e0fb8 --- /dev/null +++ b/capabilities/blob/list.go @@ -0,0 +1,16 @@ +package blob + +import ( + bdm "github.com/fil-forge/libforge/capabilities/blob/datamodel" + "github.com/fil-forge/ucantone/validator/bindcap" +) + +const ListCommand = "/blob/list" + +type ( + ListArguments = bdm.ListArgumentsModel + ListOK = bdm.ListOKModel + ListBlobItem = bdm.ListBlobItem +) + +var List, _ = bindcap.New[*ListArguments](ListCommand) diff --git a/capabilities/cbor_time.go b/capabilities/cbor_time.go deleted file mode 100644 index c955562..0000000 --- a/capabilities/cbor_time.go +++ /dev/null @@ -1,71 +0,0 @@ -package capabilities - -import ( - "encoding/json" - "io" - "time" - - jsg "github.com/alanshaw/dag-json-gen" - cbg "github.com/whyrusleeping/cbor-gen" -) - -type CborTime time.Time - -func (ct CborTime) MarshalCBOR(w io.Writer) error { - nsecs := ct.Time().UnixNano() - - cbi := cbg.CborInt(nsecs) - - return cbi.MarshalCBOR(w) -} - -func (ct *CborTime) UnmarshalCBOR(r io.Reader) error { - var cbi cbg.CborInt - if err := cbi.UnmarshalCBOR(r); err != nil { - return err - } - - t := time.Unix(0, int64(cbi)) - - *ct = (CborTime)(t) - return nil -} - -func (ct CborTime) Time() time.Time { - return (time.Time)(ct) -} - -func (ct CborTime) MarshalDagJSON(w io.Writer) error { - nsecs := ct.Time().UnixNano() - buf, err := json.Marshal(nsecs) - if err != nil { - return err - } - _, err = w.Write(buf) - return err -} - -func (ct *CborTime) UnmarshalDagJSON(r io.Reader) error { - var nsecs int64 - jr := jsg.NewDagJsonReader(r) - nsecs, err := jr.ReadNumberAsInt64() - if err != nil { - return err - } - t := time.Unix(0, nsecs) - *ct = (CborTime)(t) - return nil -} - -func (ct CborTime) MarshalJSON() ([]byte, error) { - return ct.Time().MarshalJSON() -} - -func (ct *CborTime) UnmarshalJSON(b []byte) error { - var t time.Time - if err := t.UnmarshalJSON(b); err != nil { - return err - } - *(*time.Time)(ct) = t - return nil -} diff --git a/capabilities/claim/datamodel/json_gen.go b/capabilities/claim/datamodel/json_gen.go index 706886c..4ae0ce4 100644 --- a/capabilities/claim/datamodel/json_gen.go +++ b/capabilities/claim/datamodel/json_gen.go @@ -31,17 +31,17 @@ func (t *CacheArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Claim (cid.Cid) (struct) if len("claim") > 8192 { - return fmt.Errorf("String in field \"claim\" was too long") + return fmt.Errorf("string in field \"claim\" was too long") } if err := jw.WriteString(string("claim")); err != nil { - return fmt.Errorf("\"claim\": %w", err) + return fmt.Errorf("writing string for field \"claim\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteCid(t.Claim); err != nil { - return fmt.Errorf("t.Claim: %w", err) + return fmt.Errorf("writing CID for field t.Claim: %w", err) } written++ @@ -53,16 +53,16 @@ func (t *CacheArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Provider (datamodel.ProviderModel) (struct) if len("provider") > 8192 { - return fmt.Errorf("String in field \"provider\" was too long") + return fmt.Errorf("string in field \"provider\" was too long") } if err := jw.WriteString(string("provider")); err != nil { - return fmt.Errorf("\"provider\": %w", err) + return fmt.Errorf("writing string for field \"provider\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Provider.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Provider: %w", err) + return fmt.Errorf("marshaling field t.Provider: %w", err) } written++ if err := jw.WriteObjectClose(); err != nil { @@ -80,27 +80,27 @@ func (t *CacheArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("CacheArgumentsModel: %w", err) + return fmt.Errorf("reading object open for CacheArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("CacheArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for CacheArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("CacheArgumentsModel: %w", err) + return fmt.Errorf("reading object close for CacheArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("CacheArgumentsModel: string too large") + return fmt.Errorf("reading string for field CacheArgumentsModel: string too large") } - return fmt.Errorf("CacheArgumentsModel: %w", err) + return fmt.Errorf("reading string for field CacheArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("CacheArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field CacheArgumentsModel: %w", err) } switch name { @@ -110,7 +110,7 @@ func (t *CacheArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { c, err := jr.ReadCid() if err != nil { - return fmt.Errorf("t.Claim: %w", err) + return fmt.Errorf("reading CID for field t.Claim: %w", err) } t.Claim = c @@ -126,19 +126,19 @@ func (t *CacheArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("CacheArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for CacheArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("CacheArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field CacheArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("CacheArgumentsModel: map too large") + return fmt.Errorf("map too large for CacheArgumentsModel") } } } @@ -157,38 +157,38 @@ func (t *ProviderModel) MarshalDagJSON(w io.Writer) error { // t.Addresses ([][]uint8) (slice) if len("addresses") > 8192 { - return fmt.Errorf("String in field \"addresses\" was too long") + return fmt.Errorf("string in field \"addresses\" was too long") } if err := jw.WriteString(string("addresses")); err != nil { - return fmt.Errorf("\"addresses\": %w", err) + return fmt.Errorf("writing string for field \"addresses\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if len(t.Addresses) > 8192 { - return fmt.Errorf("Slice value in field t.Addresses was too long") + return fmt.Errorf("slice value in field t.Addresses was too long") } if err := jw.WriteArrayOpen(); err != nil { - return fmt.Errorf("t.Addresses: %w", err) + return fmt.Errorf("writing array open for field t.Addresses: %w", err) } for i, v := range t.Addresses { if i > 0 { if err := jw.WriteComma(); err != nil { - return fmt.Errorf("t.Addresses: %w", err) + return fmt.Errorf("writing comma for field t.Addresses: %w", err) } } if len(v) > 2097152 { - return fmt.Errorf("Byte array in field v was too long") + return fmt.Errorf("byte array in field v was too long") } if err := jw.WriteBytes(v); err != nil { - return fmt.Errorf("v: %w", err) + return fmt.Errorf("writing bytes for field v: %w", err) } } if err := jw.WriteArrayClose(); err != nil { - return fmt.Errorf("t.Addresses: %w", err) + return fmt.Errorf("writing array close for field t.Addresses: %w", err) } if err := jw.WriteObjectClose(); err != nil { @@ -206,27 +206,27 @@ func (t *ProviderModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("ProviderModel: %w", err) + return fmt.Errorf("reading object open for ProviderModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("ProviderModel: %w", err) + return fmt.Errorf("peeking object close for ProviderModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("ProviderModel: %w", err) + return fmt.Errorf("reading object close for ProviderModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("ProviderModel: string too large") + return fmt.Errorf("reading string for field ProviderModel: string too large") } - return fmt.Errorf("ProviderModel: %w", err) + return fmt.Errorf("reading string for field ProviderModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("ProviderModel: %w", err) + return fmt.Errorf("reading object colon for field ProviderModel: %w", err) } switch name { @@ -235,16 +235,16 @@ func (t *ProviderModel) UnmarshalDagJSON(r io.Reader) (err error) { { if err := jr.ReadArrayOpen(); err != nil { - return fmt.Errorf("t.Addresses: %w", err) + return fmt.Errorf("reading array open for field t.Addresses: %w", err) } close, err := jr.PeekArrayClose() if err != nil { - return fmt.Errorf("t.Addresses: %w", err) + return fmt.Errorf("peeking array close for field t.Addresses: %w", err) } if close { if err := jr.ReadArrayClose(); err != nil { - return fmt.Errorf("t.Addresses: %w", err) + return fmt.Errorf("reading array close for field t.Addresses: %w", err) } } else { @@ -255,9 +255,9 @@ func (t *ProviderModel) UnmarshalDagJSON(r io.Reader) (err error) { bval, err := jr.ReadBytes(2097152) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("item[0]: byte array too large") + return fmt.Errorf("reading bytes for field item[0]: byte array too large") } - return fmt.Errorf("item[0]: %w", err) + return fmt.Errorf("reading bytes for field item[0]: %w", err) } if len(bval) > 0 { item[0] = []uint8(bval) @@ -268,13 +268,13 @@ func (t *ProviderModel) UnmarshalDagJSON(r io.Reader) (err error) { close, err := jr.ReadArrayCloseOrComma() if err != nil { - return fmt.Errorf("t.Addresses: %w", err) + return fmt.Errorf("reading array close or comma for field t.Addresses: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("t.Addresses: slice too large") + return fmt.Errorf("reading array for field t.Addresses: slice too large") } } } @@ -283,19 +283,19 @@ func (t *ProviderModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("ProviderModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for ProviderModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("ProviderModel: %w", err) + return fmt.Errorf("reading object close or comma for field ProviderModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("ProviderModel: map too large") + return fmt.Errorf("map too large for ProviderModel") } } } diff --git a/capabilities/content/datamodel/json_gen.maps.go b/capabilities/content/datamodel/json_gen.maps.go index db8f4e4..428d277 100644 --- a/capabilities/content/datamodel/json_gen.maps.go +++ b/capabilities/content/datamodel/json_gen.maps.go @@ -30,20 +30,20 @@ func (t *BlobModel) MarshalDagJSON(w io.Writer) error { // t.Digest (multihash.Multihash) (slice) if len("digest") > 8192 { - return fmt.Errorf("String in field \"digest\" was too long") + return fmt.Errorf("string in field \"digest\" was too long") } if err := jw.WriteString(string("digest")); err != nil { - return fmt.Errorf("\"digest\": %w", err) + return fmt.Errorf("writing string for field \"digest\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if len(t.Digest) > 2097152 { - return fmt.Errorf("Byte array in field t.Digest was too long") + return fmt.Errorf("byte array in field t.Digest was too long") } if err := jw.WriteBytes(t.Digest); err != nil { - return fmt.Errorf("t.Digest: %w", err) + return fmt.Errorf("writing bytes for field t.Digest: %w", err) } if err := jw.WriteObjectClose(); err != nil { @@ -61,27 +61,27 @@ func (t *BlobModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("BlobModel: %w", err) + return fmt.Errorf("reading object open for BlobModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("BlobModel: %w", err) + return fmt.Errorf("peeking object close for BlobModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("BlobModel: %w", err) + return fmt.Errorf("reading object close for BlobModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("BlobModel: string too large") + return fmt.Errorf("reading string for field BlobModel: string too large") } - return fmt.Errorf("BlobModel: %w", err) + return fmt.Errorf("reading string for field BlobModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("BlobModel: %w", err) + return fmt.Errorf("reading object colon for field BlobModel: %w", err) } switch name { @@ -92,9 +92,9 @@ func (t *BlobModel) UnmarshalDagJSON(r io.Reader) (err error) { bval, err := jr.ReadBytes(2097152) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("t.Digest: byte array too large") + return fmt.Errorf("reading bytes for field t.Digest: byte array too large") } - return fmt.Errorf("t.Digest: %w", err) + return fmt.Errorf("reading bytes for field t.Digest: %w", err) } if len(bval) > 0 { t.Digest = []uint8(bval) @@ -104,19 +104,19 @@ func (t *BlobModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("BlobModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for BlobModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("BlobModel: %w", err) + return fmt.Errorf("reading object close or comma for field BlobModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("BlobModel: map too large") + return fmt.Errorf("map too large for BlobModel") } } } @@ -136,16 +136,16 @@ func (t *RetrieveArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Blob (datamodel.BlobModel) (struct) if len("blob") > 8192 { - return fmt.Errorf("String in field \"blob\" was too long") + return fmt.Errorf("string in field \"blob\" was too long") } if err := jw.WriteString(string("blob")); err != nil { - return fmt.Errorf("\"blob\": %w", err) + return fmt.Errorf("writing string for field \"blob\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Blob.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Blob: %w", err) + return fmt.Errorf("marshaling field t.Blob: %w", err) } written++ if written > 0 { @@ -156,16 +156,16 @@ func (t *RetrieveArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Range (datamodel.RangeModel) (struct) if len("range") > 8192 { - return fmt.Errorf("String in field \"range\" was too long") + return fmt.Errorf("string in field \"range\" was too long") } if err := jw.WriteString(string("range")); err != nil { - return fmt.Errorf("\"range\": %w", err) + return fmt.Errorf("writing string for field \"range\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Range.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Range: %w", err) + return fmt.Errorf("marshaling field t.Range: %w", err) } written++ if err := jw.WriteObjectClose(); err != nil { @@ -183,27 +183,27 @@ func (t *RetrieveArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("RetrieveArgumentsModel: %w", err) + return fmt.Errorf("reading object open for RetrieveArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("RetrieveArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for RetrieveArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("RetrieveArgumentsModel: %w", err) + return fmt.Errorf("reading object close for RetrieveArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("RetrieveArgumentsModel: string too large") + return fmt.Errorf("reading string for field RetrieveArgumentsModel: string too large") } - return fmt.Errorf("RetrieveArgumentsModel: %w", err) + return fmt.Errorf("reading string for field RetrieveArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("RetrieveArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field RetrieveArgumentsModel: %w", err) } switch name { @@ -224,19 +224,19 @@ func (t *RetrieveArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("RetrieveArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for RetrieveArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("RetrieveArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field RetrieveArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("RetrieveArgumentsModel: map too large") + return fmt.Errorf("map too large for RetrieveArgumentsModel") } } } diff --git a/capabilities/content/datamodel/json_gen.tuples.go b/capabilities/content/datamodel/json_gen.tuples.go index ed0309b..2cc1857 100644 --- a/capabilities/content/datamodel/json_gen.tuples.go +++ b/capabilities/content/datamodel/json_gen.tuples.go @@ -25,27 +25,27 @@ func (t *RangeModel) MarshalDagJSON(w io.Writer) error { return err } if err := jw.WriteArrayOpen(); err != nil { - return fmt.Errorf("RangeModel: %w", err) + return fmt.Errorf("writing array open for field RangeModel: %w", err) } // t.Start (uint64) (uint64) if err := jw.WriteUint64(uint64(t.Start)); err != nil { - return fmt.Errorf("t.Start: %w", err) + return fmt.Errorf("writing uint64 for field t.Start: %w", err) } if err := jw.WriteComma(); err != nil { - return fmt.Errorf("End: %w", err) + return fmt.Errorf("writing comma for field End: %w", err) } // t.End (uint64) (uint64) if err := jw.WriteUint64(uint64(t.End)); err != nil { - return fmt.Errorf("t.End: %w", err) + return fmt.Errorf("writing uint64 for field t.End: %w", err) } if err := jw.WriteArrayClose(); err != nil { - return fmt.Errorf("RangeModel: %w", err) + return fmt.Errorf("writing array close for field RangeModel: %w", err) } return nil } @@ -60,15 +60,15 @@ func (t *RangeModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadArrayOpen(); err != nil { - return fmt.Errorf("RangeModel: %w", err) + return fmt.Errorf("reading array open for field RangeModel: %w", err) } close, err := jr.PeekArrayClose() if err != nil { - return fmt.Errorf("RangeModel: %w", err) + return fmt.Errorf("peeking array close for field RangeModel: %w", err) } if close { if err := jr.ReadArrayClose(); err != nil { - return fmt.Errorf("RangeModel: %w", err) + return fmt.Errorf("reading array close for field RangeModel: %w", err) } } else { @@ -78,7 +78,7 @@ func (t *RangeModel) UnmarshalDagJSON(r io.Reader) (err error) { nval, err := jr.ReadNumberAsUint64() if err != nil { - return fmt.Errorf("t.Start: %w", err) + return fmt.Errorf("reading uint64 for field t.Start: %w", err) } t.Start = uint64(nval) @@ -86,7 +86,7 @@ func (t *RangeModel) UnmarshalDagJSON(r io.Reader) (err error) { { close, err := jr.ReadArrayCloseOrComma() if err != nil { - return fmt.Errorf("RangeModel: %w", err) + return fmt.Errorf("reading array close or comma for field RangeModel: %w", err) } if close { return fmt.Errorf("json input has too few fields 1 < 2") @@ -99,13 +99,13 @@ func (t *RangeModel) UnmarshalDagJSON(r io.Reader) (err error) { nval, err := jr.ReadNumberAsUint64() if err != nil { - return fmt.Errorf("t.End: %w", err) + return fmt.Errorf("reading uint64 for field t.End: %w", err) } t.End = uint64(nval) } if err := jr.ReadArrayClose(); err != nil { - return fmt.Errorf("RangeModel: %w", err) + return fmt.Errorf("reading array close for field RangeModel: %w", err) } } return nil diff --git a/capabilities/datamodel/json_gen.go b/capabilities/datamodel/json_gen.go index bf88c5d..ffbaf2f 100644 --- a/capabilities/datamodel/json_gen.go +++ b/capabilities/datamodel/json_gen.go @@ -42,45 +42,45 @@ func (t *UnitModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("UnitModel: %w", err) + return fmt.Errorf("reading object open for UnitModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("UnitModel: %w", err) + return fmt.Errorf("peeking object close for UnitModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("UnitModel: %w", err) + return fmt.Errorf("reading object close for UnitModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("UnitModel: string too large") + return fmt.Errorf("reading string for field UnitModel: string too large") } - return fmt.Errorf("UnitModel: %w", err) + return fmt.Errorf("reading string for field UnitModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("UnitModel: %w", err) + return fmt.Errorf("reading object colon for field UnitModel: %w", err) } switch name { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("UnitModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for UnitModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("UnitModel: %w", err) + return fmt.Errorf("reading object close or comma for field UnitModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("UnitModel: map too large") + return fmt.Errorf("map too large for UnitModel") } } } diff --git a/capabilities/debug/datamodel/json_gen.go b/capabilities/debug/datamodel/json_gen.go index b997700..4bdb05e 100644 --- a/capabilities/debug/datamodel/json_gen.go +++ b/capabilities/debug/datamodel/json_gen.go @@ -30,19 +30,19 @@ func (t *EchoArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Message (string) (string) if len("message") > 8192 { - return fmt.Errorf("String in field \"message\" was too long") + return fmt.Errorf("string in field \"message\" was too long") } if err := jw.WriteString(string("message")); err != nil { - return fmt.Errorf("\"message\": %w", err) + return fmt.Errorf("writing string for field \"message\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if len(t.Message) > 8192 { - return fmt.Errorf("String in field t.Message was too long") + return fmt.Errorf("string in field t.Message was too long") } if err := jw.WriteString(string(t.Message)); err != nil { - return fmt.Errorf("t.Message: %w", err) + return fmt.Errorf("writing string for field t.Message: %w", err) } if err := jw.WriteObjectClose(); err != nil { return err @@ -59,27 +59,27 @@ func (t *EchoArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("EchoArgumentsModel: %w", err) + return fmt.Errorf("reading object open for EchoArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("EchoArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for EchoArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("EchoArgumentsModel: %w", err) + return fmt.Errorf("reading object close for EchoArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("EchoArgumentsModel: string too large") + return fmt.Errorf("reading string for field EchoArgumentsModel: string too large") } - return fmt.Errorf("EchoArgumentsModel: %w", err) + return fmt.Errorf("reading string for field EchoArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("EchoArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field EchoArgumentsModel: %w", err) } switch name { @@ -89,28 +89,28 @@ func (t *EchoArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { sval, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("t.Message: string too long") + return fmt.Errorf("reading string for field t.Message: string too long") } - return fmt.Errorf("t.Message: %w", err) + return fmt.Errorf("reading string for field t.Message: %w", err) } t.Message = string(sval) } default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("EchoArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for EchoArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("EchoArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field EchoArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("EchoArgumentsModel: map too large") + return fmt.Errorf("map too large for EchoArgumentsModel") } } } diff --git a/capabilities/http/datamodel/json_gen.go b/capabilities/http/datamodel/json_gen.go index ade57f9..5a00143 100644 --- a/capabilities/http/datamodel/json_gen.go +++ b/capabilities/http/datamodel/json_gen.go @@ -31,16 +31,16 @@ func (t *PutArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Body (datamodel.BlobModel) (struct) if len("body") > 8192 { - return fmt.Errorf("String in field \"body\" was too long") + return fmt.Errorf("string in field \"body\" was too long") } if err := jw.WriteString(string("body")); err != nil { - return fmt.Errorf("\"body\": %w", err) + return fmt.Errorf("writing string for field \"body\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Body.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Body: %w", err) + return fmt.Errorf("marshaling field t.Body: %w", err) } written++ if written > 0 { @@ -51,16 +51,16 @@ func (t *PutArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Destination (promise.AwaitOK) (struct) if len("destination") > 8192 { - return fmt.Errorf("String in field \"destination\" was too long") + return fmt.Errorf("string in field \"destination\" was too long") } if err := jw.WriteString(string("destination")); err != nil { - return fmt.Errorf("\"destination\": %w", err) + return fmt.Errorf("writing string for field \"destination\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := t.Destination.MarshalDagJSON(jw); err != nil { - return fmt.Errorf("t.Destination: %w", err) + return fmt.Errorf("marshaling field t.Destination: %w", err) } written++ if err := jw.WriteObjectClose(); err != nil { @@ -78,27 +78,27 @@ func (t *PutArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("PutArgumentsModel: %w", err) + return fmt.Errorf("reading object open for PutArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("PutArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for PutArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("PutArgumentsModel: %w", err) + return fmt.Errorf("reading object close for PutArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("PutArgumentsModel: string too large") + return fmt.Errorf("reading string for field PutArgumentsModel: string too large") } - return fmt.Errorf("PutArgumentsModel: %w", err) + return fmt.Errorf("reading string for field PutArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("PutArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field PutArgumentsModel: %w", err) } switch name { @@ -119,19 +119,19 @@ func (t *PutArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("PutArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for PutArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("PutArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field PutArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("PutArgumentsModel: map too large") + return fmt.Errorf("map too large for PutArgumentsModel") } } } diff --git a/capabilities/index/add.go b/capabilities/index/add.go new file mode 100644 index 0000000..9d093d9 --- /dev/null +++ b/capabilities/index/add.go @@ -0,0 +1,21 @@ +package index + +import ( + cdm "github.com/fil-forge/libforge/capabilities/datamodel" + dm "github.com/fil-forge/libforge/capabilities/index/datamodel" + "github.com/fil-forge/ucantone/errors" + "github.com/fil-forge/ucantone/validator/bindcap" +) + +const AddCommand = "/index/add" + +type ( + AddArguments = dm.AddArgumentsModel + AddOK = cdm.UnitModel +) + +var Add, _ = bindcap.New[*AddArguments](AddCommand) + +const IndexNotFoundErrorName = "IndexNotFound" + +var ErrIndexNotFound = errors.New(IndexNotFoundErrorName, "index not found in space") diff --git a/capabilities/index/datamodel/add.go b/capabilities/index/datamodel/add.go new file mode 100644 index 0000000..e629b31 --- /dev/null +++ b/capabilities/index/datamodel/add.go @@ -0,0 +1,8 @@ +package datamodel + +import "github.com/ipfs/go-cid" + +type AddArgumentsModel struct { + // Index is a link to the Content Archive (CAR) containing the index. + Index cid.Cid `cborgen:"index" dagjsongen:"index"` +} diff --git a/capabilities/index/datamodel/cbor_gen.go b/capabilities/index/datamodel/cbor_gen.go new file mode 100644 index 0000000..7c79d9b --- /dev/null +++ b/capabilities/index/datamodel/cbor_gen.go @@ -0,0 +1,116 @@ +// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT. + +package datamodel + +import ( + "fmt" + "io" + "math" + "sort" + + cid "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + xerrors "golang.org/x/xerrors" +) + +var _ = xerrors.Errorf +var _ = cid.Undef +var _ = math.E +var _ = sort.Sort + +func (t *AddArgumentsModel) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{161}); err != nil { + return err + } + + // t.Index (cid.Cid) (struct) + if len("index") > 8192 { + return xerrors.Errorf("Value in field \"index\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("index"))); err != nil { + return err + } + if _, err := cw.WriteString(string("index")); err != nil { + return err + } + + if err := cbg.WriteCid(cw, t.Index); err != nil { + return xerrors.Errorf("failed to write cid field t.Index: %w", err) + } + + return nil +} + +func (t *AddArgumentsModel) UnmarshalCBOR(r io.Reader) (err error) { + *t = AddArgumentsModel{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("AddArgumentsModel: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 5) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Index (cid.Cid) (struct) + case "index": + + { + + c, err := cbg.ReadCid(cr) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Index: %w", err) + } + + t.Index = c + + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} diff --git a/capabilities/index/datamodel/gen/main.go b/capabilities/index/datamodel/gen/main.go new file mode 100644 index 0000000..2ffc8fc --- /dev/null +++ b/capabilities/index/datamodel/gen/main.go @@ -0,0 +1,21 @@ +//go:generate go run . + +package main + +import ( + jsg "github.com/alanshaw/dag-json-gen" + dm "github.com/fil-forge/libforge/capabilities/index/datamodel" + cbg "github.com/whyrusleeping/cbor-gen" +) + +func main() { + models := []any{ + dm.AddArgumentsModel{}, + } + if err := cbg.WriteMapEncodersToFile("../cbor_gen.go", "datamodel", models...); err != nil { + panic(err) + } + if err := jsg.WriteMapEncodersToFile("../json_gen.go", "datamodel", models...); err != nil { + panic(err) + } +} diff --git a/capabilities/index/datamodel/json_gen.go b/capabilities/index/datamodel/json_gen.go new file mode 100644 index 0000000..65aff53 --- /dev/null +++ b/capabilities/index/datamodel/json_gen.go @@ -0,0 +1,117 @@ +// Code generated by github.com/alanshaw/dag-json-gen. DO NOT EDIT. + +package datamodel + +import ( + "errors" + "fmt" + "io" + "math" + "sort" + + jsg "github.com/alanshaw/dag-json-gen" + cid "github.com/ipfs/go-cid" +) + +var _ = cid.Undef +var _ = math.E +var _ = sort.Sort +var _ = errors.Is + +func (t *AddArgumentsModel) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + + // t.Index (cid.Cid) (struct) + if len("index") > 8192 { + return fmt.Errorf("string in field \"index\" was too long") + } + if err := jw.WriteString(string("index")); err != nil { + return fmt.Errorf("writing string for field \"index\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if err := jw.WriteCid(t.Index); err != nil { + return fmt.Errorf("writing CID for field t.Index: %w", err) + } + + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *AddArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { + *t = AddArgumentsModel{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for AddArgumentsModel: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for AddArgumentsModel: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for AddArgumentsModel: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field AddArgumentsModel: string too large") + } + return fmt.Errorf("reading string for field AddArgumentsModel: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field AddArgumentsModel: %w", err) + } + switch name { + + // t.Index (cid.Cid) (struct) + case "index": + { + + c, err := jr.ReadCid() + if err != nil { + return fmt.Errorf("reading CID for field t.Index: %w", err) + } + t.Index = c + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for AddArgumentsModel: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field AddArgumentsModel: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for AddArgumentsModel") + } + } + } + + return nil +} diff --git a/capabilities/provider/add.go b/capabilities/provider/add.go new file mode 100644 index 0000000..36e8a67 --- /dev/null +++ b/capabilities/provider/add.go @@ -0,0 +1,23 @@ +package provider + +import ( + dm "github.com/fil-forge/libforge/capabilities/provider/datamodel" + "github.com/fil-forge/ucantone/errors" + "github.com/fil-forge/ucantone/validator/bindcap" +) + +const AddCommand = "/provider/add" + +type ( + AddArguments = dm.AddArgumentsModel + AddOK = dm.AddOKModel +) + +var Add, _ = bindcap.New[*AddArguments](AddCommand) + +const ( + InvalidAccountErrorName = "InvalidAccount" + AccountPlanMissingErrorName = "AccountPlanMissing" +) + +var ErrAccountPlanMissing = errors.New(AccountPlanMissingErrorName, "account does not have an active payment plan") diff --git a/capabilities/provider/datamodel/add.go b/capabilities/provider/datamodel/add.go new file mode 100644 index 0000000..2fefd03 --- /dev/null +++ b/capabilities/provider/datamodel/add.go @@ -0,0 +1,14 @@ +package datamodel + +import ( + "github.com/fil-forge/ucantone/did" +) + +type AddArgumentsModel struct { + Provider did.DID `cborgen:"provider" dagjsongen:"provider"` + Consumer did.DID `cborgen:"consumer" dagjsongen:"consumer"` +} + +type AddOKModel struct { + ID string `cborgen:"id" dagjsongen:"id"` +} diff --git a/capabilities/provider/datamodel/cbor_gen.go b/capabilities/provider/datamodel/cbor_gen.go new file mode 100644 index 0000000..d912711 --- /dev/null +++ b/capabilities/provider/datamodel/cbor_gen.go @@ -0,0 +1,238 @@ +// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT. + +package datamodel + +import ( + "fmt" + "io" + "math" + "sort" + + cid "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + xerrors "golang.org/x/xerrors" +) + +var _ = xerrors.Errorf +var _ = cid.Undef +var _ = math.E +var _ = sort.Sort + +func (t *AddArgumentsModel) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{162}); err != nil { + return err + } + + // t.Consumer (did.DID) (struct) + if len("consumer") > 8192 { + return xerrors.Errorf("Value in field \"consumer\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("consumer"))); err != nil { + return err + } + if _, err := cw.WriteString(string("consumer")); err != nil { + return err + } + + if err := t.Consumer.MarshalCBOR(cw); err != nil { + return err + } + + // t.Provider (did.DID) (struct) + if len("provider") > 8192 { + return xerrors.Errorf("Value in field \"provider\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("provider"))); err != nil { + return err + } + if _, err := cw.WriteString(string("provider")); err != nil { + return err + } + + if err := t.Provider.MarshalCBOR(cw); err != nil { + return err + } + return nil +} + +func (t *AddArgumentsModel) UnmarshalCBOR(r io.Reader) (err error) { + *t = AddArgumentsModel{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("AddArgumentsModel: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 8) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Consumer (did.DID) (struct) + case "consumer": + + { + + if err := t.Consumer.UnmarshalCBOR(cr); err != nil { + return xerrors.Errorf("unmarshaling t.Consumer: %w", err) + } + + } + // t.Provider (did.DID) (struct) + case "provider": + + { + + if err := t.Provider.UnmarshalCBOR(cr); err != nil { + return xerrors.Errorf("unmarshaling t.Provider: %w", err) + } + + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *AddOKModel) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{161}); err != nil { + return err + } + + // t.ID (string) (string) + if len("id") > 8192 { + return xerrors.Errorf("Value in field \"id\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("id"))); err != nil { + return err + } + if _, err := cw.WriteString(string("id")); err != nil { + return err + } + + if len(t.ID) > 8192 { + return xerrors.Errorf("Value in field t.ID was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.ID))); err != nil { + return err + } + if _, err := cw.WriteString(string(t.ID)); err != nil { + return err + } + return nil +} + +func (t *AddOKModel) UnmarshalCBOR(r io.Reader) (err error) { + *t = AddOKModel{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("AddOKModel: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 2) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.ID (string) (string) + case "id": + + { + sval, err := cbg.ReadStringWithMax(cr, 8192) + if err != nil { + return err + } + + t.ID = string(sval) + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} diff --git a/capabilities/provider/datamodel/gen/main.go b/capabilities/provider/datamodel/gen/main.go new file mode 100644 index 0000000..aacfd96 --- /dev/null +++ b/capabilities/provider/datamodel/gen/main.go @@ -0,0 +1,22 @@ +//go:generate go run . + +package main + +import ( + jsg "github.com/alanshaw/dag-json-gen" + dm "github.com/fil-forge/libforge/capabilities/provider/datamodel" + cbg "github.com/whyrusleeping/cbor-gen" +) + +func main() { + models := []any{ + dm.AddArgumentsModel{}, + dm.AddOKModel{}, + } + if err := cbg.WriteMapEncodersToFile("../cbor_gen.go", "datamodel", models...); err != nil { + panic(err) + } + if err := jsg.WriteMapEncodersToFile("../json_gen.go", "datamodel", models...); err != nil { + panic(err) + } +} diff --git a/capabilities/provider/datamodel/json_gen.go b/capabilities/provider/datamodel/json_gen.go new file mode 100644 index 0000000..35210f0 --- /dev/null +++ b/capabilities/provider/datamodel/json_gen.go @@ -0,0 +1,239 @@ +// Code generated by github.com/alanshaw/dag-json-gen. DO NOT EDIT. + +package datamodel + +import ( + "errors" + "fmt" + "io" + "math" + "sort" + + jsg "github.com/alanshaw/dag-json-gen" + cid "github.com/ipfs/go-cid" +) + +var _ = cid.Undef +var _ = math.E +var _ = sort.Sort +var _ = errors.Is + +func (t *AddArgumentsModel) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.Consumer (did.DID) (struct) + if len("consumer") > 8192 { + return fmt.Errorf("string in field \"consumer\" was too long") + } + if err := jw.WriteString(string("consumer")); err != nil { + return fmt.Errorf("writing string for field \"consumer\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if err := t.Consumer.MarshalDagJSON(jw); err != nil { + return fmt.Errorf("marshaling field t.Consumer: %w", err) + } + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Provider (did.DID) (struct) + if len("provider") > 8192 { + return fmt.Errorf("string in field \"provider\" was too long") + } + if err := jw.WriteString(string("provider")); err != nil { + return fmt.Errorf("writing string for field \"provider\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if err := t.Provider.MarshalDagJSON(jw); err != nil { + return fmt.Errorf("marshaling field t.Provider: %w", err) + } + written++ + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *AddArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { + *t = AddArgumentsModel{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for AddArgumentsModel: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for AddArgumentsModel: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for AddArgumentsModel: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field AddArgumentsModel: string too large") + } + return fmt.Errorf("reading string for field AddArgumentsModel: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field AddArgumentsModel: %w", err) + } + switch name { + + // t.Consumer (did.DID) (struct) + case "consumer": + + if err := t.Consumer.UnmarshalDagJSON(jr); err != nil { + return fmt.Errorf("unmarshaling t.Consumer: %w", err) + } + + // t.Provider (did.DID) (struct) + case "provider": + + if err := t.Provider.UnmarshalDagJSON(jr); err != nil { + return fmt.Errorf("unmarshaling t.Provider: %w", err) + } + + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for AddArgumentsModel: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field AddArgumentsModel: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for AddArgumentsModel") + } + } + } + + return nil +} +func (t *AddOKModel) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + + // t.ID (string) (string) + if len("id") > 8192 { + return fmt.Errorf("string in field \"id\" was too long") + } + if err := jw.WriteString(string("id")); err != nil { + return fmt.Errorf("writing string for field \"id\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.ID) > 8192 { + return fmt.Errorf("string in field t.ID was too long") + } + if err := jw.WriteString(string(t.ID)); err != nil { + return fmt.Errorf("writing string for field t.ID: %w", err) + } + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *AddOKModel) UnmarshalDagJSON(r io.Reader) (err error) { + *t = AddOKModel{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for AddOKModel: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for AddOKModel: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for AddOKModel: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field AddOKModel: string too large") + } + return fmt.Errorf("reading string for field AddOKModel: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field AddOKModel: %w", err) + } + switch name { + + // t.ID (string) (string) + case "id": + { + sval, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field t.ID: string too long") + } + return fmt.Errorf("reading string for field t.ID: %w", err) + } + t.ID = string(sval) + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for AddOKModel: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field AddOKModel: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for AddOKModel") + } + } + } + + return nil +} diff --git a/capabilities/space/datamodel/cbor_gen.go b/capabilities/space/datamodel/cbor_gen.go new file mode 100644 index 0000000..cae0f83 --- /dev/null +++ b/capabilities/space/datamodel/cbor_gen.go @@ -0,0 +1,152 @@ +// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT. + +package datamodel + +import ( + "fmt" + "io" + "math" + "sort" + + did "github.com/fil-forge/ucantone/did" + cid "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + xerrors "golang.org/x/xerrors" +) + +var _ = xerrors.Errorf +var _ = cid.Undef +var _ = math.E +var _ = sort.Sort + +func (t *InfoOKModel) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{161}); err != nil { + return err + } + + // t.Providers ([]did.DID) (slice) + if len("providers") > 8192 { + return xerrors.Errorf("Value in field \"providers\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("providers"))); err != nil { + return err + } + if _, err := cw.WriteString(string("providers")); err != nil { + return err + } + + if len(t.Providers) > 8192 { + return xerrors.Errorf("Slice value in field t.Providers was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Providers))); err != nil { + return err + } + for _, v := range t.Providers { + if err := v.MarshalCBOR(cw); err != nil { + return err + } + + } + return nil +} + +func (t *InfoOKModel) UnmarshalCBOR(r io.Reader) (err error) { + *t = InfoOKModel{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("InfoOKModel: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 9) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Providers ([]did.DID) (slice) + case "providers": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 8192 { + return fmt.Errorf("t.Providers: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.Providers = make([]did.DID, extra) + } + + for i := 0; i < int(extra); i++ { + { + var maj byte + var extra uint64 + var err error + _ = maj + _ = extra + _ = err + + { + + if err := t.Providers[i].UnmarshalCBOR(cr); err != nil { + return xerrors.Errorf("unmarshaling t.Providers[i]: %w", err) + } + + } + + } + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} diff --git a/capabilities/space/datamodel/gen/main.go b/capabilities/space/datamodel/gen/main.go new file mode 100644 index 0000000..5ff9852 --- /dev/null +++ b/capabilities/space/datamodel/gen/main.go @@ -0,0 +1,21 @@ +//go:generate go run . + +package main + +import ( + jsg "github.com/alanshaw/dag-json-gen" + dm "github.com/fil-forge/libforge/capabilities/space/datamodel" + cbg "github.com/whyrusleeping/cbor-gen" +) + +func main() { + models := []any{ + dm.InfoOKModel{}, + } + if err := cbg.WriteMapEncodersToFile("../cbor_gen.go", "datamodel", models...); err != nil { + panic(err) + } + if err := jsg.WriteMapEncodersToFile("../json_gen.go", "datamodel", models...); err != nil { + panic(err) + } +} diff --git a/capabilities/space/datamodel/info.go b/capabilities/space/datamodel/info.go new file mode 100644 index 0000000..ffc017c --- /dev/null +++ b/capabilities/space/datamodel/info.go @@ -0,0 +1,7 @@ +package datamodel + +import "github.com/fil-forge/ucantone/did" + +type InfoOKModel struct { + Providers []did.DID `cborgen:"providers" dagjsongen:"providers"` +} diff --git a/capabilities/space/datamodel/json_gen.go b/capabilities/space/datamodel/json_gen.go new file mode 100644 index 0000000..074f9f8 --- /dev/null +++ b/capabilities/space/datamodel/json_gen.go @@ -0,0 +1,164 @@ +// Code generated by github.com/alanshaw/dag-json-gen. DO NOT EDIT. + +package datamodel + +import ( + "errors" + "fmt" + "io" + "math" + "sort" + + jsg "github.com/alanshaw/dag-json-gen" + did "github.com/fil-forge/ucantone/did" + cid "github.com/ipfs/go-cid" +) + +var _ = cid.Undef +var _ = math.E +var _ = sort.Sort +var _ = errors.Is + +func (t *InfoOKModel) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + + // t.Providers ([]did.DID) (slice) + if len("providers") > 8192 { + return fmt.Errorf("string in field \"providers\" was too long") + } + if err := jw.WriteString(string("providers")); err != nil { + return fmt.Errorf("writing string for field \"providers\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Providers) > 8192 { + return fmt.Errorf("slice value in field t.Providers was too long") + } + + if err := jw.WriteArrayOpen(); err != nil { + return fmt.Errorf("writing array open for field t.Providers: %w", err) + } + for i, v := range t.Providers { + if i > 0 { + if err := jw.WriteComma(); err != nil { + return fmt.Errorf("writing comma for field t.Providers: %w", err) + } + } + if err := v.MarshalDagJSON(jw); err != nil { + return fmt.Errorf("marshaling field v: %w", err) + } + } + if err := jw.WriteArrayClose(); err != nil { + return fmt.Errorf("writing array close for field t.Providers: %w", err) + } + + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *InfoOKModel) UnmarshalDagJSON(r io.Reader) (err error) { + *t = InfoOKModel{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for InfoOKModel: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for InfoOKModel: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for InfoOKModel: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field InfoOKModel: string too large") + } + return fmt.Errorf("reading string for field InfoOKModel: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field InfoOKModel: %w", err) + } + switch name { + + // t.Providers ([]did.DID) (slice) + case "providers": + { + + if err := jr.ReadArrayOpen(); err != nil { + return fmt.Errorf("reading array open for field t.Providers: %w", err) + } + + close, err := jr.PeekArrayClose() + if err != nil { + return fmt.Errorf("peeking array close for field t.Providers: %w", err) + } + if close { + if err := jr.ReadArrayClose(); err != nil { + return fmt.Errorf("reading array close for field t.Providers: %w", err) + } + + } else { + for i := 0; i < 8192; i++ { + item := make([]did.DID, 1) + + if err := item[0].UnmarshalDagJSON(jr); err != nil { + return fmt.Errorf("unmarshaling item[0]: %w", err) + } + + t.Providers = append(t.Providers, item[0]) + + close, err := jr.ReadArrayCloseOrComma() + if err != nil { + return fmt.Errorf("reading array close or comma for field t.Providers: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("reading array for field t.Providers: slice too large") + } + } + } + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for InfoOKModel: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field InfoOKModel: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for InfoOKModel") + } + } + } + + return nil +} diff --git a/capabilities/space/info.go b/capabilities/space/info.go new file mode 100644 index 0000000..4f508a7 --- /dev/null +++ b/capabilities/space/info.go @@ -0,0 +1,18 @@ +package space + +import ( + cdm "github.com/fil-forge/libforge/capabilities/datamodel" + dm "github.com/fil-forge/libforge/capabilities/space/datamodel" + "github.com/fil-forge/ucantone/validator/bindcap" +) + +const InfoCommand = "/space/info" + +type ( + InfoArguments = cdm.UnitModel + InfoOK = dm.InfoOKModel +) + +var Info, _ = bindcap.New[*InfoArguments](InfoCommand) + +const UnknownSpaceErrorName = "UnknownSpace" diff --git a/capabilities/ucan/attest/datamodel/json_gen.go b/capabilities/ucan/attest/datamodel/json_gen.go index 416e3a4..3cba623 100644 --- a/capabilities/ucan/attest/datamodel/json_gen.go +++ b/capabilities/ucan/attest/datamodel/json_gen.go @@ -30,17 +30,17 @@ func (t *ProofArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Proof (cid.Cid) (struct) if len("proof") > 8192 { - return fmt.Errorf("String in field \"proof\" was too long") + return fmt.Errorf("string in field \"proof\" was too long") } if err := jw.WriteString(string("proof")); err != nil { - return fmt.Errorf("\"proof\": %w", err) + return fmt.Errorf("writing string for field \"proof\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteCid(t.Proof); err != nil { - return fmt.Errorf("t.Proof: %w", err) + return fmt.Errorf("writing CID for field t.Proof: %w", err) } if err := jw.WriteObjectClose(); err != nil { @@ -58,27 +58,27 @@ func (t *ProofArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("ProofArgumentsModel: %w", err) + return fmt.Errorf("reading object open for ProofArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("ProofArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for ProofArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("ProofArgumentsModel: %w", err) + return fmt.Errorf("reading object close for ProofArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("ProofArgumentsModel: string too large") + return fmt.Errorf("reading string for field ProofArgumentsModel: string too large") } - return fmt.Errorf("ProofArgumentsModel: %w", err) + return fmt.Errorf("reading string for field ProofArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("ProofArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field ProofArgumentsModel: %w", err) } switch name { @@ -88,7 +88,7 @@ func (t *ProofArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { c, err := jr.ReadCid() if err != nil { - return fmt.Errorf("t.Proof: %w", err) + return fmt.Errorf("reading CID for field t.Proof: %w", err) } t.Proof = c @@ -96,19 +96,19 @@ func (t *ProofArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("ProofArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for ProofArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("ProofArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field ProofArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("ProofArgumentsModel: map too large") + return fmt.Errorf("map too large for ProofArgumentsModel") } } } diff --git a/capabilities/ucan/conclude.go b/capabilities/ucan/conclude.go index bce56b0..2b9d7e7 100644 --- a/capabilities/ucan/conclude.go +++ b/capabilities/ucan/conclude.go @@ -3,6 +3,7 @@ package ucan import ( cdm "github.com/fil-forge/libforge/capabilities/datamodel" udm "github.com/fil-forge/libforge/capabilities/ucan/datamodel" + "github.com/fil-forge/ucantone/errors" "github.com/fil-forge/ucantone/validator/bindcap" ) @@ -14,3 +15,7 @@ type ( const ConcludeCommand = "/ucan/conclude" var Conclude, _ = bindcap.New[*ConcludeArguments](ConcludeCommand) + +const ConclusionReceiptNotFoundErrorName = "ConclusionReceiptNotFound" + +var ErrConclusionReceiptNotFound = errors.New(ConclusionReceiptNotFoundErrorName, "conclusion receipt not found") diff --git a/capabilities/ucan/datamodel/json_gen.go b/capabilities/ucan/datamodel/json_gen.go index 229b6e2..c1e100d 100644 --- a/capabilities/ucan/datamodel/json_gen.go +++ b/capabilities/ucan/datamodel/json_gen.go @@ -30,17 +30,17 @@ func (t *ConcludeArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Receipt (cid.Cid) (struct) if len("receipt") > 8192 { - return fmt.Errorf("String in field \"receipt\" was too long") + return fmt.Errorf("string in field \"receipt\" was too long") } if err := jw.WriteString(string("receipt")); err != nil { - return fmt.Errorf("\"receipt\": %w", err) + return fmt.Errorf("writing string for field \"receipt\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteCid(t.Receipt); err != nil { - return fmt.Errorf("t.Receipt: %w", err) + return fmt.Errorf("writing CID for field t.Receipt: %w", err) } if err := jw.WriteObjectClose(); err != nil { @@ -58,27 +58,27 @@ func (t *ConcludeArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("ConcludeArgumentsModel: %w", err) + return fmt.Errorf("reading object open for ConcludeArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("ConcludeArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for ConcludeArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("ConcludeArgumentsModel: %w", err) + return fmt.Errorf("reading object close for ConcludeArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("ConcludeArgumentsModel: string too large") + return fmt.Errorf("reading string for field ConcludeArgumentsModel: string too large") } - return fmt.Errorf("ConcludeArgumentsModel: %w", err) + return fmt.Errorf("reading string for field ConcludeArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("ConcludeArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field ConcludeArgumentsModel: %w", err) } switch name { @@ -88,7 +88,7 @@ func (t *ConcludeArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { c, err := jr.ReadCid() if err != nil { - return fmt.Errorf("t.Receipt: %w", err) + return fmt.Errorf("reading CID for field t.Receipt: %w", err) } t.Receipt = c @@ -96,19 +96,19 @@ func (t *ConcludeArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("ConcludeArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for ConcludeArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("ConcludeArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field ConcludeArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("ConcludeArgumentsModel: map too large") + return fmt.Errorf("map too large for ConcludeArgumentsModel") } } } diff --git a/capabilities/upload/datamodel/add.go b/capabilities/upload/datamodel/add.go index 8e748fa..6e4a983 100644 --- a/capabilities/upload/datamodel/add.go +++ b/capabilities/upload/datamodel/add.go @@ -7,5 +7,5 @@ import ( type AddArgumentsModel struct { Root cid.Cid `cborgen:"root" dagjsongen:"root"` Shards []cid.Cid `cborgen:"shards" dagjsongen:"shards"` - Index cid.Cid `cborgen:"index" dagjsongen:"index"` + Index *cid.Cid `cborgen:"index,omitempty" dagjsongen:"index,omitempty"` } diff --git a/capabilities/upload/datamodel/cbor_gen.go b/capabilities/upload/datamodel/cbor_gen.go index 3214d1b..0029ade 100644 --- a/capabilities/upload/datamodel/cbor_gen.go +++ b/capabilities/upload/datamodel/cbor_gen.go @@ -25,8 +25,13 @@ func (t *AddArgumentsModel) MarshalCBOR(w io.Writer) error { } cw := cbg.NewCborWriter(w) + fieldCount := 3 - if _, err := cw.Write([]byte{163}); err != nil { + if t.Index == nil { + fieldCount-- + } + + if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil { return err } @@ -47,19 +52,29 @@ func (t *AddArgumentsModel) MarshalCBOR(w io.Writer) error { } // t.Index (cid.Cid) (struct) - if len("index") > 8192 { - return xerrors.Errorf("Value in field \"index\" was too long") - } + if t.Index != nil { - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("index"))); err != nil { - return err - } - if _, err := cw.WriteString(string("index")); err != nil { - return err - } + if len("index") > 8192 { + return xerrors.Errorf("Value in field \"index\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("index"))); err != nil { + return err + } + if _, err := cw.WriteString(string("index")); err != nil { + return err + } + + if t.Index == nil { + if _, err := cw.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(cw, *t.Index); err != nil { + return xerrors.Errorf("failed to write cid field t.Index: %w", err) + } + } - if err := cbg.WriteCid(cw, t.Index); err != nil { - return xerrors.Errorf("failed to write cid field t.Index: %w", err) } // t.Shards ([]cid.Cid) (slice) @@ -150,12 +165,22 @@ func (t *AddArgumentsModel) UnmarshalCBOR(r io.Reader) (err error) { { - c, err := cbg.ReadCid(cr) + b, err := cr.ReadByte() if err != nil { - return xerrors.Errorf("failed to read cid field t.Index: %w", err) + return err } + if b != cbg.CborNull[0] { + if err := cr.UnreadByte(); err != nil { + return err + } - t.Index = c + c, err := cbg.ReadCid(cr) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Index: %w", err) + } + + t.Index = &c + } } // t.Shards ([]cid.Cid) (slice) @@ -307,3 +332,585 @@ func (t *RemoveArgumentsModel) UnmarshalCBOR(r io.Reader) (err error) { return nil } +func (t *ListArgumentsModel) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + fieldCount := 2 + + if t.Cursor == nil { + fieldCount-- + } + + if t.Size == nil { + fieldCount-- + } + + if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil { + return err + } + + // t.Size (int64) (int64) + if t.Size != nil { + + if len("size") > 8192 { + return xerrors.Errorf("Value in field \"size\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("size"))); err != nil { + return err + } + if _, err := cw.WriteString(string("size")); err != nil { + return err + } + + if t.Size == nil { + if _, err := cw.Write(cbg.CborNull); err != nil { + return err + } + } else { + if *t.Size >= 0 { + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(*t.Size)); err != nil { + return err + } + } else { + if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-*t.Size-1)); err != nil { + return err + } + } + } + + } + + // t.Cursor (string) (string) + if t.Cursor != nil { + + if len("cursor") > 8192 { + return xerrors.Errorf("Value in field \"cursor\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("cursor"))); err != nil { + return err + } + if _, err := cw.WriteString(string("cursor")); err != nil { + return err + } + + if t.Cursor == nil { + if _, err := cw.Write(cbg.CborNull); err != nil { + return err + } + } else { + if len(*t.Cursor) > 8192 { + return xerrors.Errorf("Value in field t.Cursor was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Cursor))); err != nil { + return err + } + if _, err := cw.WriteString(string(*t.Cursor)); err != nil { + return err + } + } + } + return nil +} + +func (t *ListArgumentsModel) UnmarshalCBOR(r io.Reader) (err error) { + *t = ListArgumentsModel{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("ListArgumentsModel: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 6) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Size (int64) (int64) + case "size": + { + + b, err := cr.ReadByte() + if err != nil { + return err + } + if b != cbg.CborNull[0] { + if err := cr.UnreadByte(); err != nil { + return err + } + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + var extraI int64 + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative overflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.Size = (*int64)(&extraI) + } + } + // t.Cursor (string) (string) + case "cursor": + + { + b, err := cr.ReadByte() + if err != nil { + return err + } + if b != cbg.CborNull[0] { + if err := cr.UnreadByte(); err != nil { + return err + } + + sval, err := cbg.ReadStringWithMax(cr, 8192) + if err != nil { + return err + } + + t.Cursor = (*string)(&sval) + } + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *ListOKModel) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + fieldCount := 3 + + if t.Cursor == nil { + fieldCount-- + } + + if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil { + return err + } + + // t.Size (int64) (int64) + if len("size") > 8192 { + return xerrors.Errorf("Value in field \"size\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("size"))); err != nil { + return err + } + if _, err := cw.WriteString(string("size")); err != nil { + return err + } + + if t.Size >= 0 { + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Size)); err != nil { + return err + } + } else { + if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.Size-1)); err != nil { + return err + } + } + + // t.Cursor (string) (string) + if t.Cursor != nil { + + if len("cursor") > 8192 { + return xerrors.Errorf("Value in field \"cursor\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("cursor"))); err != nil { + return err + } + if _, err := cw.WriteString(string("cursor")); err != nil { + return err + } + + if t.Cursor == nil { + if _, err := cw.Write(cbg.CborNull); err != nil { + return err + } + } else { + if len(*t.Cursor) > 8192 { + return xerrors.Errorf("Value in field t.Cursor was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Cursor))); err != nil { + return err + } + if _, err := cw.WriteString(string(*t.Cursor)); err != nil { + return err + } + } + } + + // t.Results ([]datamodel.ListUploadItem) (slice) + if len("results") > 8192 { + return xerrors.Errorf("Value in field \"results\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("results"))); err != nil { + return err + } + if _, err := cw.WriteString(string("results")); err != nil { + return err + } + + if len(t.Results) > 8192 { + return xerrors.Errorf("Slice value in field t.Results was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Results))); err != nil { + return err + } + for _, v := range t.Results { + if err := v.MarshalCBOR(cw); err != nil { + return err + } + + } + return nil +} + +func (t *ListOKModel) UnmarshalCBOR(r io.Reader) (err error) { + *t = ListOKModel{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("ListOKModel: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 7) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Size (int64) (int64) + case "size": + { + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + var extraI int64 + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative overflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.Size = int64(extraI) + } + // t.Cursor (string) (string) + case "cursor": + + { + b, err := cr.ReadByte() + if err != nil { + return err + } + if b != cbg.CborNull[0] { + if err := cr.UnreadByte(); err != nil { + return err + } + + sval, err := cbg.ReadStringWithMax(cr, 8192) + if err != nil { + return err + } + + t.Cursor = (*string)(&sval) + } + } + // t.Results ([]datamodel.ListUploadItem) (slice) + case "results": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 8192 { + return fmt.Errorf("t.Results: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.Results = make([]ListUploadItem, extra) + } + + for i := 0; i < int(extra); i++ { + { + var maj byte + var extra uint64 + var err error + _ = maj + _ = extra + _ = err + + { + + if err := t.Results[i].UnmarshalCBOR(cr); err != nil { + return xerrors.Errorf("unmarshaling t.Results[i]: %w", err) + } + + } + + } + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *ListUploadItem) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + fieldCount := 2 + + if t.Index == nil { + fieldCount-- + } + + if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil { + return err + } + + // t.Root (cid.Cid) (struct) + if len("root") > 8192 { + return xerrors.Errorf("Value in field \"root\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("root"))); err != nil { + return err + } + if _, err := cw.WriteString(string("root")); err != nil { + return err + } + + if err := cbg.WriteCid(cw, t.Root); err != nil { + return xerrors.Errorf("failed to write cid field t.Root: %w", err) + } + + // t.Index (cid.Cid) (struct) + if t.Index != nil { + + if len("index") > 8192 { + return xerrors.Errorf("Value in field \"index\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("index"))); err != nil { + return err + } + if _, err := cw.WriteString(string("index")); err != nil { + return err + } + + if t.Index == nil { + if _, err := cw.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(cw, *t.Index); err != nil { + return xerrors.Errorf("failed to write cid field t.Index: %w", err) + } + } + + } + return nil +} + +func (t *ListUploadItem) UnmarshalCBOR(r io.Reader) (err error) { + *t = ListUploadItem{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("ListUploadItem: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 5) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Root (cid.Cid) (struct) + case "root": + + { + + c, err := cbg.ReadCid(cr) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Root: %w", err) + } + + t.Root = c + + } + // t.Index (cid.Cid) (struct) + case "index": + + { + + b, err := cr.ReadByte() + if err != nil { + return err + } + if b != cbg.CborNull[0] { + if err := cr.UnreadByte(); err != nil { + return err + } + + c, err := cbg.ReadCid(cr) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Index: %w", err) + } + + t.Index = &c + } + + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} diff --git a/capabilities/upload/datamodel/gen/main.go b/capabilities/upload/datamodel/gen/main.go index 00492af..cd83181 100644 --- a/capabilities/upload/datamodel/gen/main.go +++ b/capabilities/upload/datamodel/gen/main.go @@ -12,6 +12,9 @@ func main() { models := []any{ dm.AddArgumentsModel{}, dm.RemoveArgumentsModel{}, + dm.ListArgumentsModel{}, + dm.ListOKModel{}, + dm.ListUploadItem{}, } if err := cbg.WriteMapEncodersToFile("../cbor_gen.go", "datamodel", models...); err != nil { panic(err) diff --git a/capabilities/upload/datamodel/json_gen.go b/capabilities/upload/datamodel/json_gen.go index 45a01aa..8b3dbd9 100644 --- a/capabilities/upload/datamodel/json_gen.go +++ b/capabilities/upload/datamodel/json_gen.go @@ -30,21 +30,29 @@ func (t *AddArgumentsModel) MarshalDagJSON(w io.Writer) error { written := 0 // t.Index (cid.Cid) (struct) - if len("index") > 8192 { - return fmt.Errorf("String in field \"index\" was too long") - } - if err := jw.WriteString(string("index")); err != nil { - return fmt.Errorf("\"index\": %w", err) - } - if err := jw.WriteObjectColon(); err != nil { - return err - } + if t.Index != nil { + if len("index") > 8192 { + return fmt.Errorf("string in field \"index\" was too long") + } + if err := jw.WriteString(string("index")); err != nil { + return fmt.Errorf("writing string for field \"index\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } - if err := jw.WriteCid(t.Index); err != nil { - return fmt.Errorf("t.Index: %w", err) - } + if t.Index == nil { + if err := jw.WriteNull(); err != nil { + return fmt.Errorf("writing null for field t.Index: %w", err) + } + } else { + if err := jw.WriteCid(*t.Index); err != nil { + return fmt.Errorf("writing CID for field t.Index: %w", err) + } + } - written++ + written++ + } if written > 0 { if err := jw.WriteComma(); err != nil { return err @@ -53,17 +61,17 @@ func (t *AddArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Root (cid.Cid) (struct) if len("root") > 8192 { - return fmt.Errorf("String in field \"root\" was too long") + return fmt.Errorf("string in field \"root\" was too long") } if err := jw.WriteString(string("root")); err != nil { - return fmt.Errorf("\"root\": %w", err) + return fmt.Errorf("writing string for field \"root\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteCid(t.Root); err != nil { - return fmt.Errorf("t.Root: %w", err) + return fmt.Errorf("writing CID for field t.Root: %w", err) } written++ @@ -75,35 +83,35 @@ func (t *AddArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Shards ([]cid.Cid) (slice) if len("shards") > 8192 { - return fmt.Errorf("String in field \"shards\" was too long") + return fmt.Errorf("string in field \"shards\" was too long") } if err := jw.WriteString(string("shards")); err != nil { - return fmt.Errorf("\"shards\": %w", err) + return fmt.Errorf("writing string for field \"shards\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if len(t.Shards) > 8192 { - return fmt.Errorf("Slice value in field t.Shards was too long") + return fmt.Errorf("slice value in field t.Shards was too long") } if err := jw.WriteArrayOpen(); err != nil { - return fmt.Errorf("t.Shards: %w", err) + return fmt.Errorf("writing array open for field t.Shards: %w", err) } for i, v := range t.Shards { if i > 0 { if err := jw.WriteComma(); err != nil { - return fmt.Errorf("t.Shards: %w", err) + return fmt.Errorf("writing comma for field t.Shards: %w", err) } } if err := jw.WriteCid(v); err != nil { - return fmt.Errorf("v: %w", err) + return fmt.Errorf("writing CID for field v: %w", err) } } if err := jw.WriteArrayClose(); err != nil { - return fmt.Errorf("t.Shards: %w", err) + return fmt.Errorf("writing array close for field t.Shards: %w", err) } written++ @@ -122,27 +130,27 @@ func (t *AddArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("AddArgumentsModel: %w", err) + return fmt.Errorf("reading object open for AddArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("AddArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for AddArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("AddArgumentsModel: %w", err) + return fmt.Errorf("reading object close for AddArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("AddArgumentsModel: string too large") + return fmt.Errorf("reading string for field AddArgumentsModel: string too large") } - return fmt.Errorf("AddArgumentsModel: %w", err) + return fmt.Errorf("reading string for field AddArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("AddArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field AddArgumentsModel: %w", err) } switch name { @@ -150,9 +158,9 @@ func (t *AddArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { case "index": { - c, err := jr.ReadCid() + c, err := jr.ReadCidOrNull() if err != nil { - return fmt.Errorf("t.Index: %w", err) + return fmt.Errorf("reading CID or null for field t.Index: %w", err) } t.Index = c @@ -164,7 +172,7 @@ func (t *AddArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { c, err := jr.ReadCid() if err != nil { - return fmt.Errorf("t.Root: %w", err) + return fmt.Errorf("reading CID for field t.Root: %w", err) } t.Root = c @@ -175,16 +183,16 @@ func (t *AddArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { { if err := jr.ReadArrayOpen(); err != nil { - return fmt.Errorf("t.Shards: %w", err) + return fmt.Errorf("reading array open for field t.Shards: %w", err) } close, err := jr.PeekArrayClose() if err != nil { - return fmt.Errorf("t.Shards: %w", err) + return fmt.Errorf("peeking array close for field t.Shards: %w", err) } if close { if err := jr.ReadArrayClose(); err != nil { - return fmt.Errorf("t.Shards: %w", err) + return fmt.Errorf("reading array close for field t.Shards: %w", err) } } else { @@ -194,7 +202,7 @@ func (t *AddArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { c, err := jr.ReadCid() if err != nil { - return fmt.Errorf("item[0]: %w", err) + return fmt.Errorf("reading CID for field item[0]: %w", err) } item[0] = c @@ -203,13 +211,13 @@ func (t *AddArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { close, err := jr.ReadArrayCloseOrComma() if err != nil { - return fmt.Errorf("t.Shards: %w", err) + return fmt.Errorf("reading array close or comma for field t.Shards: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("t.Shards: slice too large") + return fmt.Errorf("reading array for field t.Shards: slice too large") } } } @@ -218,19 +226,19 @@ func (t *AddArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("AddArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for AddArgumentsModel: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("AddArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field AddArgumentsModel: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("AddArgumentsModel: map too large") + return fmt.Errorf("map too large for AddArgumentsModel") } } } @@ -249,17 +257,17 @@ func (t *RemoveArgumentsModel) MarshalDagJSON(w io.Writer) error { // t.Root (cid.Cid) (struct) if len("root") > 8192 { - return fmt.Errorf("String in field \"root\" was too long") + return fmt.Errorf("string in field \"root\" was too long") } if err := jw.WriteString(string("root")); err != nil { - return fmt.Errorf("\"root\": %w", err) + return fmt.Errorf("writing string for field \"root\": %w", err) } if err := jw.WriteObjectColon(); err != nil { return err } if err := jw.WriteCid(t.Root); err != nil { - return fmt.Errorf("t.Root: %w", err) + return fmt.Errorf("writing CID for field t.Root: %w", err) } if err := jw.WriteObjectClose(); err != nil { @@ -277,27 +285,27 @@ func (t *RemoveArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { } }() if err := jr.ReadObjectOpen(); err != nil { - return fmt.Errorf("RemoveArgumentsModel: %w", err) + return fmt.Errorf("reading object open for RemoveArgumentsModel: %w", err) } close, err := jr.PeekObjectClose() if err != nil { - return fmt.Errorf("RemoveArgumentsModel: %w", err) + return fmt.Errorf("peeking object close for RemoveArgumentsModel: %w", err) } if close { if err := jr.ReadObjectClose(); err != nil { - return fmt.Errorf("RemoveArgumentsModel: %w", err) + return fmt.Errorf("reading object close for RemoveArgumentsModel: %w", err) } } else { for i := uint64(0); i < 8192; i++ { name, err := jr.ReadString(8192) if err != nil { if errors.Is(err, jsg.ErrLimitExceeded) { - return fmt.Errorf("RemoveArgumentsModel: string too large") + return fmt.Errorf("reading string for field RemoveArgumentsModel: string too large") } - return fmt.Errorf("RemoveArgumentsModel: %w", err) + return fmt.Errorf("reading string for field RemoveArgumentsModel: %w", err) } if err := jr.ReadObjectColon(); err != nil { - return fmt.Errorf("RemoveArgumentsModel: %w", err) + return fmt.Errorf("reading object colon for field RemoveArgumentsModel: %w", err) } switch name { @@ -307,7 +315,531 @@ func (t *RemoveArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { c, err := jr.ReadCid() if err != nil { - return fmt.Errorf("t.Root: %w", err) + return fmt.Errorf("reading CID for field t.Root: %w", err) + } + t.Root = c + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for RemoveArgumentsModel: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field RemoveArgumentsModel: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for RemoveArgumentsModel") + } + } + } + + return nil +} +func (t *ListArgumentsModel) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.Cursor (string) (string) + if t.Cursor != nil { + if len("cursor") > 8192 { + return fmt.Errorf("string in field \"cursor\" was too long") + } + if err := jw.WriteString(string("cursor")); err != nil { + return fmt.Errorf("writing string for field \"cursor\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if t.Cursor == nil { + if err := jw.WriteNull(); err != nil { + return fmt.Errorf("writing null for field t.Cursor: %w", err) + } + } else { + if len(*t.Cursor) > 8192 { + return fmt.Errorf("string in field t.Cursor was too long") + } + if err := jw.WriteString(string(*t.Cursor)); err != nil { + return fmt.Errorf("writing string for field t.Cursor: %w", err) + } + } + written++ + } + if t.Size != nil { + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + } + + // t.Size (int64) (int64) + if t.Size != nil { + if len("size") > 8192 { + return fmt.Errorf("string in field \"size\" was too long") + } + if err := jw.WriteString(string("size")); err != nil { + return fmt.Errorf("writing string for field \"size\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if t.Size == nil { + if err := jw.WriteNull(); err != nil { + return fmt.Errorf("writing null for field t.Size: %w", err) + } + } else { + if err := jw.WriteInt64(int64(*t.Size)); err != nil { + return fmt.Errorf("writing int64 for field t.Size: %w", err) + } + } + + written++ + } + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *ListArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { + *t = ListArgumentsModel{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for ListArgumentsModel: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for ListArgumentsModel: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for ListArgumentsModel: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field ListArgumentsModel: string too large") + } + return fmt.Errorf("reading string for field ListArgumentsModel: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field ListArgumentsModel: %w", err) + } + switch name { + + // t.Cursor (string) (string) + case "cursor": + { + sval, err := jr.ReadStringOrNull(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string or null for field t.Cursor: string too long") + } + return fmt.Errorf("reading string or null for field t.Cursor: %w", err) + } + if sval != nil { + t.Cursor = (*string)(sval) + } + } + + // t.Size (int64) (int64) + case "size": + { + + nval, err := jr.ReadNumberAsInt64OrNull() + if err != nil { + return fmt.Errorf("reading int64 or null for field t.Size: %w", err) + } + if nval != nil { + typed := int64(*nval) + t.Size = &typed + } + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for ListArgumentsModel: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field ListArgumentsModel: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for ListArgumentsModel") + } + } + } + + return nil +} +func (t *ListOKModel) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.Cursor (string) (string) + if t.Cursor != nil { + if len("cursor") > 8192 { + return fmt.Errorf("string in field \"cursor\" was too long") + } + if err := jw.WriteString(string("cursor")); err != nil { + return fmt.Errorf("writing string for field \"cursor\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if t.Cursor == nil { + if err := jw.WriteNull(); err != nil { + return fmt.Errorf("writing null for field t.Cursor: %w", err) + } + } else { + if len(*t.Cursor) > 8192 { + return fmt.Errorf("string in field t.Cursor was too long") + } + if err := jw.WriteString(string(*t.Cursor)); err != nil { + return fmt.Errorf("writing string for field t.Cursor: %w", err) + } + } + written++ + } + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Results ([]datamodel.ListUploadItem) (slice) + if len("results") > 8192 { + return fmt.Errorf("string in field \"results\" was too long") + } + if err := jw.WriteString(string("results")); err != nil { + return fmt.Errorf("writing string for field \"results\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Results) > 8192 { + return fmt.Errorf("slice value in field t.Results was too long") + } + + if err := jw.WriteArrayOpen(); err != nil { + return fmt.Errorf("writing array open for field t.Results: %w", err) + } + for i, v := range t.Results { + if i > 0 { + if err := jw.WriteComma(); err != nil { + return fmt.Errorf("writing comma for field t.Results: %w", err) + } + } + if err := v.MarshalDagJSON(jw); err != nil { + return fmt.Errorf("marshaling field v: %w", err) + } + } + if err := jw.WriteArrayClose(); err != nil { + return fmt.Errorf("writing array close for field t.Results: %w", err) + } + + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Size (int64) (int64) + if len("size") > 8192 { + return fmt.Errorf("string in field \"size\" was too long") + } + if err := jw.WriteString(string("size")); err != nil { + return fmt.Errorf("writing string for field \"size\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if err := jw.WriteInt64(int64(t.Size)); err != nil { + return fmt.Errorf("writing int64 for field t.Size: %w", err) + } + + written++ + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *ListOKModel) UnmarshalDagJSON(r io.Reader) (err error) { + *t = ListOKModel{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for ListOKModel: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for ListOKModel: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for ListOKModel: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field ListOKModel: string too large") + } + return fmt.Errorf("reading string for field ListOKModel: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field ListOKModel: %w", err) + } + switch name { + + // t.Cursor (string) (string) + case "cursor": + { + sval, err := jr.ReadStringOrNull(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string or null for field t.Cursor: string too long") + } + return fmt.Errorf("reading string or null for field t.Cursor: %w", err) + } + if sval != nil { + t.Cursor = (*string)(sval) + } + } + + // t.Results ([]datamodel.ListUploadItem) (slice) + case "results": + { + + if err := jr.ReadArrayOpen(); err != nil { + return fmt.Errorf("reading array open for field t.Results: %w", err) + } + + close, err := jr.PeekArrayClose() + if err != nil { + return fmt.Errorf("peeking array close for field t.Results: %w", err) + } + if close { + if err := jr.ReadArrayClose(); err != nil { + return fmt.Errorf("reading array close for field t.Results: %w", err) + } + + } else { + for i := 0; i < 8192; i++ { + item := make([]ListUploadItem, 1) + + if err := item[0].UnmarshalDagJSON(jr); err != nil { + return fmt.Errorf("unmarshaling item[0]: %w", err) + } + + t.Results = append(t.Results, item[0]) + + close, err := jr.ReadArrayCloseOrComma() + if err != nil { + return fmt.Errorf("reading array close or comma for field t.Results: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("reading array for field t.Results: slice too large") + } + } + } + + } + + // t.Size (int64) (int64) + case "size": + { + + nval, err := jr.ReadNumberAsInt64() + if err != nil { + return fmt.Errorf("reading int64 for field t.Size: %w", err) + } + t.Size = int64(nval) + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for ListOKModel: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field ListOKModel: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for ListOKModel") + } + } + } + + return nil +} +func (t *ListUploadItem) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.Index (cid.Cid) (struct) + if t.Index != nil { + if len("index") > 8192 { + return fmt.Errorf("string in field \"index\" was too long") + } + if err := jw.WriteString(string("index")); err != nil { + return fmt.Errorf("writing string for field \"index\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if t.Index == nil { + if err := jw.WriteNull(); err != nil { + return fmt.Errorf("writing null for field t.Index: %w", err) + } + } else { + if err := jw.WriteCid(*t.Index); err != nil { + return fmt.Errorf("writing CID for field t.Index: %w", err) + } + } + + written++ + } + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Root (cid.Cid) (struct) + if len("root") > 8192 { + return fmt.Errorf("string in field \"root\" was too long") + } + if err := jw.WriteString(string("root")); err != nil { + return fmt.Errorf("writing string for field \"root\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if err := jw.WriteCid(t.Root); err != nil { + return fmt.Errorf("writing CID for field t.Root: %w", err) + } + + written++ + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *ListUploadItem) UnmarshalDagJSON(r io.Reader) (err error) { + *t = ListUploadItem{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for ListUploadItem: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for ListUploadItem: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for ListUploadItem: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field ListUploadItem: string too large") + } + return fmt.Errorf("reading string for field ListUploadItem: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field ListUploadItem: %w", err) + } + switch name { + + // t.Index (cid.Cid) (struct) + case "index": + { + + c, err := jr.ReadCidOrNull() + if err != nil { + return fmt.Errorf("reading CID or null for field t.Index: %w", err) + } + t.Index = c + + } + + // t.Root (cid.Cid) (struct) + case "root": + { + + c, err := jr.ReadCid() + if err != nil { + return fmt.Errorf("reading CID for field t.Root: %w", err) } t.Root = c @@ -315,19 +847,19 @@ func (t *RemoveArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { default: // Field doesn't exist on this type, so ignore it if err := jr.DiscardType(); err != nil { - return fmt.Errorf("RemoveArgumentsModel: ignoring field %s: %w", name, err) + return fmt.Errorf("ignoring field %s for ListUploadItem: %w", name, err) } } close, err := jr.ReadObjectCloseOrComma() if err != nil { - return fmt.Errorf("RemoveArgumentsModel: %w", err) + return fmt.Errorf("reading object close or comma for field ListUploadItem: %w", err) } if close { break } if i == 8192-1 { - return fmt.Errorf("RemoveArgumentsModel: map too large") + return fmt.Errorf("map too large for ListUploadItem") } } } diff --git a/capabilities/upload/datamodel/list.go b/capabilities/upload/datamodel/list.go new file mode 100644 index 0000000..ed92a23 --- /dev/null +++ b/capabilities/upload/datamodel/list.go @@ -0,0 +1,19 @@ +package datamodel + +import "github.com/ipfs/go-cid" + +type ListArgumentsModel struct { + Cursor *string `cborgen:"cursor,omitempty" dagjsongen:"cursor,omitempty"` + Size *int64 `cborgen:"size,omitempty" dagjsongen:"size,omitempty"` +} + +type ListOKModel struct { + Cursor *string `cborgen:"cursor,omitempty" dagjsongen:"cursor,omitempty"` + Size int64 `cborgen:"size" dagjsongen:"size"` + Results []ListUploadItem `cborgen:"results" dagjsongen:"results"` +} + +type ListUploadItem struct { + Root cid.Cid `cborgen:"root" dagjsongen:"root"` + Index *cid.Cid `cborgen:"index,omitempty" dagjsongen:"index,omitempty"` +} diff --git a/capabilities/upload/list.go b/capabilities/upload/list.go new file mode 100644 index 0000000..1949d1e --- /dev/null +++ b/capabilities/upload/list.go @@ -0,0 +1,16 @@ +package upload + +import ( + dm "github.com/fil-forge/libforge/capabilities/upload/datamodel" + "github.com/fil-forge/ucantone/validator/bindcap" +) + +const ListCommand = "/upload/list" + +type ( + ListArguments = dm.ListArgumentsModel + ListOK = dm.ListOKModel + ListUploadItem = dm.ListUploadItem +) + +var List, _ = bindcap.New[*ListArguments](ListCommand) diff --git a/capabilities/upload/shard/datamodel/cbor_gen.go b/capabilities/upload/shard/datamodel/cbor_gen.go new file mode 100644 index 0000000..76b33a3 --- /dev/null +++ b/capabilities/upload/shard/datamodel/cbor_gen.go @@ -0,0 +1,486 @@ +// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT. + +package datamodel + +import ( + "fmt" + "io" + "math" + "sort" + + cid "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + xerrors "golang.org/x/xerrors" +) + +var _ = xerrors.Errorf +var _ = cid.Undef +var _ = math.E +var _ = sort.Sort + +func (t *ListArgumentsModel) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + fieldCount := 3 + + if t.Cursor == nil { + fieldCount-- + } + + if t.Size == nil { + fieldCount-- + } + + if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil { + return err + } + + // t.Root (cid.Cid) (struct) + if len("root") > 8192 { + return xerrors.Errorf("Value in field \"root\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("root"))); err != nil { + return err + } + if _, err := cw.WriteString(string("root")); err != nil { + return err + } + + if err := cbg.WriteCid(cw, t.Root); err != nil { + return xerrors.Errorf("failed to write cid field t.Root: %w", err) + } + + // t.Size (int64) (int64) + if t.Size != nil { + + if len("size") > 8192 { + return xerrors.Errorf("Value in field \"size\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("size"))); err != nil { + return err + } + if _, err := cw.WriteString(string("size")); err != nil { + return err + } + + if t.Size == nil { + if _, err := cw.Write(cbg.CborNull); err != nil { + return err + } + } else { + if *t.Size >= 0 { + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(*t.Size)); err != nil { + return err + } + } else { + if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-*t.Size-1)); err != nil { + return err + } + } + } + + } + + // t.Cursor (string) (string) + if t.Cursor != nil { + + if len("cursor") > 8192 { + return xerrors.Errorf("Value in field \"cursor\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("cursor"))); err != nil { + return err + } + if _, err := cw.WriteString(string("cursor")); err != nil { + return err + } + + if t.Cursor == nil { + if _, err := cw.Write(cbg.CborNull); err != nil { + return err + } + } else { + if len(*t.Cursor) > 8192 { + return xerrors.Errorf("Value in field t.Cursor was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Cursor))); err != nil { + return err + } + if _, err := cw.WriteString(string(*t.Cursor)); err != nil { + return err + } + } + } + return nil +} + +func (t *ListArgumentsModel) UnmarshalCBOR(r io.Reader) (err error) { + *t = ListArgumentsModel{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("ListArgumentsModel: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 6) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Root (cid.Cid) (struct) + case "root": + + { + + c, err := cbg.ReadCid(cr) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Root: %w", err) + } + + t.Root = c + + } + // t.Size (int64) (int64) + case "size": + { + + b, err := cr.ReadByte() + if err != nil { + return err + } + if b != cbg.CborNull[0] { + if err := cr.UnreadByte(); err != nil { + return err + } + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + var extraI int64 + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative overflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.Size = (*int64)(&extraI) + } + } + // t.Cursor (string) (string) + case "cursor": + + { + b, err := cr.ReadByte() + if err != nil { + return err + } + if b != cbg.CborNull[0] { + if err := cr.UnreadByte(); err != nil { + return err + } + + sval, err := cbg.ReadStringWithMax(cr, 8192) + if err != nil { + return err + } + + t.Cursor = (*string)(&sval) + } + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *ListOKModel) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + fieldCount := 3 + + if t.Cursor == nil { + fieldCount-- + } + + if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil { + return err + } + + // t.Size (int64) (int64) + if len("size") > 8192 { + return xerrors.Errorf("Value in field \"size\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("size"))); err != nil { + return err + } + if _, err := cw.WriteString(string("size")); err != nil { + return err + } + + if t.Size >= 0 { + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Size)); err != nil { + return err + } + } else { + if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.Size-1)); err != nil { + return err + } + } + + // t.Cursor (string) (string) + if t.Cursor != nil { + + if len("cursor") > 8192 { + return xerrors.Errorf("Value in field \"cursor\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("cursor"))); err != nil { + return err + } + if _, err := cw.WriteString(string("cursor")); err != nil { + return err + } + + if t.Cursor == nil { + if _, err := cw.Write(cbg.CborNull); err != nil { + return err + } + } else { + if len(*t.Cursor) > 8192 { + return xerrors.Errorf("Value in field t.Cursor was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Cursor))); err != nil { + return err + } + if _, err := cw.WriteString(string(*t.Cursor)); err != nil { + return err + } + } + } + + // t.Results ([]cid.Cid) (slice) + if len("results") > 8192 { + return xerrors.Errorf("Value in field \"results\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("results"))); err != nil { + return err + } + if _, err := cw.WriteString(string("results")); err != nil { + return err + } + + if len(t.Results) > 8192 { + return xerrors.Errorf("Slice value in field t.Results was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Results))); err != nil { + return err + } + for _, v := range t.Results { + + if err := cbg.WriteCid(cw, v); err != nil { + return xerrors.Errorf("failed to write cid field v: %w", err) + } + + } + return nil +} + +func (t *ListOKModel) UnmarshalCBOR(r io.Reader) (err error) { + *t = ListOKModel{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("ListOKModel: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 7) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Size (int64) (int64) + case "size": + { + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + var extraI int64 + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative overflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.Size = int64(extraI) + } + // t.Cursor (string) (string) + case "cursor": + + { + b, err := cr.ReadByte() + if err != nil { + return err + } + if b != cbg.CborNull[0] { + if err := cr.UnreadByte(); err != nil { + return err + } + + sval, err := cbg.ReadStringWithMax(cr, 8192) + if err != nil { + return err + } + + t.Cursor = (*string)(&sval) + } + } + // t.Results ([]cid.Cid) (slice) + case "results": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 8192 { + return fmt.Errorf("t.Results: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.Results = make([]cid.Cid, extra) + } + + for i := 0; i < int(extra); i++ { + { + var maj byte + var extra uint64 + var err error + _ = maj + _ = extra + _ = err + + { + + c, err := cbg.ReadCid(cr) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Results[i]: %w", err) + } + + t.Results[i] = c + + } + + } + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} diff --git a/capabilities/upload/shard/datamodel/gen/main.go b/capabilities/upload/shard/datamodel/gen/main.go new file mode 100644 index 0000000..08f5db1 --- /dev/null +++ b/capabilities/upload/shard/datamodel/gen/main.go @@ -0,0 +1,22 @@ +//go:generate go run . + +package main + +import ( + jsg "github.com/alanshaw/dag-json-gen" + dm "github.com/fil-forge/libforge/capabilities/upload/shard/datamodel" + cbg "github.com/whyrusleeping/cbor-gen" +) + +func main() { + models := []any{ + dm.ListArgumentsModel{}, + dm.ListOKModel{}, + } + if err := cbg.WriteMapEncodersToFile("../cbor_gen.go", "datamodel", models...); err != nil { + panic(err) + } + if err := jsg.WriteMapEncodersToFile("../json_gen.go", "datamodel", models...); err != nil { + panic(err) + } +} diff --git a/capabilities/upload/shard/datamodel/json_gen.go b/capabilities/upload/shard/datamodel/json_gen.go new file mode 100644 index 0000000..5f0770e --- /dev/null +++ b/capabilities/upload/shard/datamodel/json_gen.go @@ -0,0 +1,443 @@ +// Code generated by github.com/alanshaw/dag-json-gen. DO NOT EDIT. + +package datamodel + +import ( + "errors" + "fmt" + "io" + "math" + "sort" + + jsg "github.com/alanshaw/dag-json-gen" + cid "github.com/ipfs/go-cid" +) + +var _ = cid.Undef +var _ = math.E +var _ = sort.Sort +var _ = errors.Is + +func (t *ListArgumentsModel) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.Cursor (string) (string) + if t.Cursor != nil { + if len("cursor") > 8192 { + return fmt.Errorf("string in field \"cursor\" was too long") + } + if err := jw.WriteString(string("cursor")); err != nil { + return fmt.Errorf("writing string for field \"cursor\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if t.Cursor == nil { + if err := jw.WriteNull(); err != nil { + return fmt.Errorf("writing null for field t.Cursor: %w", err) + } + } else { + if len(*t.Cursor) > 8192 { + return fmt.Errorf("string in field t.Cursor was too long") + } + if err := jw.WriteString(string(*t.Cursor)); err != nil { + return fmt.Errorf("writing string for field t.Cursor: %w", err) + } + } + written++ + } + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Root (cid.Cid) (struct) + if len("root") > 8192 { + return fmt.Errorf("string in field \"root\" was too long") + } + if err := jw.WriteString(string("root")); err != nil { + return fmt.Errorf("writing string for field \"root\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if err := jw.WriteCid(t.Root); err != nil { + return fmt.Errorf("writing CID for field t.Root: %w", err) + } + + written++ + if t.Size != nil { + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + } + + // t.Size (int64) (int64) + if t.Size != nil { + if len("size") > 8192 { + return fmt.Errorf("string in field \"size\" was too long") + } + if err := jw.WriteString(string("size")); err != nil { + return fmt.Errorf("writing string for field \"size\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if t.Size == nil { + if err := jw.WriteNull(); err != nil { + return fmt.Errorf("writing null for field t.Size: %w", err) + } + } else { + if err := jw.WriteInt64(int64(*t.Size)); err != nil { + return fmt.Errorf("writing int64 for field t.Size: %w", err) + } + } + + written++ + } + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *ListArgumentsModel) UnmarshalDagJSON(r io.Reader) (err error) { + *t = ListArgumentsModel{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for ListArgumentsModel: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for ListArgumentsModel: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for ListArgumentsModel: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field ListArgumentsModel: string too large") + } + return fmt.Errorf("reading string for field ListArgumentsModel: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field ListArgumentsModel: %w", err) + } + switch name { + + // t.Cursor (string) (string) + case "cursor": + { + sval, err := jr.ReadStringOrNull(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string or null for field t.Cursor: string too long") + } + return fmt.Errorf("reading string or null for field t.Cursor: %w", err) + } + if sval != nil { + t.Cursor = (*string)(sval) + } + } + + // t.Root (cid.Cid) (struct) + case "root": + { + + c, err := jr.ReadCid() + if err != nil { + return fmt.Errorf("reading CID for field t.Root: %w", err) + } + t.Root = c + + } + + // t.Size (int64) (int64) + case "size": + { + + nval, err := jr.ReadNumberAsInt64OrNull() + if err != nil { + return fmt.Errorf("reading int64 or null for field t.Size: %w", err) + } + if nval != nil { + typed := int64(*nval) + t.Size = &typed + } + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for ListArgumentsModel: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field ListArgumentsModel: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for ListArgumentsModel") + } + } + } + + return nil +} +func (t *ListOKModel) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.Cursor (string) (string) + if t.Cursor != nil { + if len("cursor") > 8192 { + return fmt.Errorf("string in field \"cursor\" was too long") + } + if err := jw.WriteString(string("cursor")); err != nil { + return fmt.Errorf("writing string for field \"cursor\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if t.Cursor == nil { + if err := jw.WriteNull(); err != nil { + return fmt.Errorf("writing null for field t.Cursor: %w", err) + } + } else { + if len(*t.Cursor) > 8192 { + return fmt.Errorf("string in field t.Cursor was too long") + } + if err := jw.WriteString(string(*t.Cursor)); err != nil { + return fmt.Errorf("writing string for field t.Cursor: %w", err) + } + } + written++ + } + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Results ([]cid.Cid) (slice) + if len("results") > 8192 { + return fmt.Errorf("string in field \"results\" was too long") + } + if err := jw.WriteString(string("results")); err != nil { + return fmt.Errorf("writing string for field \"results\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Results) > 8192 { + return fmt.Errorf("slice value in field t.Results was too long") + } + + if err := jw.WriteArrayOpen(); err != nil { + return fmt.Errorf("writing array open for field t.Results: %w", err) + } + for i, v := range t.Results { + if i > 0 { + if err := jw.WriteComma(); err != nil { + return fmt.Errorf("writing comma for field t.Results: %w", err) + } + } + + if err := jw.WriteCid(v); err != nil { + return fmt.Errorf("writing CID for field v: %w", err) + } + + } + if err := jw.WriteArrayClose(); err != nil { + return fmt.Errorf("writing array close for field t.Results: %w", err) + } + + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Size (int64) (int64) + if len("size") > 8192 { + return fmt.Errorf("string in field \"size\" was too long") + } + if err := jw.WriteString(string("size")); err != nil { + return fmt.Errorf("writing string for field \"size\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if err := jw.WriteInt64(int64(t.Size)); err != nil { + return fmt.Errorf("writing int64 for field t.Size: %w", err) + } + + written++ + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *ListOKModel) UnmarshalDagJSON(r io.Reader) (err error) { + *t = ListOKModel{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for ListOKModel: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for ListOKModel: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for ListOKModel: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field ListOKModel: string too large") + } + return fmt.Errorf("reading string for field ListOKModel: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field ListOKModel: %w", err) + } + switch name { + + // t.Cursor (string) (string) + case "cursor": + { + sval, err := jr.ReadStringOrNull(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string or null for field t.Cursor: string too long") + } + return fmt.Errorf("reading string or null for field t.Cursor: %w", err) + } + if sval != nil { + t.Cursor = (*string)(sval) + } + } + + // t.Results ([]cid.Cid) (slice) + case "results": + { + + if err := jr.ReadArrayOpen(); err != nil { + return fmt.Errorf("reading array open for field t.Results: %w", err) + } + + close, err := jr.PeekArrayClose() + if err != nil { + return fmt.Errorf("peeking array close for field t.Results: %w", err) + } + if close { + if err := jr.ReadArrayClose(); err != nil { + return fmt.Errorf("reading array close for field t.Results: %w", err) + } + + } else { + for i := 0; i < 8192; i++ { + item := make([]cid.Cid, 1) + { + + c, err := jr.ReadCid() + if err != nil { + return fmt.Errorf("reading CID for field item[0]: %w", err) + } + item[0] = c + + } + t.Results = append(t.Results, item[0]) + + close, err := jr.ReadArrayCloseOrComma() + if err != nil { + return fmt.Errorf("reading array close or comma for field t.Results: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("reading array for field t.Results: slice too large") + } + } + } + + } + + // t.Size (int64) (int64) + case "size": + { + + nval, err := jr.ReadNumberAsInt64() + if err != nil { + return fmt.Errorf("reading int64 for field t.Size: %w", err) + } + t.Size = int64(nval) + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for ListOKModel: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field ListOKModel: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for ListOKModel") + } + } + } + + return nil +} diff --git a/capabilities/upload/shard/datamodel/list.go b/capabilities/upload/shard/datamodel/list.go new file mode 100644 index 0000000..09b3e44 --- /dev/null +++ b/capabilities/upload/shard/datamodel/list.go @@ -0,0 +1,15 @@ +package datamodel + +import "github.com/ipfs/go-cid" + +type ListArgumentsModel struct { + Root cid.Cid `cborgen:"root" dagjsongen:"root"` + Cursor *string `cborgen:"cursor,omitempty" dagjsongen:"cursor,omitempty"` + Size *int64 `cborgen:"size,omitempty" dagjsongen:"size,omitempty"` +} + +type ListOKModel struct { + Cursor *string `cborgen:"cursor,omitempty" dagjsongen:"cursor,omitempty"` + Size int64 `cborgen:"size" dagjsongen:"size"` + Results []cid.Cid `cborgen:"results" dagjsongen:"results"` +} diff --git a/capabilities/upload/shard/list.go b/capabilities/upload/shard/list.go new file mode 100644 index 0000000..06481c8 --- /dev/null +++ b/capabilities/upload/shard/list.go @@ -0,0 +1,15 @@ +package shard + +import ( + dm "github.com/fil-forge/libforge/capabilities/upload/shard/datamodel" + "github.com/fil-forge/ucantone/validator/bindcap" +) + +const ListCommand = "/upload/shard/list" + +type ( + ListArguments = dm.ListArgumentsModel + ListOK = dm.ListOKModel +) + +var List, _ = bindcap.New[*ListArguments](ListCommand) diff --git a/go.mod b/go.mod index 8a6325a..b4fa2b2 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/fil-forge/libforge go 1.25.3 require ( - github.com/alanshaw/dag-json-gen v0.0.4 + github.com/alanshaw/dag-json-gen v0.0.5 github.com/fil-forge/ucantone v0.0.0-20260505091407-736de689fa66 github.com/ipfs/go-cid v0.6.1 github.com/ipfs/go-log/v2 v2.9.1 diff --git a/go.sum b/go.sum index 75e3e92..52abaa1 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/alanshaw/dag-json-gen v0.0.4 h1:qoryz04TVH6zu16NRFnzgolzQGaPfTvoIawv/F5rDoY= github.com/alanshaw/dag-json-gen v0.0.4/go.mod h1:rXxWw0SItP9QjxpRMpkju66h0KumF7TPCtvHdOKS5lY= +github.com/alanshaw/dag-json-gen v0.0.5 h1:jUOqsTrfZ7ddkBqAsx/xbCeJtpe70jrFL2Z+i4qQB1U= +github.com/alanshaw/dag-json-gen v0.0.5/go.mod h1:rXxWw0SItP9QjxpRMpkju66h0KumF7TPCtvHdOKS5lY= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fil-forge/ucantone v0.0.0-20260505091407-736de689fa66 h1:avaCKf+0prLhzkePMhmjis/OqBma0Aj8TDEAMZ3qbVY= diff --git a/jobqueue/jobqueue.go b/jobqueue/jobqueue.go new file mode 100644 index 0000000..6d7ba70 --- /dev/null +++ b/jobqueue/jobqueue.go @@ -0,0 +1,265 @@ +package jobqueue + +import ( + "context" + "errors" + "sync" + "time" +) + +// ErrQueueShutdown means the queue is shutdown so the job could not be queued +var ErrQueueShutdown = errors.New("queue is shutdown") + +type ( + // Option modifies the config of a JobQueue + Option func(*config) + + // Handler handles jobs of the given type + Handler[Job any] interface { + isHandler() + } + + // JobQueue is asyncronous queue for jobs, that can be processed in parallel + // by the job queue's handler + JobQueue[Job any] struct { + *config + handler Handler[Job] + incoming chan quitOrJob + closed chan struct{} + closing chan struct{} + } + + config struct { + jobTimeout time.Duration + shutdownTimeout time.Duration + errorHandler func(error) + buffer int + concurrency int + } + + quitOrJob interface { + isQuitOrJob() + } + + job[Job any] struct { + j Job + } + quit struct{} + + singleHandler[Job any] struct { + handler func(ctx context.Context, j Job) error + } + multiHandler[Job any] struct { + handler func(ctx context.Context, jobs []Job) error + } +) + +// WithBuffer allows a set amount of jobs to be buffered even if all workers are busy +func WithBuffer(buffer int) Option { + return func(c *config) { + c.buffer = buffer + } +} + +// WithConcurrency sets the number of workers that will process jobs in +// parallel +func WithConcurrency(concurrency int) Option { + return func(c *config) { + c.concurrency = concurrency + } +} + +// WithErrorHandler uses the given error handler whenever a job errors while processing +func WithErrorHandler(errorHandler func(error)) Option { + return func(c *config) { + c.errorHandler = errorHandler + } +} + +// WithJobTimeout cancels the past into context to the job handler after the specified +// timeout +func WithJobTimeout(jobTimeout time.Duration) Option { + return func(c *config) { + c.jobTimeout = jobTimeout + } +} + +// WithShutdownTimeout sets the shutdown timeout. When the queue is shutdown, the +// context passed to all job handlers will cancel after the specified timeout +func WithShutdownTimeout(shutdownTimeout time.Duration) Option { + return func(c *config) { + c.shutdownTimeout = shutdownTimeout + } +} + +func JobHandler[Job any](handler func(ctx context.Context, j Job) error) Handler[Job] { + return singleHandler[Job]{ + handler: handler, + } +} + +func MultiJobHandler[Job any](handler func(ctx context.Context, jobs []Job) error) Handler[Job] { + return multiHandler[Job]{ + handler: handler, + } +} + +// NewJobQueue returns a new job queue that processes with the given handler +func NewJobQueue[Job any](handler Handler[Job], opts ...Option) *JobQueue[Job] { + c := &config{ + concurrency: 1, + } + for _, opt := range opts { + opt(c) + } + return &JobQueue[Job]{ + config: c, + handler: handler, + incoming: make(chan quitOrJob), + closing: make(chan struct{}), + closed: make(chan struct{}), + } +} + +// Queue attempts to queue the job. It will fail if the queue is shutdown, or +// the passed context cancels before the job can be queued +func (p *JobQueue[Job]) Queue(ctx context.Context, j Job) error { + select { + case <-ctx.Done(): + return ctx.Err() + case <-p.closing: + return ErrQueueShutdown + case p.incoming <- job[Job]{j}: + return nil + } +} + +// Startup starts the queue in the background (returns immediately) +func (p *JobQueue[Job]) Startup() { + go p.run() +} + +// Shutdown shuts down the queue, returning when the whole queue is shutdown or +// the passed context cancels +func (p *JobQueue[Job]) Shutdown(ctx context.Context) error { + // signal the queue is closing -- this will cause anyone awaiting a queue + // to abort + close(p.closing) + // now get get a quit message into the incoming queue this will be the last + // message written in the queue but we also don't just close incoming cause it + // would cause a potential panic + p.incoming <- quit{} + // now wait for the go routines to complete + select { + case <-p.closed: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +func (p *JobQueue[Job]) run() { + // the queue is fully closed when this function completes + defer close(p.closed) + // outgoing will be used to consume jobs by the workers + outgoing := make(chan Job, p.buffer) + + // setup a cancellable context so that you can shut down all job + // executions when ready + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + var wg sync.WaitGroup + // spin up all workers + for range p.concurrency { + wg.Add(1) + go func() { + defer wg.Done() + p.worker(ctx, outgoing) + }() + } + + for { + // read the next message from the incoming queue + queued := <-p.incoming + switch typed := queued.(type) { + case job[Job]: + // if its a job, just send to the workers + outgoing <- typed.j + case quit: + // if it's a quit message, this is the last message we will receive + // so start the shutdown process + + // tell all the workers they're done processing jobs + close(outgoing) + // if there is a shut down timeout, queue a background routune to cancel + // the context (i.e. accelerate workers shutting down by the handler getting + // a shutdown context) + if p.shutdownTimeout != 0 { + timer := time.NewTimer(p.shutdownTimeout) + go func() { + <-timer.C + cancel() + }() + } + // wait for the workers to shutdown + wg.Wait() + return + } + } +} + +func (p *JobQueue[Job]) jobCtx(ctx context.Context) (context.Context, context.CancelFunc) { + if p.jobTimeout != 0 { + return context.WithTimeout(ctx, p.jobTimeout) + } + return context.WithCancel(ctx) +} + +func (p *JobQueue[Job]) handleJob(ctx context.Context, job Job, handler func(ctx context.Context, j Job) error) { + ctx, cancel := p.jobCtx(ctx) + defer cancel() + err := handler(ctx, job) + if err != nil && p.errorHandler != nil { + p.errorHandler(err) + } +} + +func (p *JobQueue[Job]) handleJobs(ctx context.Context, jobs []Job, handler func(ctx context.Context, jobs []Job) error) { + ctx, cancel := p.jobCtx(ctx) + defer cancel() + err := handler(ctx, jobs) + if err != nil && p.errorHandler != nil { + p.errorHandler(err) + } +} + +func (p *JobQueue[Job]) worker(ctx context.Context, jobs <-chan Job) { + for job := range jobs { + switch handler := p.handler.(type) { + case singleHandler[Job]: + p.handleJob(ctx, job, handler.handler) + case multiHandler[Job]: + toProcess := []Job{job} + readAvailable: + for { + select { + case job, ok := <-jobs: + if !ok { + break readAvailable + } + toProcess = append(toProcess, job) + default: + break readAvailable + } + } + p.handleJobs(ctx, toProcess, handler.handler) + } + } +} + +func (job[Job]) isQuitOrJob() {} +func (quit) isQuitOrJob() {} + +func (singleHandler[Job]) isHandler() {} +func (multiHandler[Job]) isHandler() {} diff --git a/jobqueue/jobqueue_test.go b/jobqueue/jobqueue_test.go new file mode 100644 index 0000000..cef2bf9 --- /dev/null +++ b/jobqueue/jobqueue_test.go @@ -0,0 +1,238 @@ +package jobqueue_test + +import ( + "context" + "slices" + "sync" + "testing" + "time" + + "github.com/fil-forge/libforge/jobqueue" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// Enqueues three jobs into a single-handler queue and verifies that all are processed before shutdown. +func TestJobQueueSingleHandlerBasic(t *testing.T) { + var mu sync.Mutex + processed := make([]int, 0) + + // Single handler that appends each job to a slice under a lock. + h := jobqueue.JobHandler(func(ctx context.Context, job int) error { + mu.Lock() + defer mu.Unlock() + processed = append(processed, job) + return nil + }) + + q := jobqueue.NewJobQueue[int](h) + q.Startup() + + ctx := context.Background() + require.NoError(t, q.Queue(ctx, 1)) + require.NoError(t, q.Queue(ctx, 2)) + require.NoError(t, q.Queue(ctx, 3)) + + shutdownCtx, cancel := context.WithTimeout(ctx, 3*time.Second) + defer cancel() + require.NoError(t, q.Shutdown(shutdownCtx)) + + // Check that all jobs have been processed + assert.ElementsMatch(t, []int{1, 2, 3}, processed) +} + +// Exercises concurrency by queueing multiple jobs in parallel with a concurrency level of 4. Verifies all jobs are handled +func TestJobQueueSingleHandlerConcurrency(t *testing.T) { + var mu sync.Mutex + var processed []int + + h := jobqueue.JobHandler(func(ctx context.Context, j int) error { + // Simulate random processing time + time.Sleep(5 * time.Millisecond) + mu.Lock() + defer mu.Unlock() + processed = append(processed, j) + return nil + }) + + q := jobqueue.NewJobQueue[int](h, + jobqueue.WithConcurrency(4), + ) + + q.Startup() + + ctx := context.Background() + jobCount := 20 + for i := 1; i <= jobCount; i++ { + require.NoError(t, q.Queue(ctx, i)) + } + + shutdownCtx, cancel := context.WithTimeout(ctx, 3*time.Second) + defer cancel() + require.NoError(t, q.Shutdown(shutdownCtx)) + + // We expect all jobs to be processed + require.Len(t, processed, jobCount, "expected all jobs to be processed") +} + +// Uses a multi-handler that reads all available jobs into a slice. Verifies that all jobs are seen in total. +func TestJobQueueMultiHandlerBasicBatching(t *testing.T) { + var mu sync.Mutex + var allBatches [][]int + + // multi handler that collects all the items that come in a batch + mh := jobqueue.MultiJobHandler(func(ctx context.Context, jobs []int) error { + mu.Lock() + defer mu.Unlock() + copied := make([]int, len(jobs)) + copy(copied, jobs) + allBatches = append(allBatches, copied) + return nil + }) + + q := jobqueue.NewJobQueue[int](mh, jobqueue.WithConcurrency(1)) + q.Startup() + + ctx := context.Background() + for i := 1; i <= 5; i++ { + require.NoError(t, q.Queue(ctx, i)) + } + + shutdownCtx, cancel := context.WithTimeout(ctx, 3*time.Second) + defer cancel() + + require.NoError(t, q.Shutdown(shutdownCtx)) + + // Because multiHandler tries to read all available jobs at once, we typically + // expect them all in a single batch, but it depends on scheduling. This test + // at least ensures we see all five in total. + foundItems := 0 + for _, batch := range allBatches { + foundItems += len(batch) + } + assert.Equal(t, 5, foundItems, "expecting total of 5 items processed in batches") +} + +// Verifies that queueing a job after calling Shutdown returns ErrQueueShutdown +func TestJobQueueQueueShutdown(t *testing.T) { + h := jobqueue.JobHandler(func(ctx context.Context, j int) error { + return nil + }) + + q := jobqueue.NewJobQueue[int](h) + q.Startup() + + ctx := context.Background() + require.NoError(t, q.Queue(ctx, 42)) + + shutdownCtx, cancel := context.WithTimeout(ctx, time.Second) + defer cancel() + require.NoError(t, q.Shutdown(shutdownCtx)) + + // After shutdown, queueing a job should fail with ErrQueueShutdown + err := q.Queue(ctx, 99) + assert.ErrorIs(t, err, jobqueue.ErrQueueShutdown) +} + +// Verifies that if the context is canceled before calling Queue, the call returns context.Canceled. +func TestJobQueueContextCancellation(t *testing.T) { + h := jobqueue.JobHandler(func(ctx context.Context, job int) error { + return nil + }) + + q := jobqueue.NewJobQueue[int](h) + q.Startup() + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + // queueing after the context is canceled + err := q.Queue(ctx, 123) + require.Error(t, err) + assert.ErrorIs(t, err, context.Canceled) +} + +// Demonstrates buffering behavior. The queue is given a small concurrency level (1) but a buffer of 2. +// We enqueue 4 jobs, confirming that after the first 3 are accepted, the fourth must wait until the queue has capacity, +// and eventually, all 4 get processed +func TestJobQueueBuffer(t *testing.T) { + var mu sync.Mutex + var processed []int + + h := jobqueue.JobHandler(func(ctx context.Context, j int) error { + time.Sleep(50 * time.Millisecond) + mu.Lock() + defer mu.Unlock() + processed = append(processed, j) + return nil + }) + + q := jobqueue.NewJobQueue[int](h, + jobqueue.WithBuffer(2), + jobqueue.WithConcurrency(1), + ) + + q.Startup() + + ctx := context.Background() + // We push more jobs than concurrency. The buffer is 2, so total of 3 can be + // queued at once (one actively processed, 2 in the channel). + for i := 0; i <= 2; i++ { + require.NoError(t, q.Queue(ctx, i)) + } + + // This next queue operation should block until at least one job is processed + // or context canceled. We'll do it in a separate goroutine with a short delay. + var queueErr error + var wg sync.WaitGroup + wg.Add(1) + go func() { + queueErr = q.Queue(ctx, 99) + wg.Done() + }() + + wg.Wait() + + shutdownCtx, cancel := context.WithTimeout(ctx, 4*time.Second) + defer cancel() + assert.NoError(t, q.Shutdown(shutdownCtx), "queue shut down should be successful") + + // The queueErr must not be an error at this point; the capacity eventually + // freed up and job #99 was queued + assert.NoError(t, queueErr) + + // We expect all 4 jobs to eventually be processed + assert.Len(t, processed, 4, "all jobs should have processed") +} + +func TestJobQueueStress(t *testing.T) { + ctx := context.Background() + var mu sync.Mutex + var processed []int + + h := jobqueue.JobHandler(func(ctx context.Context, j int) error { + time.Sleep(1 * time.Millisecond) + mu.Lock() + defer mu.Unlock() + processed = append(processed, j) + return nil + }) + + q := jobqueue.NewJobQueue[int](h, + jobqueue.WithBuffer(5), + jobqueue.WithConcurrency(5), + ) + + q.Startup() + + for i := range 10_000 { + require.NoError(t, q.Queue(ctx, i)) + } + + require.NoError(t, q.Shutdown(ctx)) + + require.Equal(t, len(processed), 10_000) + for i := range 10_000 { + require.True(t, slices.Contains(processed, i)) + } +} diff --git a/ucan/attestations.go b/ucan/attestations.go new file mode 100644 index 0000000..d7753f7 --- /dev/null +++ b/ucan/attestations.go @@ -0,0 +1,54 @@ +package ucanlib + +import ( + "context" + "fmt" + "iter" + + "github.com/fil-forge/libforge/capabilities/ucan/attest" + "github.com/fil-forge/ucantone/ucan" + "github.com/fil-forge/ucantone/varsig/algorithm/nonstandard" + "github.com/ipfs/go-cid" +) + +// InvocationListerFunc lists invocations that match EXACTLY the given audience, +// command, and subject. +type InvocationListerFunc func(ctx context.Context, aud ucan.Principal, cmd ucan.Command, sub ucan.Subject) iter.Seq2[ucan.Invocation, error] + +// ProofAttestations returns a list of attestations for proofs that need them. +// i.e. if a proof is signed with a non-standard signature this function will +// fetch an attestation for it, and fail if it cannot. The authority parameter +// is the DID of the service we trust to be issuing attestations. +func ProofAttestations(ctx context.Context, listInvocations InvocationListerFunc, proofs []ucan.Delegation, authority ucan.Principal) ([]ucan.Invocation, error) { + var attestations []ucan.Invocation + for _, proof := range proofs { + if proof.Signature().Header().SignatureAlgorithm().Code() != nonstandard.Code { + continue + } + var attestation ucan.Invocation + for inv, err := range listInvocations(ctx, proof.Audience(), attest.ProofCommand, authority) { + if err != nil { + return nil, fmt.Errorf("listing invocations for proof signed by %q: %w", proof.Issuer().DID(), err) + } + // unlikely since all attestations should be self-signed by the authority + if inv.Issuer().DID() != authority.DID() { + continue + } + if ucan.IsExpired(inv) { + continue + } + // ensure this attestation corresponds to the proof + attestedProof, ok := inv.Arguments()["proof"].(cid.Cid) + if !ok || attestedProof != proof.Link() { + continue + } + attestation = inv + break + } + if attestation == nil { + return nil, fmt.Errorf("no attestation found for proof signed by %q", proof.Issuer().DID()) + } + attestations = append(attestations, attestation) + } + return attestations, nil +} diff --git a/ucan/attestations_test.go b/ucan/attestations_test.go new file mode 100644 index 0000000..5c2c329 --- /dev/null +++ b/ucan/attestations_test.go @@ -0,0 +1,181 @@ +package ucanlib_test + +import ( + "context" + "errors" + "iter" + "testing" + + "github.com/fil-forge/libforge/capabilities/ucan/attest" + "github.com/fil-forge/libforge/didmailto" + "github.com/fil-forge/libforge/testutil" + ucanlib "github.com/fil-forge/libforge/ucan" + "github.com/fil-forge/ucantone/principal/absentee" + "github.com/fil-forge/ucantone/ucan" + "github.com/fil-forge/ucantone/ucan/command" + "github.com/fil-forge/ucantone/ucan/delegation" + "github.com/fil-forge/ucantone/ucan/invocation" + "github.com/stretchr/testify/require" +) + +// recordedCall captures arguments passed to a stub AttestationGetterFunc. +type recordedCall struct { + aud ucan.Principal + cmd ucan.Command + sub ucan.Subject +} + +// stubAttestationLister returns an AttestationGetterFunc that produces a fresh +// attestation invocation per call (signed by authority) and records each call. +func stubAttestationLister(authority ucan.Signer, proofs []ucan.Link, calls *[]recordedCall) ucanlib.InvocationListerFunc { + i := 0 + return func(ctx context.Context, aud ucan.Principal, cmd ucan.Command, sub ucan.Subject) iter.Seq2[ucan.Invocation, error] { + *calls = append(*calls, recordedCall{aud: aud, cmd: cmd, sub: sub}) + return func(yield func(ucan.Invocation, error) bool) { + if i >= len(proofs) { + return + } + inv, err := attest.Proof.Invoke( + authority, + sub, + &attest.ProofArguments{Proof: proofs[i]}, + invocation.WithAudience(aud), + ) + if err != nil { + yield(nil, err) + return + } + yield(inv, nil) + i++ + } + } +} + +func TestProofAttestations(t *testing.T) { + t.Run("no proofs", func(t *testing.T) { + service := testutil.WebService + var calls []recordedCall + lister := stubAttestationLister(service, nil, &calls) + + attestations, err := ucanlib.ProofAttestations(t.Context(), lister, nil, service) + require.NoError(t, err) + require.Empty(t, attestations) + require.Empty(t, calls) + }) + + t.Run("standard signatures only", func(t *testing.T) { + service := testutil.WebService + space := testutil.RandomSigner(t) + alice := testutil.Alice + cmd := testutil.Must(command.Parse("/test/do"))(t) + + // ed25519-signed proof — should be filtered out (no attestation needed). + dlg := testutil.Must(delegation.Delegate(space, alice, space, cmd))(t) + + var calls []recordedCall + lister := stubAttestationLister(service, nil, &calls) + + attestations, err := ucanlib.ProofAttestations(t.Context(), lister, []ucan.Delegation{dlg}, service) + require.NoError(t, err) + require.Empty(t, attestations) + require.Empty(t, calls, "lister should not be called for standard signatures") + }) + + t.Run("absentee-signed proof", func(t *testing.T) { + service := testutil.WebService + mailtoDID := testutil.Must(didmailto.New("alice@example.com"))(t) + account := absentee.From(mailtoDID) + agent := testutil.Alice + space := testutil.RandomSigner(t) + cmd := testutil.Must(command.Parse("/test/do"))(t) + + // account (absentee, did:mailto) → agent — this proof needs an attestation. + dlg := testutil.Must(delegation.Delegate(account, agent, space, cmd))(t) + + var calls []recordedCall + lister := stubAttestationLister(service, []ucan.Link{dlg.Link()}, &calls) + + attestations, err := ucanlib.ProofAttestations(t.Context(), lister, []ucan.Delegation{dlg}, service) + require.NoError(t, err) + require.Len(t, attestations, 1) + require.Len(t, calls, 1) + + // Lister should be called with the proof's audience, the /ucan/attest/proof + // command, and the authority as subject. + require.Equal(t, agent.DID(), calls[0].aud.DID()) + require.Equal(t, ucan.Command(attest.ProofCommand), calls[0].cmd) + require.Equal(t, service.DID(), calls[0].sub.DID()) + }) + + t.Run("mixed standard and absentee proofs", func(t *testing.T) { + service := testutil.WebService + mailtoDID := testutil.Must(didmailto.New("alice@example.com"))(t) + account := absentee.From(mailtoDID) + agent := testutil.Alice + bob := testutil.Bob + space := testutil.RandomSigner(t) + cmd := testutil.Must(command.Parse("/test/do"))(t) + + // standard signature — no attestation needed + standardDlg := testutil.Must(delegation.Delegate(space, bob, space, cmd))(t) + // absentee signature — needs attestation + absenteeDlg := testutil.Must(delegation.Delegate(account, agent, space, cmd))(t) + + var calls []recordedCall + lister := stubAttestationLister(service, []ucan.Link{absenteeDlg.Link()}, &calls) + + attestations, err := ucanlib.ProofAttestations(t.Context(), lister, []ucan.Delegation{standardDlg, absenteeDlg}, service) + require.NoError(t, err) + require.Len(t, attestations, 1, "only the absentee-signed proof needs an attestation") + require.Len(t, calls, 1) + require.Equal(t, agent.DID(), calls[0].aud.DID()) + }) + + t.Run("multiple absentee-signed proofs", func(t *testing.T) { + service := testutil.WebService + aliceMailto := testutil.Must(didmailto.New("alice@example.com"))(t) + bobMailto := testutil.Must(didmailto.New("bob@example.com"))(t) + aliceAccount := absentee.From(aliceMailto) + bobAccount := absentee.From(bobMailto) + + agentA := testutil.Alice + agentB := testutil.Bob + space := testutil.RandomSigner(t) + cmd := testutil.Must(command.Parse("/test/do"))(t) + + dlgA := testutil.Must(delegation.Delegate(aliceAccount, agentA, space, cmd))(t) + dlgB := testutil.Must(delegation.Delegate(bobAccount, agentB, space, cmd))(t) + + var calls []recordedCall + lister := stubAttestationLister(service, []ucan.Link{dlgA.Link(), dlgB.Link()}, &calls) + + attestations, err := ucanlib.ProofAttestations(t.Context(), lister, []ucan.Delegation{dlgA, dlgB}, service) + require.NoError(t, err) + require.Len(t, attestations, 2) + require.Len(t, calls, 2) + require.Equal(t, agentA.DID(), calls[0].aud.DID()) + require.Equal(t, agentB.DID(), calls[1].aud.DID()) + }) + + t.Run("lister error is propagated", func(t *testing.T) { + service := testutil.WebService + mailtoDID := testutil.Must(didmailto.New("alice@example.com"))(t) + account := absentee.From(mailtoDID) + agent := testutil.Alice + space := testutil.RandomSigner(t) + cmd := testutil.Must(command.Parse("/test/do"))(t) + + dlg := testutil.Must(delegation.Delegate(account, agent, space, cmd))(t) + + wantErr := errors.New("boom") + lister := func(ctx context.Context, aud ucan.Principal, cmd ucan.Command, sub ucan.Subject) iter.Seq2[ucan.Invocation, error] { + return func(yield func(ucan.Invocation, error) bool) { + yield(nil, wantErr) + } + } + + attestations, err := ucanlib.ProofAttestations(t.Context(), lister, []ucan.Delegation{dlg}, service) + require.ErrorIs(t, err, wantErr) + require.Nil(t, attestations) + }) +} diff --git a/ucan/proof_chain.go b/ucan/proof_chain.go index 8a8bd60..9c26d81 100644 --- a/ucan/proof_chain.go +++ b/ucan/proof_chain.go @@ -9,60 +9,56 @@ import ( "github.com/fil-forge/ucantone/ucan/command" ) -type DelegationMatcher interface { - // Match finds delegations matching the given audience, command, and subject. - // Note: subject MUST not be nil. Matching delegations MAY include powerline - // delegations (with nil subject) and delegations where command is a matching - // parent of the passed command. - Match(ctx context.Context, aud ucan.Principal, cmd ucan.Command, sub ucan.Subject) iter.Seq2[ucan.Delegation, error] -} - -type DelegationFinder interface { - // FindByAudienceCommandSubject retrieves delegations for the given audience, - // command, and subject. Note: subject MAY be nil to indicate powerline. - FindByAudienceCommandSubject(ctx context.Context, aud ucan.Principal, cmd ucan.Command, sub ucan.Subject) iter.Seq2[ucan.Delegation, error] -} +// DelegationMatcherFunc finds all delegations matching the given audience, +// command, and subject. +// +// The subject parameter MUST not be nil, but matching delegations MAY include +// powerline delegations (with nil subject) and delegations where command is a +// matching parent of the passed command e.g. if passed command is "/read/file", +// delegations with command "/read", and "/" may be returned. +type DelegationMatcherFunc func(ctx context.Context, aud ucan.Principal, cmd ucan.Command, sub ucan.Subject) iter.Seq2[ucan.Delegation, error] -type FinderDelegationMatcher struct { - finder DelegationFinder -} +// DelegationListerFunc lists delegations for the given audience, command, and +// subject. It differs from [DelegationMatcherFunc] in that it only retrieves +// delegations for the EXACT audience, command and subject. +// +// Note: the subject parameter MAY be nil to indicate powerline. +type DelegationListerFunc func(ctx context.Context, aud ucan.Principal, cmd ucan.Command, sub ucan.Subject) iter.Seq2[ucan.Delegation, error] // NewDelegationMatcher creates a simple delegation matcher that queries the // passed finder to retrieve delegations matching the given audience, command, // and subject. -func NewDelegationMatcher(finder DelegationFinder) *FinderDelegationMatcher { - return &FinderDelegationMatcher{finder: finder} -} - -func (gm *FinderDelegationMatcher) Match(ctx context.Context, aud ucan.Principal, cmd ucan.Command, sub ucan.Principal) iter.Seq2[ucan.Delegation, error] { - return func(yield func(ucan.Delegation, error) bool) { - cmdVariations := []ucan.Command{} - segs := cmd.Segments() - for i := len(segs) - 1; i >= 0; i-- { - cmd := command.Top().Join(segs[0 : i+1]...) - cmdVariations = append(cmdVariations, cmd) - } - cmdVariations = append(cmdVariations, command.Top()) - - for _, cmd := range cmdVariations { - for dlg, err := range gm.finder.FindByAudienceCommandSubject(ctx, aud, cmd, sub) { - if err != nil { - yield(nil, err) - return - } - if !yield(dlg, nil) { - return - } +func NewDelegationMatcher(listDelegations DelegationListerFunc) DelegationMatcherFunc { + return func(ctx context.Context, aud ucan.Principal, cmd ucan.Command, sub ucan.Principal) iter.Seq2[ucan.Delegation, error] { + return func(yield func(ucan.Delegation, error) bool) { + cmdVariations := []ucan.Command{} + segs := cmd.Segments() + for i := len(segs) - 1; i >= 0; i-- { + cmd := command.Top().Join(segs[0 : i+1]...) + cmdVariations = append(cmdVariations, cmd) } - // try powerline - // TODO: stop early if we already found delegations? - for dlg, err := range gm.finder.FindByAudienceCommandSubject(ctx, aud, cmd, nil) { - if err != nil { - yield(nil, err) - return + cmdVariations = append(cmdVariations, command.Top()) + + for _, cmd := range cmdVariations { + for dlg, err := range listDelegations(ctx, aud, cmd, sub) { + if err != nil { + yield(nil, err) + return + } + if !yield(dlg, nil) { + return + } } - if !yield(dlg, nil) { - return + // try powerline + // TODO: stop early if we already found delegations? + for dlg, err := range listDelegations(ctx, aud, cmd, nil) { + if err != nil { + yield(nil, err) + return + } + if !yield(dlg, nil) { + return + } } } } @@ -75,8 +71,8 @@ func (gm *FinderDelegationMatcher) Match(ctx context.Context, aud ucan.Principal // invocation. i.e. starting from the root Delegation (issued by the Subject), // in strict sequence where the aud of the previous Delegation matches the iss // of the next Delegation. -func ProofChain(ctx context.Context, matcher DelegationMatcher, aud ucan.Principal, cmd ucan.Command, sub ucan.Principal) ([]ucan.Delegation, []ucan.Link, error) { - proofs, links, err := proofChain(ctx, matcher, aud, cmd, sub) +func ProofChain(ctx context.Context, matchDelegations DelegationMatcherFunc, aud ucan.Principal, cmd ucan.Command, sub ucan.Principal) ([]ucan.Delegation, []ucan.Link, error) { + proofs, links, err := proofChain(ctx, matchDelegations, aud, cmd, sub) if err != nil { return nil, nil, err } @@ -88,11 +84,11 @@ func ProofChain(ctx context.Context, matcher DelegationMatcher, aud ucan.Princip // proofChain returns the delegations and links from the audience toward the // subject, i.e. in reverse of the invocation order. [ProofChain] reverses the // result before returning it to the caller. -func proofChain(ctx context.Context, matcher DelegationMatcher, aud ucan.Principal, cmd ucan.Command, sub ucan.Principal) ([]ucan.Delegation, []ucan.Link, error) { +func proofChain(ctx context.Context, matchDelegations DelegationMatcherFunc, aud ucan.Principal, cmd ucan.Command, sub ucan.Principal) ([]ucan.Delegation, []ucan.Link, error) { var proofs []ucan.Delegation var links []ucan.Link - for d, err := range matcher.Match(ctx, aud, cmd, sub) { + for d, err := range matchDelegations(ctx, aud, cmd, sub) { if err != nil { return nil, nil, err } @@ -102,7 +98,7 @@ func proofChain(ctx context.Context, matcher DelegationMatcher, aud ucan.Princip break } // if subject is nil, or subject != issuer, we need more proof - ps, ls, err := proofChain(ctx, matcher, d.Issuer(), d.Command(), sub) + ps, ls, err := proofChain(ctx, matchDelegations, d.Issuer(), d.Command(), sub) if err != nil { return nil, nil, err } diff --git a/ucan/proof_chain_test.go b/ucan/proof_chain_test.go index b4bf21c..c28f13b 100644 --- a/ucan/proof_chain_test.go +++ b/ucan/proof_chain_test.go @@ -14,12 +14,12 @@ import ( "github.com/stretchr/testify/require" ) -// memFinder is an in-memory [ucanlib.DelegationFinder] for tests. -type memFinder struct { +// memLister is an in-memory [ucanlib.DelegationLister] for tests. +type memLister struct { delegations []ucan.Delegation } -func (f *memFinder) FindByAudienceCommandSubject(ctx context.Context, aud ucan.Principal, cmd ucan.Command, sub ucan.Subject) iter.Seq2[ucan.Delegation, error] { +func (f *memLister) List(ctx context.Context, aud ucan.Principal, cmd ucan.Command, sub ucan.Subject) iter.Seq2[ucan.Delegation, error] { return func(yield func(ucan.Delegation, error) bool) { for _, d := range f.delegations { if d.Audience().DID() != aud.DID() { @@ -44,10 +44,10 @@ func (f *memFinder) FindByAudienceCommandSubject(ctx context.Context, aud ucan.P } } -// erroringFinder yields a single error from the iterator. -type erroringFinder struct{ err error } +// erroringLister yields a single error from the iterator. +type erroringLister struct{ err error } -func (f *erroringFinder) FindByAudienceCommandSubject(ctx context.Context, aud ucan.Principal, cmd ucan.Command, sub ucan.Subject) iter.Seq2[ucan.Delegation, error] { +func (f *erroringLister) List(ctx context.Context, aud ucan.Principal, cmd ucan.Command, sub ucan.Subject) iter.Seq2[ucan.Delegation, error] { return func(yield func(ucan.Delegation, error) bool) { yield(nil, f.err) } @@ -71,8 +71,8 @@ func TestProofChain_SelfIssued(t *testing.T) { // space delegates to alice (root of chain, subject is the space). root := testutil.Must(delegation.Delegate(space, alice, space, cmd))(t) - finder := &memFinder{delegations: []ucan.Delegation{root}} - matcher := ucanlib.NewDelegationMatcher(finder) + finder := &memLister{delegations: []ucan.Delegation{root}} + matcher := ucanlib.NewDelegationMatcher(finder.List) proofs, links, err := ucanlib.ProofChain(t.Context(), matcher, alice, cmd, space) require.NoError(t, err) @@ -93,8 +93,8 @@ func TestProofChain_MultiHop(t *testing.T) { // bob → carol (re-delegates the space's authority) bc := testutil.Must(delegation.Delegate(bob, carol, space, cmd))(t) - finder := &memFinder{delegations: []ucan.Delegation{sa, ab, bc}} - matcher := ucanlib.NewDelegationMatcher(finder) + finder := &memLister{delegations: []ucan.Delegation{sa, ab, bc}} + matcher := ucanlib.NewDelegationMatcher(finder.List) proofs, links, err := ucanlib.ProofChain(t.Context(), matcher, carol, cmd, space) require.NoError(t, err) @@ -107,7 +107,7 @@ func TestProofChain_NoDelegations(t *testing.T) { alice := testutil.Alice cmd := testutil.Must(command.Parse("/test/do"))(t) - matcher := ucanlib.NewDelegationMatcher(&memFinder{}) + matcher := ucanlib.NewDelegationMatcher((&memLister{}).List) proofs, links, err := ucanlib.ProofChain(t.Context(), matcher, alice, cmd, space) require.NoError(t, err) require.Empty(t, proofs) @@ -123,8 +123,8 @@ func TestProofChain_BrokenChain(t *testing.T) { // alice → bob exists, but no space → alice root. ab := testutil.Must(delegation.Delegate(alice, bob, space, cmd))(t) - finder := &memFinder{delegations: []ucan.Delegation{ab}} - matcher := ucanlib.NewDelegationMatcher(finder) + finder := &memLister{delegations: []ucan.Delegation{ab}} + matcher := ucanlib.NewDelegationMatcher(finder.List) proofs, links, err := ucanlib.ProofChain(t.Context(), matcher, bob, cmd, space) require.NoError(t, err) @@ -141,8 +141,8 @@ func TestProofChain_ParentCommand(t *testing.T) { // space delegates to alice for the parent command. root := testutil.Must(delegation.Delegate(space, alice, space, parent))(t) - finder := &memFinder{delegations: []ucan.Delegation{root}} - matcher := ucanlib.NewDelegationMatcher(finder) + finder := &memLister{delegations: []ucan.Delegation{root}} + matcher := ucanlib.NewDelegationMatcher(finder.List) // Invocation for the child command should still resolve via the parent. proofs, links, err := ucanlib.ProofChain(t.Context(), matcher, alice, child, space) @@ -161,8 +161,8 @@ func TestProofChain_Powerline(t *testing.T) { // powerline: alice → bob with nil subject. powerline := testutil.Must(delegation.Delegate(alice, bob, nil, cmd))(t) - finder := &memFinder{delegations: []ucan.Delegation{root, powerline}} - matcher := ucanlib.NewDelegationMatcher(finder) + finder := &memLister{delegations: []ucan.Delegation{root, powerline}} + matcher := ucanlib.NewDelegationMatcher(finder.List) proofs, links, err := ucanlib.ProofChain(t.Context(), matcher, bob, cmd, space) require.NoError(t, err) @@ -178,8 +178,8 @@ func TestProofChain_UnrelatedCommandIgnored(t *testing.T) { // delegation exists but for an unrelated command path. dlg := testutil.Must(delegation.Delegate(space, alice, space, other))(t) - finder := &memFinder{delegations: []ucan.Delegation{dlg}} - matcher := ucanlib.NewDelegationMatcher(finder) + finder := &memLister{delegations: []ucan.Delegation{dlg}} + matcher := ucanlib.NewDelegationMatcher(finder.List) proofs, links, err := ucanlib.ProofChain(t.Context(), matcher, alice, cmd, space) require.NoError(t, err) @@ -193,7 +193,13 @@ func TestProofChain_FinderError(t *testing.T) { cmd := testutil.Must(command.Parse("/test/do"))(t) wantErr := errors.New("boom") - matcher := ucanlib.NewDelegationMatcher(&erroringFinder{err: wantErr}) + matcher := ucanlib.NewDelegationMatcher( + func(ctx context.Context, aud ucan.Principal, cmd ucan.Command, sub ucan.Subject) iter.Seq2[ucan.Delegation, error] { + return func(yield func(ucan.Delegation, error) bool) { + yield(nil, wantErr) + } + }, + ) _, _, err := ucanlib.ProofChain(t.Context(), matcher, alice, cmd, space) require.ErrorIs(t, err, wantErr)