Search Apps Documentation Source Content File Folder Download Copy Actions Download

repost_storage.gno

2.31 Kb · 98 lines
 1package boards
 2
 3import (
 4	"errors"
 5
 6	"gno.land/p/nt/avl/v0"
 7	"gno.land/p/nt/seqid/v0"
 8)
 9
10type (
11	// RepostIterFn defines a function type to iterate reposts.
12	RepostIterFn func(board, repost ID) bool
13
14	// RepostStorage defines an interface for storing reposts.
15	RepostStorage interface {
16		// Get returns the repost ID for a board.
17		Get(board ID) (repost ID, found bool)
18
19		// Add adds a new repost to the storage.
20		Add(repost *Post) error
21
22		// Remove removes repost for a board.
23		Remove(board ID) (removed bool)
24
25		// Size returns the number of reposts in the storage.
26		Size() int
27
28		// Iterate iterates reposts.
29		// To reverse iterate reposts use a negative count.
30		// If the callback returns true, the iteration is stopped.
31		Iterate(start, count int, fn RepostIterFn) bool
32	}
33)
34
35// NewRepostStorage creates a new storage for reposts.
36// The new storage uses an AVL tree to store reposts.
37func NewRepostStorage() RepostStorage {
38	return &repostStorage{avl.NewTree()}
39}
40
41type repostStorage struct {
42	reposts *avl.Tree // string(Board.ID) -> Post.ID
43}
44
45// Get returns the repost ID for a board.
46func (s repostStorage) Get(boardID ID) (ID, bool) {
47	v, found := s.reposts.Get(boardID.Key())
48	if !found {
49		return 0, false
50	}
51	return v.(ID), true
52}
53
54// Add adds a new repost to the storage.
55func (s *repostStorage) Add(repost *Post) error {
56	if repost == nil {
57		return errors.New("saving nil reposts is not allowed")
58	}
59
60	s.reposts.Set(repost.Board.ID.Key(), repost.ID)
61	return nil
62}
63
64// Remove removes repost for a board.
65func (s *repostStorage) Remove(boardID ID) bool {
66	_, removed := s.reposts.Remove(boardID.Key())
67	return removed
68}
69
70// Size returns the number of reposts in the storage.
71func (s repostStorage) Size() int {
72	return s.reposts.Size()
73}
74
75// Iterate iterates reposts.
76// To reverse iterate reposts use a negative count.
77// If the callback returns true, the iteration is stopped.
78func (s repostStorage) Iterate(start, count int, fn RepostIterFn) bool {
79	if count < 0 {
80		return s.reposts.ReverseIterateByOffset(start, -count, func(k string, v any) bool {
81			id, err := seqid.FromString(k)
82			if err != nil {
83				panic(err)
84			}
85
86			return fn(ID(id), v.(ID))
87		})
88	}
89
90	return s.reposts.IterateByOffset(start, count, func(k string, v any) bool {
91		id, err := seqid.FromString(k)
92		if err != nil {
93			panic(err)
94		}
95
96		return fn(ID(id), v.(ID))
97	})
98}