Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

entry.gno

2.70 Kb · 148 lines
  1package collection
  2
  3import "gno.land/p/nt/ufmt/v0"
  4
  5// Entry represents a single object in the collection with its ID
  6type Entry struct {
  7	ID  string
  8	Obj any
  9}
 10
 11// String returns a string representation of the Entry
 12func (e *Entry) String() string {
 13	if e == nil {
 14		return "<nil>"
 15	}
 16	return ufmt.Sprintf("Entry{ID: %s, Obj: %v}", e.ID, e.Obj)
 17}
 18
 19// EntryIterator provides iteration over collection entries
 20type EntryIterator struct {
 21	collection *Collection
 22	indexName  string
 23	key        string
 24	currentID  string
 25	currentObj any
 26	err        error
 27	closed     bool
 28
 29	// For multi-value cases
 30	ids        []string
 31	currentIdx int
 32}
 33
 34func (ei *EntryIterator) Close() error {
 35	ei.closed = true
 36	ei.currentID = ""
 37	ei.currentObj = nil
 38	ei.ids = nil
 39	return nil
 40}
 41
 42func (ei *EntryIterator) Next() bool {
 43	if ei == nil || ei.closed || ei.err != nil {
 44		return false
 45	}
 46
 47	// Handle ID index specially
 48	if ei.indexName == IDIndex {
 49		if ei.currentID != "" { // We've already returned the single value
 50			return false
 51		}
 52		obj := ei.collection.indexes[IDIndex].tree.Get(ei.key)
 53		if obj == nil {
 54			return false
 55		}
 56		ei.currentID = ei.key
 57		ei.currentObj = obj
 58		return true
 59	}
 60
 61	// Get the index
 62	idx, exists := ei.collection.indexes[ei.indexName]
 63	if !exists {
 64		return false
 65	}
 66
 67	// Initialize ids slice if needed
 68	if ei.ids == nil {
 69		idData := idx.tree.Get(ei.key)
 70		if idData == nil {
 71			return false
 72		}
 73
 74		switch stored := idData.(type) {
 75		case []string:
 76			ei.ids = stored
 77			ei.currentIdx = -1
 78		case string:
 79			ei.ids = []string{stored}
 80			ei.currentIdx = -1
 81		default:
 82			return false
 83		}
 84	}
 85
 86	// Move to next ID
 87	ei.currentIdx++
 88	if ei.currentIdx >= len(ei.ids) {
 89		return false
 90	}
 91
 92	// Fetch the actual object
 93	ei.currentID = ei.ids[ei.currentIdx]
 94	obj := ei.collection.indexes[IDIndex].tree.Get(ei.currentID)
 95	if obj == nil {
 96		// Skip invalid entries
 97		return ei.Next()
 98	}
 99	ei.currentObj = obj
100	return true
101}
102
103func (ei *EntryIterator) Error() error {
104	return ei.err
105}
106
107func (ei *EntryIterator) Value() *Entry {
108	if ei == nil || ei.closed || ei.currentID == "" {
109		return nil
110	}
111	return &Entry{
112		ID:  ei.currentID,
113		Obj: ei.currentObj,
114	}
115}
116
117func (ei *EntryIterator) Empty() bool {
118	if ei == nil || ei.closed || ei.err != nil {
119		return true
120	}
121
122	// Handle ID index specially
123	if ei.indexName == IDIndex {
124		return !ei.collection.indexes[IDIndex].tree.Has(ei.key)
125	}
126
127	// Get the index
128	idx, exists := ei.collection.indexes[ei.indexName]
129	if !exists {
130		return true
131	}
132
133	// Check if key exists in index
134	idData := idx.tree.Get(ei.key)
135	if idData == nil {
136		return true
137	}
138
139	// Check if there are any valid IDs
140	switch stored := idData.(type) {
141	case []string:
142		return len(stored) == 0
143	case string:
144		return stored == ""
145	default:
146		return true
147	}
148}