diff --git a/interrupt/main.go b/interrupt/main.go index d6a3555..0d7cc89 100644 --- a/interrupt/main.go +++ b/interrupt/main.go @@ -13,12 +13,15 @@ import ( "realy.lol/qu" ) +// HandlerWithSource is an interrupt handling closure and the source location that it was sent +// from. type HandlerWithSource struct { Source string Fn func() } var ( + // RestartRequested is set true after restart is requested. RestartRequested bool // = true requested atomic.Bool diff --git a/interrupt/restart.go b/interrupt/restart.go index 4073d69..2259587 100644 --- a/interrupt/restart.go +++ b/interrupt/restart.go @@ -9,6 +9,8 @@ import ( "github.com/kardianos/osext" ) +// Restart uses syscall.Exec to restart the process. MacOS and Windows are not implemented, +// currently. func Restart() { log.D.Ln("restarting") file, e := osext.Executable() diff --git a/ints/ints.go b/ints/ints.go index 065b1de..0fec1a8 100644 --- a/ints/ints.go +++ b/ints/ints.go @@ -7,6 +7,8 @@ package ints import ( _ "embed" "io" + + "golang.org/x/exp/constraints" ) // run this to regenerate (pointlessly) the base 10 array of 4 places per entry @@ -17,16 +19,22 @@ var base10k []byte const base = 10000 +// T is an integer with a fast codec to decimal ASCII. type T struct { N uint64 } -func New[V uint | int | uint64 | uint32 | uint16 | uint8 | int64 | int32 | int16 | int8](n V) *T { +func New[V constraints.Integer](n V) *T { return &T{uint64(n)} } +// Uint64 returns the int.T as a uint64 (the base type) func (n *T) Uint64() uint64 { return n.N } -func (n *T) Int64() int64 { return int64(n.N) } + +// Int64 returns an int64 from the base number (may cause truncation) +func (n *T) Int64() int64 { return int64(n.N) } + +// Uint16 returns an uint16 from the base number (may cause truncation) func (n *T) Uint16() uint16 { return uint16(n.N) } var powers = []*T{ @@ -40,6 +48,7 @@ var powers = []*T{ const zero = '0' const nine = '9' +// Marshal the int.T into a byte string. func (n *T) Marshal(dst []byte) (b []byte) { nn := n.N b = dst diff --git a/json/array.go b/json/array.go index 7c8b38c..7be89b2 100644 --- a/json/array.go +++ b/json/array.go @@ -6,9 +6,12 @@ import ( "realy.lol/codec" ) -// An Array is an ordered list of values. +// An Array is an ordered list of values. Each field is typed, to deal with the javascript +// dynamic typing. This means the array is essentially static typed, so it won't work if the +// data is not in a predictable format. type Array struct{ V []codec.JSON } +// Marshal a list of values func (a *Array) Marshal(dst []byte) (b []byte) { b = dst b = append(b, '[') @@ -23,6 +26,8 @@ func (a *Array) Marshal(dst []byte) (b []byte) { return } +// Unmarshal decodes a byte string into an array, and returns the remainder after the end of the +// array. func (a *Array) Unmarshal(dst []byte) (rem []byte, err error) { rem = dst var openBracket bool diff --git a/json/base64.go b/json/base64.go index b48b672..12194d6 100644 --- a/json/base64.go +++ b/json/base64.go @@ -10,6 +10,7 @@ import ( // Base64 is a string representing binary data encoded as base64. type Base64 struct{ V []byte } +// Marshal encodes a byte string into base64. This uses standard encoding, not URL encoding. func (b2 *Base64) Marshal(dst []byte) (b []byte) { b = dst buf := &bytes.Buffer{} @@ -24,6 +25,7 @@ func (b2 *Base64) Marshal(dst []byte) (b []byte) { return } +// Unmarshal a base64 standard encoded string into a byte string. func (b2 *Base64) Unmarshal(dst []byte) (rem []byte, err error) { var c []byte if c, rem, err = text.UnmarshalQuoted(dst); chk.E(err) { diff --git a/json/bech32.go b/json/bech32.go index 638a404..b45608b 100644 --- a/json/bech32.go +++ b/json/bech32.go @@ -17,6 +17,7 @@ import ( // encoded, it returns an error. type Bech32 struct{ HRP, V []byte } +// Marshal a byte slice, with a given HRP prefix into a Bech32 string. func (b2 *Bech32) Marshal(dst []byte) (b []byte) { var err error var b5 []byte @@ -33,6 +34,7 @@ func (b2 *Bech32) Marshal(dst []byte) (b []byte) { return } +// Unmarshal a Bech32 string into raw bytes, and extract the HRP prefix. func (b2 *Bech32) Unmarshal(dst []byte) (rem []byte, err error) { var c []byte if c, rem, err = text.UnmarshalQuoted(dst); chk.E(err) { diff --git a/json/bool.go b/json/bool.go index 6a2e35f..8cf8a05 100644 --- a/json/bool.go +++ b/json/bool.go @@ -20,17 +20,20 @@ var Bools = map[bool][]byte{ false: []byte(F), } +// Marshal a Bool into JSON text (ie true/false) func (b2 *Bool) Marshal(dst []byte) (b []byte) { b = dst b = append(b, Bools[b2.V]...) return } +// Unmarshal a byte string that should be containing a boolean true/false. +// +// this is a shortcut evaluation because any text not in quotes in JSON is invalid so if +// it is something other than the exact correct, the next value will not match and the +// larger structure being unmarshalled will fail with an error. func (b2 *Bool) Unmarshal(dst []byte) (rem []byte, err error) { rem = dst - // this is a shortcut evaluation because any text not in quotes in JSON is invalid so if - // it is something other than the exact correct, the next value will not match and the - // larger structure being unmarshalled will fail with an error. if rem[0] == Bools[true][0] { if len(rem) < len(T) { err = io.EOF diff --git a/json/hex.go b/json/hex.go index cc47d69..1ace248 100644 --- a/json/hex.go +++ b/json/hex.go @@ -8,6 +8,7 @@ import ( // Hex is a string representing binary data encoded as hexadecimal. type Hex struct{ V []byte } +// Marshal a byte string into hexadecimal wrapped in double quotes. func (h *Hex) Marshal(dst []byte) (b []byte) { b = dst b = append(b, '"') @@ -16,6 +17,8 @@ func (h *Hex) Marshal(dst []byte) (b []byte) { return } +// Unmarshal a string wrapped in double quotes that should be a hexadecimal string. If it fails, +// it will return an error. func (h *Hex) Unmarshal(dst []byte) (rem []byte, err error) { var c []byte if c, rem, err = text.UnmarshalQuoted(dst); chk.E(err) { diff --git a/json/keyvalue.go b/json/keyvalue.go index c098dea..018956d 100644 --- a/json/keyvalue.go +++ b/json/keyvalue.go @@ -15,6 +15,7 @@ type KeyValue struct { Value codec.JSON } +// Marshal a KeyValue - ie, a JSON object key, from the provided byte string. func (k *KeyValue) Marshal(dst []byte) (b []byte) { b = (&String{k.Key}).Marshal(dst) b = append(b, ':') @@ -22,6 +23,7 @@ func (k *KeyValue) Marshal(dst []byte) (b []byte) { return } +// Unmarshal a JSON object key from a provided byte string. func (k *KeyValue) Unmarshal(dst []byte) (rem []byte, err error) { rem = dst s := &String{} diff --git a/json/signed.go b/json/signed.go index 6d25aec..4407f60 100644 --- a/json/signed.go +++ b/json/signed.go @@ -1,6 +1,8 @@ package json import ( + "golang.org/x/exp/constraints" + "realy.lol/ints" ) @@ -21,8 +23,10 @@ import ( // automatically converts it to the biggest type that is used in runtime. type Signed struct{ V int64 } -func NewSigned[V int64 | int32 | int16 | int8](i V) *Signed { return &Signed{int64(i)} } +// NewSigned creates a new Signed integer value. +func NewSigned[V constraints.Signed](i V) *Signed { return &Signed{int64(i)} } +// Marshal the Signed into a byte string in standard JSON formatting. func (s *Signed) Marshal(dst []byte) (b []byte) { b = dst v := s.V @@ -35,6 +39,7 @@ func (s *Signed) Marshal(dst []byte) (b []byte) { return } +// Unmarshal a Signed in JSON form into its value. func (s *Signed) Unmarshal(dst []byte) (rem []byte, err error) { rem = dst var neg bool diff --git a/json/string.go b/json/string.go index cbe69b5..84bfc2b 100644 --- a/json/string.go +++ b/json/string.go @@ -15,13 +15,16 @@ import ( // golang strings to save the caller from doing so. type String struct{ V []byte } -func NewString[V string | []byte](s V) *String { return &String{[]byte(s)} } +// NewString creates a new String from a string or byte string. +func NewString[V ~string | ~[]byte](s V) *String { return &String{[]byte(s)} } +// Marshal a String into a quoted byte string. func (s *String) Marshal(dst []byte) (b []byte) { b = text.AppendQuote(dst, s.V, text.NostrEscape) return } +// Unmarshal from a quoted JSON string into a String. func (s *String) Unmarshal(dst []byte) (rem []byte, err error) { var c []byte if c, rem, err = text.UnmarshalQuoted(dst); chk.E(err) { diff --git a/json/unsigned.go b/json/unsigned.go index a3d9e98..f8bacc5 100644 --- a/json/unsigned.go +++ b/json/unsigned.go @@ -1,6 +1,8 @@ package json import ( + "golang.org/x/exp/constraints" + "realy.lol/ints" ) @@ -16,14 +18,15 @@ import ( // the internal uint64 type, saving the caller from needing to cast it in their code. type Unsigned struct{ V uint64 } -func NewUnsigned[V int64 | int32 | int16 | int8 | uint64 | uint32 | uint16 | - uint8](i V) *Signed { - - return &Signed{int64(i)} +// NewUnsigned creates a new Unsigned from any unsigned integer. +func NewUnsigned[V constraints.Unsigned](i V) *Unsigned { + return &Unsigned{uint64(i)} } +// Marshal an Unsigned into a byte string. func (u *Unsigned) Marshal(dst []byte) (b []byte) { return ints.New(u.V).Marshal(dst) } +// Unmarshal renders a number in ASCII into an Unsigned. func (u *Unsigned) Unmarshal(dst []byte) (rem []byte, err error) { rem = dst n := ints.New(u.V)