1package boards23import (4 "errors"56 "gno.land/p/nt/bptree/v0"7 "gno.land/p/nt/seqid/v0"8)910type (11 // RepostIterFn defines a function type to iterate reposts.12 RepostIterFn func(board, repost ID) bool1314 // 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)1819 // Add adds a new repost to the storage.20 Add(repost *Post) error2122 // Remove removes repost for a board.23 Remove(board ID) (removed bool)2425 // Size returns the number of reposts in the storage.26 Size() int2728 // 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) bool32 }33)3435// NewRepostStorage creates a new storage for reposts.36// The new storage uses an AVL tree to store reposts.37func NewRepostStorage() RepostStorage {38 return &repostStorage{bptree.NewBPTree32()}39}4041type repostStorage struct {42 reposts *bptree.BPTree // string(Board.ID) -> Post.ID43}4445// Get returns the repost ID for a board.46func (s repostStorage) Get(boardID ID) (ID, bool) {47 v := s.reposts.Get(boardID.Key())48 if v == nil {49 return 0, false50 }51 return v.(ID), true52}5354// 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 }5960 s.reposts.Set(repost.Board.ID.Key(), repost.ID)61 return nil62}6364// Remove removes repost for a board.65func (s *repostStorage) Remove(boardID ID) bool {66 _, removed := s.reposts.Remove(boardID.Key())67 return removed68}6970// Size returns the number of reposts in the storage.71func (s repostStorage) Size() int {72 return s.reposts.Size()73}7475// 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 }8586 return fn(ID(id), v.(ID))87 })88 }8990 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 }9596 return fn(ID(id), v.(ID))97 })98}99Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.