Search Apps Documentation Source Content File Folder Download Copy Actions Download

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}