rolist.gno
2.48 Kb · 86 lines
1// Package rolist provides a read-only wrapper for list.List with safe value transformation.
2package rolist
3
4import (
5 "gno.land/p/nt/bptree/v0/list"
6 "gno.land/p/nt/bptree/v0/rotree"
7)
8
9// IReadOnlyList defines the read-only operations available on a list.
10type IReadOnlyList interface {
11 Len() int
12 Get(index int) (any, bool)
13 Slice(startIndex, endIndex int) []any
14 ForEach(fn func(index int, value any) bool)
15}
16
17// ReadOnlyList wraps a list.List and provides read-only access.
18type ReadOnlyList struct {
19 list *list.List
20 makeEntrySafeFn func(any) any
21}
22
23// Verify interface implementations
24var (
25 _ IReadOnlyList = (*ReadOnlyList)(nil)
26 _ IReadOnlyList = (interface{ list.IList })(nil) // is subset of list.IList
27)
28
29// Wrap creates a new ReadOnlyList from an existing list.List and a safety transformation function.
30// If makeEntrySafeFn is nil, values will be returned as-is without transformation.
31func Wrap(list *list.List, makeEntrySafeFn func(any) any) *ReadOnlyList {
32 return &ReadOnlyList{
33 list: list,
34 makeEntrySafeFn: makeEntrySafeFn,
35 }
36}
37
38// getSafeValue applies the makeEntrySafeFn if it exists, otherwise returns the original value
39func (rol *ReadOnlyList) getSafeValue(value any) any {
40 if rol.makeEntrySafeFn == nil {
41 return value
42 }
43 return rol.makeEntrySafeFn(value)
44}
45
46// Len returns the number of elements in the list.
47func (rol *ReadOnlyList) Len() int {
48 return rol.list.Len()
49}
50
51// Get returns the value at the specified index, converted to a safe format.
52// Returns (nil, false) if index is out of bounds.
53func (rol *ReadOnlyList) Get(index int) (any, bool) {
54 value, ok := rol.list.Get(index)
55 if !ok {
56 return nil, false
57 }
58 return rol.getSafeValue(value), true
59}
60
61// Slice returns a slice of values from startIndex (inclusive) to endIndex (exclusive),
62// with all values converted to a safe format.
63func (rol *ReadOnlyList) Slice(startIndex, endIndex int) []any {
64 values := rol.list.Slice(startIndex, endIndex)
65 if values == nil {
66 return nil
67 }
68
69 result := make([]any, len(values))
70 for i, v := range values {
71 result[i] = rol.getSafeValue(v)
72 }
73 return result
74}
75
76// ForEach iterates through all elements in the list, providing safe versions of the values.
77func (rol *ReadOnlyList) ForEach(fn func(index int, value any) bool) {
78 rol.list.ForEach(func(index int, value any) bool {
79 return fn(index, rol.getSafeValue(value))
80 })
81}
82
83// Tree returns a read-only pointer to the underlying B+ tree.
84func (rol *ReadOnlyList) Tree() *rotree.ReadOnlyTree {
85 return rol.list.Tree()
86}