map_wrapper.go (2521B)
1 package rpcserver 2 3 import ( 4 capnp "capnproto.org/go/capnp/v3" 5 protocol_types "github.com/MTRNord/matrix_protobuf_fed/proto/federation/v1/types" 6 ) 7 8 /* 9 * This is a wrapper for the Map capnproto type which is defined as: 10 * 11 * ``` 12 * # A generic map from keys to values. 13 * struct Map(Key, Value) { 14 * entries @0 :List(Entry); 15 * struct Entry @0xb000b19244fa63f4 { 16 * key @0 :Key; 17 * value @1 :Value; 18 * } 19 * } 20 * ``` 21 * 22 * Contrary to normal go maps this map has a fixed size. 23 */ 24 type Map[Key capnp.Ptr, Value capnp.Ptr] struct { 25 internalMap *protocol_types.Map 26 maxSize int32 27 } 28 29 // NewMap creates a new Map Wrapper 30 func NewMap[Key capnp.Ptr, Value capnp.Ptr](s *capnp.Segment, maxSize int32) (*Map[Key, Value], error) { 31 internalMap, err := protocol_types.NewMap(s) 32 if err != nil { 33 return nil, err 34 } 35 36 return &Map[Key, Value]{ 37 internalMap: &internalMap, 38 maxSize: maxSize, 39 }, nil 40 } 41 42 // FromMap converts a capnp map to a wrapper 43 func FromMap[Key capnp.Ptr, Value capnp.Ptr](m *protocol_types.Map, maxSize int32) *Map[Key, Value] { 44 return &Map[Key, Value]{ 45 internalMap: m, 46 maxSize: maxSize, 47 } 48 } 49 50 // HasEntries returns true if the map has entries 51 func (m *Map[Key, Value]) HasEntries() bool { 52 return m.internalMap.HasEntries() 53 } 54 55 // Get a Segment of the internal map 56 func (m *Map[Key, Value]) Segment() *capnp.Segment { 57 return m.internalMap.Segment() 58 } 59 60 // Entries returns the entries of the map as a go map 61 func (m *Map[Key, Value]) Entries() (map[Key]*Value, error) { 62 // Check if we have entries. If not we return an empty map 63 result := make(map[Key]*Value) 64 if !m.HasEntries() { 65 return result, nil 66 } 67 68 entries, err := m.internalMap.Entries() 69 if err != nil { 70 return nil, err 71 } 72 73 for i := 0; i < entries.Len(); i++ { 74 entry := entries.At(i) 75 key, err := entry.Key() 76 if err != nil { 77 return nil, err 78 } 79 80 value_raw, err := entry.Value() 81 if err != nil { 82 return nil, err 83 } 84 85 value := Value(value_raw) 86 result[Key(key)] = &value 87 } 88 89 return result, nil 90 } 91 92 func (m *Map[Key, Value]) AddEntry(key Key, value Value) error { 93 // Check if we have any entries 94 if !m.internalMap.HasEntries() { 95 // Allocate enough entries 96 _, err := m.internalMap.NewEntries(m.maxSize) 97 if err != nil { 98 return err 99 } 100 } 101 internalEntries, err := m.internalMap.Entries() 102 if err != nil { 103 return err 104 } 105 106 entry := internalEntries.At(internalEntries.Len() - 1) 107 err = entry.SetKey(capnp.Ptr(key)) 108 if err != nil { 109 return err 110 } 111 return entry.SetValue(capnp.Ptr(value)) 112 }