meta,args: add missing Include, add iterator to use normal or Readonly the same way

This commit is contained in:
Michael Muré
2024-11-20 18:27:01 +01:00
parent 4ec409edc6
commit caae2f58bf
7 changed files with 206 additions and 18 deletions

View File

@@ -5,6 +5,7 @@ package args
import (
"fmt"
"iter"
"sort"
"strings"
@@ -54,21 +55,36 @@ func (a *Args) Add(key string, val any) error {
return nil
}
type Iterator interface {
Iter() iter.Seq2[string, ipld.Node]
}
// Include merges the provided arguments into the existing arguments.
//
// If duplicate keys are encountered, the new value is silently dropped
// without causing an error.
func (a *Args) Include(other *Args) {
for _, key := range other.Keys {
func (a *Args) Include(other Iterator) {
for key, value := range other.Iter() {
if _, ok := a.Values[key]; ok {
// don't overwrite
continue
}
a.Values[key] = other.Values[key]
a.Values[key] = value
a.Keys = append(a.Keys, key)
}
}
// Iter iterates over the args key/values
func (a *Args) Iter() iter.Seq2[string, ipld.Node] {
return func(yield func(string, ipld.Node) bool) {
for _, key := range a.Keys {
if !yield(key, a.Values[key]) {
return
}
}
}
}
// ToIPLD wraps an instance of an Args with an ipld.Node.
func (a *Args) ToIPLD() (ipld.Node, error) {
sort.Strings(a.Keys)

View File

@@ -1,6 +1,7 @@
package args_test
import (
"maps"
"sync"
"testing"
@@ -8,6 +9,7 @@ import (
"github.com/ipld/go-ipld-prime"
"github.com/ipld/go-ipld-prime/codec/dagcbor"
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/node/basicnode"
"github.com/ipld/go-ipld-prime/schema"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -133,6 +135,56 @@ func TestArgs_Include(t *testing.T) {
assert.Equal(t, "val4", must(argsIn.Values["key4"].AsString()))
}
func TestIterCloneEquals(t *testing.T) {
a := args.New()
require.NoError(t, a.Add("foo", "bar"))
require.NoError(t, a.Add("baz", 1234))
expected := map[string]ipld.Node{
"foo": basicnode.NewString("bar"),
"baz": basicnode.NewInt(1234),
}
// args -> iter
require.Equal(t, expected, maps.Collect(a.Iter()))
// readonly -> iter
ro := a.ReadOnly()
require.Equal(t, expected, maps.Collect(ro.Iter()))
// args -> clone -> iter
clone := a.Clone()
require.Equal(t, expected, maps.Collect(clone.Iter()))
// readonly -> WriteableClone -> iter
wclone := ro.WriteableClone()
require.Equal(t, expected, maps.Collect(wclone.Iter()))
require.True(t, a.Equals(wclone))
require.True(t, ro.Equals(wclone.ReadOnly()))
}
func TestInclude(t *testing.T) {
a1 := args.New()
require.NoError(t, a1.Add("samekey", "bar"))
require.NoError(t, a1.Add("baz", 1234))
a2 := args.New()
require.NoError(t, a2.Add("samekey", "othervalue")) // check no overwrite
require.NoError(t, a2.Add("otherkey", 1234))
a1.Include(a2)
require.Equal(t, map[string]ipld.Node{
"samekey": basicnode.NewString("bar"),
"baz": basicnode.NewInt(1234),
"otherkey": basicnode.NewInt(1234),
}, maps.Collect(a1.Iter()))
}
const (
argsSchema = "type Args { String : Any }"
argsName = "Args"

View File

@@ -1,17 +1,25 @@
package args
import "github.com/ipld/go-ipld-prime"
import (
"iter"
"github.com/ipld/go-ipld-prime"
)
type ReadOnly struct {
args *Args
}
func (r ReadOnly) Iter() iter.Seq2[string, ipld.Node] {
return r.args.Iter()
}
func (r ReadOnly) ToIPLD() (ipld.Node, error) {
return r.args.ToIPLD()
}
func (r ReadOnly) Equals(other *Args) bool {
return r.args.Equals(other)
func (r ReadOnly) Equals(other ReadOnly) bool {
return r.args.Equals(other.args)
}
func (r ReadOnly) String() string {