worm

package module
v0.0.0-...-fa6e1e7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 12, 2019 License: ISC Imports: 24 Imported by: 0

README

worm

A reflection-based RESP3 server framework for Go

Protocol

worm implements the majority of the RESP3 protocol, however the following components are not yet implemented:

  • Streaming types
  • Attribute type
  • Non-string map keys

Getting started

worm uses reflection to build a map of commands based on the methods of a struct value:

type MyCommands struct {
}

func (c *MyCommands) Example(client *worm.Client, args ...*worm.Value) error {
  return client.WriteValue(NewArray(args))
}

func (c *MyCommands) Example2(client *worm.Client, arg1 *worm.Value, arg2 *worm.Value) error {
  if err := client.WriteArrayHeader(2); err != nil {
    return err
  }

  if err := client.WriteValue(arg1); err != nil {
    return err
  }

  return client.WriteValue(arg2)
}

func (c *MyCommands) SomethingElse(i int) int {
  return i + 1
}

In the example above, MyCommands exports two worm commands named Example and Example2. SomethingElse isn't converted to a command because it has incompatible arguments.

In order to write a valid command, it must:

  1. Start with a *worm.Client argument
  2. Contain any number of *worm.Value arguments, including variadic arguments
  3. Return an error value

Once you have written all your commands, you can easily create a new server:

ctx := MyCommands {}
server, err := worm.NewTCPServer("127.0.0.1:8081", nil, &ctx)

And run it:

server.Run()

Then, using redis-cli, you can query it:

$ redis-cli -p 8081
127.0.0.1:8081> example testing 1234
1) testing
2) 1234

Documentation

Index

Constants

View Source
const WormVersion = 1

Variables

View Source
var (
	ErrInvalidType        = errors.New("invalid type")
	ErrNotEnoughArguments = errors.New("not enough arguments")
	ErrInvalidArguments   = errors.New("invalid arguments")
)
View Source
var NilValue = Value{Kind: Nil, Data: nil}

Functions

func GenerateSelfSignedSSLCert

func GenerateSelfSignedSSLCert(prefix string) (*tls.Config, error)

func LoadX509KeyPair

func LoadX509KeyPair(certFile, keyFile string) (*tls.Config, error)

Types

type Client

type Client struct {
	Version string

	Input  *bufio.Reader
	Output *bufio.Writer
	User   *User
	Data   map[string]interface{}
	// contains filtered or unexported fields
}

func Connect

func Connect(addr string) (*Client, error)

func ConnectV2

func ConnectV2(addr string) (*Client, error)

func ConnectVersion

func ConnectVersion(addr string, version string) (*Client, error)

func NewClient

func NewClient(conn net.Conn) *Client

func NewClientVersion

func NewClientVersion(conn net.Conn, version string) *Client

func (*Client) Close

func (c *Client) Close() error

func (*Client) Command

func (c *Client) Command(args ...string) (*Message, error)

func (*Client) Exec

func (c *Client) Exec(args ...*Value) (*Message, error)

func (*Client) Read

func (c *Client) Read() (*Message, error)

func (*Client) ReadValue

func (c *Client) ReadValue() (*Value, error)

func (*Client) Write

func (c *Client) Write(message *Message) error

func (*Client) WriteArrayHeader

func (c *Client) WriteArrayHeader(n int) error

func (*Client) WriteBytesHeader

func (c *Client) WriteBytesHeader(n int, tag string) error

func (*Client) WriteCRLF

func (c *Client) WriteCRLF() error

func (*Client) WriteError

func (c *Client) WriteError(msg string) error

func (*Client) WriteMapHeader

func (c *Client) WriteMapHeader(n int) error

func (*Client) WriteOK

func (c *Client) WriteOK() error

func (*Client) WriteSimpleString

func (c *Client) WriteSimpleString(s string) error

func (*Client) WriteStringHeader

func (c *Client) WriteStringHeader(n int) error

func (*Client) WriteValue

func (c *Client) WriteValue(val *Value) error

type Command

type Command = func(*Client, []*Value) error

type Kind

type Kind int
const (
	Nil Kind = iota
	Bool
	Int64
	Float64
	BigInt
	String
	Bytes
	Error
	Array
	Map
)

type Message

type Message struct {
	Kind  MessageKind
	Type  string
	Value *Value
	User  *User
}

type MessageKind

type MessageKind int
const (
	Default MessageKind = iota
	Verbatim
	SetReply
	Push
	Hello
)

type Server

type Server struct {
	Addr     string
	Mode     string
	Context  interface{}
	Commands map[string]Command

	Closed bool
	Users  map[string]User
	// contains filtered or unexported fields
}

func NewServer

func NewServer(s net.Listener, ctx interface{}) (*Server, error)

func NewTCPServer

func NewTCPServer(addr string, tlsConfig *tls.Config, ctx interface{}) (*Server, error)

func (*Server) CheckUser

func (s *Server) CheckUser(user *User) bool

func (*Server) Close

func (s *Server) Close() error

func (*Server) Run

func (server *Server) Run() error

type User

type User struct {
	Name        string
	Password    string
	Permissions []string
}

func (*User) Can

func (u *User) Can(perm string) bool

type Value

type Value struct {
	Kind Kind
	Data interface{}
}

func Decode

func Decode(r io.Reader) (*Value, error)

func DecodeBytes

func DecodeBytes(b []byte) (*Value, error)

func New

func New(value interface{}) *Value

func NewArray

func NewArray(a []*Value) *Value

func NewBigInt

func NewBigInt(i *big.Int) *Value

func NewBool

func NewBool(b bool) *Value

func NewBytes

func NewBytes(b []byte) *Value

func NewError

func NewError(s string) *Value

func NewErrorNoPrefix

func NewErrorNoPrefix(s string) *Value

func NewFloat64

func NewFloat64(f float64) *Value

func NewInt

func NewInt(i int) *Value

func NewInt64

func NewInt64(i int64) *Value

func NewMap

func NewMap(m map[string]*Value) *Value

func NewNil

func NewNil() *Value

func NewString

func NewString(s string) *Value

func NewValue

func NewValue(kind Kind, data interface{}) *Value

func (*Value) Encode

func (v *Value) Encode(w io.Writer) error

func (*Value) EncodeBytes

func (v *Value) EncodeBytes() ([]byte, error)

func (*Value) Is

func (v *Value) Is(kind Kind) bool

func (*Value) IsNil

func (v *Value) IsNil() bool

func (Value) MarshalJSON

func (v Value) MarshalJSON() ([]byte, error)

func (*Value) ToArray

func (v *Value) ToArray() []*Value

func (*Value) ToBigInt

func (v *Value) ToBigInt() *big.Int

func (*Value) ToBool

func (v *Value) ToBool() bool

func (*Value) ToBytes

func (v *Value) ToBytes() []byte

func (*Value) ToError

func (v *Value) ToError() error

func (*Value) ToFloat32

func (v *Value) ToFloat32() float32

func (*Value) ToFloat64

func (v *Value) ToFloat64() float64

func (*Value) ToInt

func (v *Value) ToInt() int

func (*Value) ToInt64

func (v *Value) ToInt64() int64

func (*Value) ToMap

func (v *Value) ToMap() map[string]*Value

func (*Value) ToString

func (v *Value) ToString() string

func (*Value) UnmarshalJSON

func (v *Value) UnmarshalJSON(b []byte) error

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL