// Generated by `wit-bindgen-wrpc-go` 0.1.1. DO NOT EDIT! package store import ( bytes "bytes" context "context" binary "encoding/binary" errors "errors" fmt "fmt" wrpc "github.com/wrpc/wrpc/go" io "io" slog "log/slog" math "math" sync "sync" atomic "sync/atomic" utf8 "unicode/utf8" ) // The set of errors which may be raised by functions in this package type Error struct { payload any discriminant ErrorDiscriminant } func (v *Error) Discriminant() ErrorDiscriminant { return v.discriminant } type ErrorDiscriminant uint8 const ( // The host does not recognize the store identifier requested. ErrorNoSuchStore ErrorDiscriminant = 0 // The requesting component does not have access to the specified store // (which may or may not exist). ErrorAccessDenied ErrorDiscriminant = 1 // Some implementation-specific error has occurred (e.g. I/O) ErrorOther ErrorDiscriminant = 2 ) func (v *Error) String() string { switch v.discriminant { case ErrorNoSuchStore: return "no-such-store" case ErrorAccessDenied: return "access-denied" case ErrorOther: return "other" default: panic("invalid variant") } } // The host does not recognize the store identifier requested. func (v *Error) GetNoSuchStore() (ok bool) { if ok = (v.discriminant == ErrorNoSuchStore); !ok { return } return } // The host does not recognize the store identifier requested. func (v *Error) SetNoSuchStore() *Error { v.discriminant = ErrorNoSuchStore v.payload = nil return v } // The host does not recognize the store identifier requested. func NewErrorNoSuchStore() *Error { return (&Error{}).SetNoSuchStore() } // The requesting component does not have access to the specified store // (which may or may not exist). func (v *Error) GetAccessDenied() (ok bool) { if ok = (v.discriminant == ErrorAccessDenied); !ok { return } return } // The requesting component does not have access to the specified store // (which may or may not exist). func (v *Error) SetAccessDenied() *Error { v.discriminant = ErrorAccessDenied v.payload = nil return v } // The requesting component does not have access to the specified store // (which may or may not exist). func NewErrorAccessDenied() *Error { return (&Error{}).SetAccessDenied() } // Some implementation-specific error has occurred (e.g. I/O) func (v *Error) GetOther() (payload string, ok bool) { if ok = (v.discriminant == ErrorOther); !ok { return } payload, ok = v.payload.(string) return } // Some implementation-specific error has occurred (e.g. I/O) func (v *Error) SetOther(payload string) *Error { v.discriminant = ErrorOther v.payload = payload return v } // Some implementation-specific error has occurred (e.g. I/O) func NewErrorOther(payload string) *Error { return (&Error{}).SetOther( payload) } func (v *Error) Error() string { return v.String() } func (v *Error) WriteToIndex(w wrpc.ByteWriter) (func(wrpc.IndexWriter) error, error) { if err := func(v uint8, w io.Writer) error { b := make([]byte, 2) i := binary.PutUvarint(b, uint64(v)) slog.Debug("writing u8 discriminant") _, err := w.Write(b[:i]) return err }(uint8(v.discriminant), w); err != nil { return nil, fmt.Errorf("failed to write discriminant: %w", err) } switch v.discriminant { case ErrorNoSuchStore: case ErrorAccessDenied: case ErrorOther: payload, ok := v.payload.(string) if !ok { return nil, errors.New("invalid payload") } write, err := (func(wrpc.IndexWriter) error)(nil), func(v string, w io.Writer) (err error) { n := len(v) if n > math.MaxUint32 { return fmt.Errorf("string byte length of %d overflows a 32-bit integer", n) } if err = func(v int, w io.Writer) error { b := make([]byte, binary.MaxVarintLen32) i := binary.PutUvarint(b, uint64(v)) slog.Debug("writing string byte length", "len", n) _, err = w.Write(b[:i]) return err }(n, w); err != nil { return fmt.Errorf("failed to write string byte length of %d: %w", n, err) } slog.Debug("writing string bytes") _, err = w.Write([]byte(v)) if err != nil { return fmt.Errorf("failed to write string bytes: %w", err) } return nil }(payload, w) if err != nil { return nil, fmt.Errorf("failed to write payload: %w", err) } if write != nil { return func(w wrpc.IndexWriter) error { w, err := w.Index(2) if err != nil { return fmt.Errorf("failed to index writer: %w", err) } return write(w) }, nil } default: return nil, errors.New("invalid variant") } return nil, nil } // A response to a `list-keys` operation. type KeyResponse struct { // The list of keys returned by the query. Keys []string // The continuation token to use to fetch the next page of keys. If this is `null`, then // there are no more keys to fetch. Cursor *uint64 } func (v *KeyResponse) String() string { return "KeyResponse" } func (v *KeyResponse) WriteToIndex(w wrpc.ByteWriter) (func(wrpc.IndexWriter) error, error) { writes := make(map[uint32]func(wrpc.IndexWriter) error, 2) slog.Debug("writing field", "name", "keys") write0, err := func(v []string, w interface { io.ByteWriter io.Writer }) (write func(wrpc.IndexWriter) error, err error) { n := len(v) if n > math.MaxUint32 { return nil, fmt.Errorf("list length of %d overflows a 32-bit integer", n) } if err = func(v int, w io.Writer) error { b := make([]byte, binary.MaxVarintLen32) i := binary.PutUvarint(b, uint64(v)) slog.Debug("writing list length", "len", n) _, err = w.Write(b[:i]) return err }(n, w); err != nil { return nil, fmt.Errorf("failed to write list length of %d: %w", n, err) } slog.Debug("writing list elements") writes := make(map[uint32]func(wrpc.IndexWriter) error, n) for i, e := range v { write, err := (func(wrpc.IndexWriter) error)(nil), func(v string, w io.Writer) (err error) { n := len(v) if n > math.MaxUint32 { return fmt.Errorf("string byte length of %d overflows a 32-bit integer", n) } if err = func(v int, w io.Writer) error { b := make([]byte, binary.MaxVarintLen32) i := binary.PutUvarint(b, uint64(v)) slog.Debug("writing string byte length", "len", n) _, err = w.Write(b[:i]) return err }(n, w); err != nil { return fmt.Errorf("failed to write string byte length of %d: %w", n, err) } slog.Debug("writing string bytes") _, err = w.Write([]byte(v)) if err != nil { return fmt.Errorf("failed to write string bytes: %w", err) } return nil }(e, w) if err != nil { return nil, fmt.Errorf("failed to write list element %d: %w", i, err) } if write != nil { writes[uint32(i)] = write } } if len(writes) > 0 { return func(w wrpc.IndexWriter) error { var wg sync.WaitGroup var wgErr atomic.Value for index, write := range writes { wg.Add(1) w, err := w.Index(index) if err != nil { return fmt.Errorf("failed to index writer: %w", err) } write := write go func() { defer wg.Done() if err := write(w); err != nil { wgErr.Store(err) } }() } wg.Wait() err := wgErr.Load() if err == nil { return nil } return err.(error) }, nil } return nil, nil }(v.Keys, w) if err != nil { return nil, fmt.Errorf("failed to write `keys` field: %w", err) } if write0 != nil { writes[0] = write0 } slog.Debug("writing field", "name", "cursor") write1, err := func(v *uint64, w interface { io.ByteWriter io.Writer }) (func(wrpc.IndexWriter) error, error) { if v == nil { slog.Debug("writing `option::none` status byte") if err := w.WriteByte(0); err != nil { return nil, fmt.Errorf("failed to write `option::none` byte: %w", err) } return nil, nil } slog.Debug("writing `option::some` status byte") if err := w.WriteByte(1); err != nil { return nil, fmt.Errorf("failed to write `option::some` status byte: %w", err) } slog.Debug("writing `option::some` payload") write, err := (func(wrpc.IndexWriter) error)(nil), func(v uint64, w io.Writer) (err error) { b := make([]byte, binary.MaxVarintLen64) i := binary.PutUvarint(b, uint64(v)) slog.Debug("writing u64") _, err = w.Write(b[:i]) return err }(*v, w) if err != nil { return nil, fmt.Errorf("failed to write `option::some` payload: %w", err) } return write, nil }(v.Cursor, w) if err != nil { return nil, fmt.Errorf("failed to write `cursor` field: %w", err) } if write1 != nil { writes[1] = write1 } if len(writes) > 0 { return func(w wrpc.IndexWriter) error { var wg sync.WaitGroup var wgErr atomic.Value for index, write := range writes { wg.Add(1) w, err := w.Index(index) if err != nil { return fmt.Errorf("failed to index writer: %w", err) } write := write go func() { defer wg.Done() if err := write(w); err != nil { wgErr.Store(err) } }() } wg.Wait() err := wgErr.Load() if err == nil { return nil } return err.(error) }, nil } return nil, nil } type Handler interface { // A bucket is a collection of key-value pairs. Each key-value pair is stored as a entry in the // bucket, and the bucket itself acts as a collection of all these entries. // // It is worth noting that the exact terminology for bucket in key-value stores can very // depending on the specific implementation. For example: // // 1. Amazon DynamoDB calls a collection of key-value pairs a table // 2. Redis has hashes, sets, and sorted sets as different types of collections // 3. Cassandra calls a collection of key-value pairs a column family // 4. MongoDB calls a collection of key-value pairs a collection // 5. Riak calls a collection of key-value pairs a bucket // 6. Memcached calls a collection of key-value pairs a slab // 7. Azure Cosmos DB calls a collection of key-value pairs a container // // In this interface, we use the term `bucket` to refer to a collection of key-value pairs // Get the value associated with the specified `key` // // The value is returned as an option. If the key-value pair exists in the // store, it returns `Ok(value)`. If the key does not exist in the // store, it returns `Ok(none)`. // // If any other error occurs, it returns an `Err(error)`. Get(ctx__ context.Context, bucket string, key string) (*wrpc.Result[[]uint8, Error], error) // Set the value associated with the key in the store. If the key already // exists in the store, it overwrites the value. // // If the key does not exist in the store, it creates a new key-value pair. // // If any other error occurs, it returns an `Err(error)`. Set(ctx__ context.Context, bucket string, key string, value []uint8) (*wrpc.Result[struct{}, Error], error) // Delete the key-value pair associated with the key in the store. // // If the key does not exist in the store, it does nothing. // // If any other error occurs, it returns an `Err(error)`. Delete(ctx__ context.Context, bucket string, key string) (*wrpc.Result[struct{}, Error], error) // Check if the key exists in the store. // // If the key exists in the store, it returns `Ok(true)`. If the key does // not exist in the store, it returns `Ok(false)`. // // If any other error occurs, it returns an `Err(error)`. Exists(ctx__ context.Context, bucket string, key string) (*wrpc.Result[bool, Error], error) // Get all the keys in the store with an optional cursor (for use in pagination). It // returns a list of keys. Please note that for most KeyValue implementations, this is a // can be a very expensive operation and so it should be used judiciously. Implementations // can return any number of keys in a single response, but they should never attempt to // send more data than is reasonable (i.e. on a small edge device, this may only be a few // KB, while on a large machine this could be several MB). Any response should also return // a cursor that can be used to fetch the next page of keys. See the `key-response` record // for more information. // // Note that the keys are not guaranteed to be returned in any particular order. // // If the store is empty, it returns an empty list. // // MAY show an out-of-date list of keys if there are concurrent writes to the store. // // If any error occurs, it returns an `Err(error)`. ListKeys(ctx__ context.Context, bucket string, cursor *uint64) (*wrpc.Result[KeyResponse, Error], error) } func ServeInterface(s wrpc.Server, h Handler) (stop func() error, err error) { stops := make([]func() error, 0, 5) stop = func() error { for _, stop := range stops { if err := stop(); err != nil { return err } } return nil } stop0, err := s.Serve("wrpc:keyvalue/store@0.2.0-draft", "get", func(ctx context.Context, w wrpc.IndexWriter, r wrpc.IndexReadCloser) error { slog.DebugContext(ctx, "reading parameter", "i", 0) p0, err := func(r interface { io.ByteReader io.Reader }) (string, error) { var x uint32 var s uint8 for i := 0; i < 5; i++ { slog.Debug("reading string length byte", "i", i) b, err := r.ReadByte() if err != nil { if i > 0 && err == io.EOF { err = io.ErrUnexpectedEOF } return "", fmt.Errorf("failed to read string length byte: %w", err) } if s == 28 && b > 0x0f { return "", errors.New("string length overflows a 32-bit integer") } if b < 0x80 { x = x | uint32(b)< 0 && err == io.EOF { err = io.ErrUnexpectedEOF } return "", fmt.Errorf("failed to read string length byte: %w", err) } if s == 28 && b > 0x0f { return "", errors.New("string length overflows a 32-bit integer") } if b < 0x80 { x = x | uint32(b)< math.MaxUint32 { return nil, fmt.Errorf("list length of %d overflows a 32-bit integer", n) } if err = func(v int, w io.Writer) error { b := make([]byte, binary.MaxVarintLen32) i := binary.PutUvarint(b, uint64(v)) slog.Debug("writing list length", "len", n) _, err = w.Write(b[:i]) return err }(n, w); err != nil { return nil, fmt.Errorf("failed to write list length of %d: %w", n, err) } slog.Debug("writing list elements") writes := make(map[uint32]func(wrpc.IndexWriter) error, n) for i, e := range v { write, err := (func(wrpc.IndexWriter) error)(nil), func(v uint8, w io.ByteWriter) error { slog.Debug("writing u8 byte") return w.WriteByte(v) }(e, w) if err != nil { return nil, fmt.Errorf("failed to write list element %d: %w", i, err) } if write != nil { writes[uint32(i)] = write } } if len(writes) > 0 { return func(w wrpc.IndexWriter) error { var wg sync.WaitGroup var wgErr atomic.Value for index, write := range writes { wg.Add(1) w, err := w.Index(index) if err != nil { return fmt.Errorf("failed to index writer: %w", err) } write := write go func() { defer wg.Done() if err := write(w); err != nil { wgErr.Store(err) } }() } wg.Wait() err := wgErr.Load() if err == nil { return nil } return err.(error) }, nil } return nil, nil }(v, w) if err != nil { return nil, fmt.Errorf("failed to write `option::some` payload: %w", err) } return write, nil }(*v.Ok, w) if err != nil { return nil, fmt.Errorf("failed to write `result::ok` payload: %w", err) } if write != nil { return write, nil } return nil, nil default: slog.Debug("writing `result::err` status byte") if err := w.WriteByte(1); err != nil { return nil, fmt.Errorf("failed to write `result::err` status byte: %w", err) } slog.Debug("writing `result::err` payload") write, err := (v.Err).WriteToIndex(w) if err != nil { return nil, fmt.Errorf("failed to write `result::err` payload: %w", err) } if write != nil { return write, nil } return nil, nil } }(r0, &buf) if err != nil { return fmt.Errorf("failed to write result value 0: %w", err) } if write0 != nil { writes[0] = write0 } slog.DebugContext(ctx, "transmitting `wrpc:keyvalue/store@0.2.0-draft.get` result") _, err = w.Write(buf.Bytes()) if err != nil { return fmt.Errorf("failed to write result: %w", err) } if len(writes) > 0 { var wg sync.WaitGroup var wgErr atomic.Value for index, write := range writes { wg.Add(1) w, err := w.Index(index) if err != nil { return fmt.Errorf("failed to index writer: %w", err) } write := write go func() { defer wg.Done() if err := write(w); err != nil { wgErr.Store(err) } }() } wg.Wait() err := wgErr.Load() if err == nil { return nil } return err.(error) } return nil }) if err != nil { return nil, fmt.Errorf("failed to serve `wrpc:keyvalue/store@0.2.0-draft.get`: %w", err) } stops = append(stops, stop0) stop1, err := s.Serve("wrpc:keyvalue/store@0.2.0-draft", "set", func(ctx context.Context, w wrpc.IndexWriter, r wrpc.IndexReadCloser) error { slog.DebugContext(ctx, "reading parameter", "i", 0) p0, err := func(r interface { io.ByteReader io.Reader }) (string, error) { var x uint32 var s uint8 for i := 0; i < 5; i++ { slog.Debug("reading string length byte", "i", i) b, err := r.ReadByte() if err != nil { if i > 0 && err == io.EOF { err = io.ErrUnexpectedEOF } return "", fmt.Errorf("failed to read string length byte: %w", err) } if s == 28 && b > 0x0f { return "", errors.New("string length overflows a 32-bit integer") } if b < 0x80 { x = x | uint32(b)< 0 && err == io.EOF { err = io.ErrUnexpectedEOF } return "", fmt.Errorf("failed to read string length byte: %w", err) } if s == 28 && b > 0x0f { return "", errors.New("string length overflows a 32-bit integer") } if b < 0x80 { x = x | uint32(b)< 0 && err == io.EOF { err = io.ErrUnexpectedEOF } return nil, fmt.Errorf("failed to read byte list length byte: %w", err) } if b < 0x80 { if i == 4 && b > 1 { return nil, errors.New("byte list length overflows a 32-bit integer") } x = x | uint32(b)< 0 { var wg sync.WaitGroup var wgErr atomic.Value for index, write := range writes { wg.Add(1) w, err := w.Index(index) if err != nil { return fmt.Errorf("failed to index writer: %w", err) } write := write go func() { defer wg.Done() if err := write(w); err != nil { wgErr.Store(err) } }() } wg.Wait() err := wgErr.Load() if err == nil { return nil } return err.(error) } return nil }) if err != nil { return nil, fmt.Errorf("failed to serve `wrpc:keyvalue/store@0.2.0-draft.set`: %w", err) } stops = append(stops, stop1) stop2, err := s.Serve("wrpc:keyvalue/store@0.2.0-draft", "delete", func(ctx context.Context, w wrpc.IndexWriter, r wrpc.IndexReadCloser) error { slog.DebugContext(ctx, "reading parameter", "i", 0) p0, err := func(r interface { io.ByteReader io.Reader }) (string, error) { var x uint32 var s uint8 for i := 0; i < 5; i++ { slog.Debug("reading string length byte", "i", i) b, err := r.ReadByte() if err != nil { if i > 0 && err == io.EOF { err = io.ErrUnexpectedEOF } return "", fmt.Errorf("failed to read string length byte: %w", err) } if s == 28 && b > 0x0f { return "", errors.New("string length overflows a 32-bit integer") } if b < 0x80 { x = x | uint32(b)< 0 && err == io.EOF { err = io.ErrUnexpectedEOF } return "", fmt.Errorf("failed to read string length byte: %w", err) } if s == 28 && b > 0x0f { return "", errors.New("string length overflows a 32-bit integer") } if b < 0x80 { x = x | uint32(b)< 0 { var wg sync.WaitGroup var wgErr atomic.Value for index, write := range writes { wg.Add(1) w, err := w.Index(index) if err != nil { return fmt.Errorf("failed to index writer: %w", err) } write := write go func() { defer wg.Done() if err := write(w); err != nil { wgErr.Store(err) } }() } wg.Wait() err := wgErr.Load() if err == nil { return nil } return err.(error) } return nil }) if err != nil { return nil, fmt.Errorf("failed to serve `wrpc:keyvalue/store@0.2.0-draft.delete`: %w", err) } stops = append(stops, stop2) stop3, err := s.Serve("wrpc:keyvalue/store@0.2.0-draft", "exists", func(ctx context.Context, w wrpc.IndexWriter, r wrpc.IndexReadCloser) error { slog.DebugContext(ctx, "reading parameter", "i", 0) p0, err := func(r interface { io.ByteReader io.Reader }) (string, error) { var x uint32 var s uint8 for i := 0; i < 5; i++ { slog.Debug("reading string length byte", "i", i) b, err := r.ReadByte() if err != nil { if i > 0 && err == io.EOF { err = io.ErrUnexpectedEOF } return "", fmt.Errorf("failed to read string length byte: %w", err) } if s == 28 && b > 0x0f { return "", errors.New("string length overflows a 32-bit integer") } if b < 0x80 { x = x | uint32(b)< 0 && err == io.EOF { err = io.ErrUnexpectedEOF } return "", fmt.Errorf("failed to read string length byte: %w", err) } if s == 28 && b > 0x0f { return "", errors.New("string length overflows a 32-bit integer") } if b < 0x80 { x = x | uint32(b)< 0 { var wg sync.WaitGroup var wgErr atomic.Value for index, write := range writes { wg.Add(1) w, err := w.Index(index) if err != nil { return fmt.Errorf("failed to index writer: %w", err) } write := write go func() { defer wg.Done() if err := write(w); err != nil { wgErr.Store(err) } }() } wg.Wait() err := wgErr.Load() if err == nil { return nil } return err.(error) } return nil }) if err != nil { return nil, fmt.Errorf("failed to serve `wrpc:keyvalue/store@0.2.0-draft.exists`: %w", err) } stops = append(stops, stop3) stop4, err := s.Serve("wrpc:keyvalue/store@0.2.0-draft", "list-keys", func(ctx context.Context, w wrpc.IndexWriter, r wrpc.IndexReadCloser) error { slog.DebugContext(ctx, "reading parameter", "i", 0) p0, err := func(r interface { io.ByteReader io.Reader }) (string, error) { var x uint32 var s uint8 for i := 0; i < 5; i++ { slog.Debug("reading string length byte", "i", i) b, err := r.ReadByte() if err != nil { if i > 0 && err == io.EOF { err = io.ErrUnexpectedEOF } return "", fmt.Errorf("failed to read string length byte: %w", err) } if s == 28 && b > 0x0f { return "", errors.New("string length overflows a 32-bit integer") } if b < 0x80 { x = x | uint32(b)< 0 && err == io.EOF { err = io.ErrUnexpectedEOF } return x, fmt.Errorf("failed to read u64 byte: %w", err) } if s == 63 && b > 0x01 { return x, errors.New("varint overflows a 64-bit integer") } if b < 0x80 { return x | uint64(b)< 0 { var wg sync.WaitGroup var wgErr atomic.Value for index, write := range writes { wg.Add(1) w, err := w.Index(index) if err != nil { return fmt.Errorf("failed to index writer: %w", err) } write := write go func() { defer wg.Done() if err := write(w); err != nil { wgErr.Store(err) } }() } wg.Wait() err := wgErr.Load() if err == nil { return nil } return err.(error) } return nil }) if err != nil { return nil, fmt.Errorf("failed to serve `wrpc:keyvalue/store@0.2.0-draft.list-keys`: %w", err) } stops = append(stops, stop4) return stop, nil }