From a049aee715462b7229fccf45d68c2b982dfc922a Mon Sep 17 00:00:00 2001 From: Will Scott Date: Wed, 9 Aug 2023 14:48:02 +0100 Subject: [PATCH] When making a map iterator over a directory, calls to `.Next()` currently return a value of the `FieldHash()` of the dagpb link. This change has them instead return a `IterLink`. In both cases, the "exposed" interface of the returned type, `AsLink()` exposes the underlying hash cidLink to the entry. By using a wrapping `IterLink` type, we provide an opportunity to type-cast the response, and instead of treating the response under it's returned `ipld.Node` interface, the client has the ability to do something of the form: ``` k, next, err := iterator.Next() nextSize := next.(*iter.IterLink).Substrate.FieldSize() ``` --- iter/iter.go | 4 +-- iter/iterlink.go | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 iter/iterlink.go diff --git a/iter/iter.go b/iter/iter.go index 3be099d..5c76a0c 100644 --- a/iter/iter.go +++ b/iter/iter.go @@ -37,7 +37,7 @@ func (itr *UnixFSDir__MapItr) Next() (k ipld.Node, v ipld.Node, err error) { if itr.transformName != nil { name = itr.transformName(name) } - return name, next.FieldHash(), nil + return name, &IterLink{next}, nil } nb := dagpb.Type.String.NewBuilder() err = nb.AssignString("") @@ -45,7 +45,7 @@ func (itr *UnixFSDir__MapItr) Next() (k ipld.Node, v ipld.Node, err error) { return nil, nil, err } s := nb.Build() - return s, next.FieldHash(), nil + return s, &IterLink{next}, nil } func (itr *UnixFSDir__MapItr) Done() bool { diff --git a/iter/iterlink.go b/iter/iterlink.go new file mode 100644 index 0000000..50aecef --- /dev/null +++ b/iter/iterlink.go @@ -0,0 +1,67 @@ +package iter + +import ( + dagpb "github.com/ipld/go-codec-dagpb" + "github.com/ipld/go-ipld-prime/datamodel" + basicnode "github.com/ipld/go-ipld-prime/node/basic" +) + +type IterLink struct { + Substrate dagpb.PBLink +} + +func (il *IterLink) AsBool() (bool, error) { + return false, datamodel.ErrWrongKind{} +} +func (il *IterLink) AsBytes() ([]byte, error) { + return nil, datamodel.ErrWrongKind{} +} +func (il *IterLink) AsFloat() (float64, error) { + return 0.0, datamodel.ErrWrongKind{} +} +func (il *IterLink) AsInt() (int64, error) { + return 0, datamodel.ErrWrongKind{} +} +func (il *IterLink) AsLink() (datamodel.Link, error) { + return il.Substrate.FieldHash().AsLink() +} +func (il *IterLink) AsString() (string, error) { + return "", datamodel.ErrWrongKind{} +} + +func (il *IterLink) IsAbsent() bool { + return il.Substrate.IsAbsent() +} +func (il *IterLink) IsNull() bool { + return il.Substrate.IsNull() +} +func (il *IterLink) Kind() datamodel.Kind { + return datamodel.Kind_Link +} +func (il *IterLink) Length() int64 { + return 0 +} +func (il *IterLink) ListIterator() datamodel.ListIterator { + return nil +} +func (il *IterLink) LookupByIndex(idx int64) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{} +} +func (il *IterLink) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{} +} +func (il *IterLink) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{} +} +func (il *IterLink) LookupByString(key string) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{} +} +func (il *IterLink) MapIterator() datamodel.MapIterator { + return nil +} +func (il *IterLink) Prototype() datamodel.NodePrototype { + return basicnode.Prototype__Link{} +} +func (il *IterLink) Representation() datamodel.Node { + return il +}