Document interrupt, ints and json
This commit is contained in:
@@ -13,12 +13,15 @@ import (
|
|||||||
"realy.lol/qu"
|
"realy.lol/qu"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// HandlerWithSource is an interrupt handling closure and the source location that it was sent
|
||||||
|
// from.
|
||||||
type HandlerWithSource struct {
|
type HandlerWithSource struct {
|
||||||
Source string
|
Source string
|
||||||
Fn func()
|
Fn func()
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// RestartRequested is set true after restart is requested.
|
||||||
RestartRequested bool // = true
|
RestartRequested bool // = true
|
||||||
requested atomic.Bool
|
requested atomic.Bool
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import (
|
|||||||
"github.com/kardianos/osext"
|
"github.com/kardianos/osext"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Restart uses syscall.Exec to restart the process. MacOS and Windows are not implemented,
|
||||||
|
// currently.
|
||||||
func Restart() {
|
func Restart() {
|
||||||
log.D.Ln("restarting")
|
log.D.Ln("restarting")
|
||||||
file, e := osext.Executable()
|
file, e := osext.Executable()
|
||||||
|
|||||||
13
ints/ints.go
13
ints/ints.go
@@ -7,6 +7,8 @@ package ints
|
|||||||
import (
|
import (
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"golang.org/x/exp/constraints"
|
||||||
)
|
)
|
||||||
|
|
||||||
// run this to regenerate (pointlessly) the base 10 array of 4 places per entry
|
// run this to regenerate (pointlessly) the base 10 array of 4 places per entry
|
||||||
@@ -17,16 +19,22 @@ var base10k []byte
|
|||||||
|
|
||||||
const base = 10000
|
const base = 10000
|
||||||
|
|
||||||
|
// T is an integer with a fast codec to decimal ASCII.
|
||||||
type T struct {
|
type T struct {
|
||||||
N uint64
|
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)}
|
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) 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) }
|
func (n *T) Uint16() uint16 { return uint16(n.N) }
|
||||||
|
|
||||||
var powers = []*T{
|
var powers = []*T{
|
||||||
@@ -40,6 +48,7 @@ var powers = []*T{
|
|||||||
const zero = '0'
|
const zero = '0'
|
||||||
const nine = '9'
|
const nine = '9'
|
||||||
|
|
||||||
|
// Marshal the int.T into a byte string.
|
||||||
func (n *T) Marshal(dst []byte) (b []byte) {
|
func (n *T) Marshal(dst []byte) (b []byte) {
|
||||||
nn := n.N
|
nn := n.N
|
||||||
b = dst
|
b = dst
|
||||||
|
|||||||
@@ -6,9 +6,12 @@ import (
|
|||||||
"realy.lol/codec"
|
"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 }
|
type Array struct{ V []codec.JSON }
|
||||||
|
|
||||||
|
// Marshal a list of values
|
||||||
func (a *Array) Marshal(dst []byte) (b []byte) {
|
func (a *Array) Marshal(dst []byte) (b []byte) {
|
||||||
b = dst
|
b = dst
|
||||||
b = append(b, '[')
|
b = append(b, '[')
|
||||||
@@ -23,6 +26,8 @@ func (a *Array) Marshal(dst []byte) (b []byte) {
|
|||||||
return
|
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) {
|
func (a *Array) Unmarshal(dst []byte) (rem []byte, err error) {
|
||||||
rem = dst
|
rem = dst
|
||||||
var openBracket bool
|
var openBracket bool
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
// Base64 is a string representing binary data encoded as base64.
|
// Base64 is a string representing binary data encoded as base64.
|
||||||
type Base64 struct{ V []byte }
|
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) {
|
func (b2 *Base64) Marshal(dst []byte) (b []byte) {
|
||||||
b = dst
|
b = dst
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
@@ -24,6 +25,7 @@ func (b2 *Base64) Marshal(dst []byte) (b []byte) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unmarshal a base64 standard encoded string into a byte string.
|
||||||
func (b2 *Base64) Unmarshal(dst []byte) (rem []byte, err error) {
|
func (b2 *Base64) Unmarshal(dst []byte) (rem []byte, err error) {
|
||||||
var c []byte
|
var c []byte
|
||||||
if c, rem, err = text.UnmarshalQuoted(dst); chk.E(err) {
|
if c, rem, err = text.UnmarshalQuoted(dst); chk.E(err) {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
// encoded, it returns an error.
|
// encoded, it returns an error.
|
||||||
type Bech32 struct{ HRP, V []byte }
|
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) {
|
func (b2 *Bech32) Marshal(dst []byte) (b []byte) {
|
||||||
var err error
|
var err error
|
||||||
var b5 []byte
|
var b5 []byte
|
||||||
@@ -33,6 +34,7 @@ func (b2 *Bech32) Marshal(dst []byte) (b []byte) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unmarshal a Bech32 string into raw bytes, and extract the HRP prefix.
|
||||||
func (b2 *Bech32) Unmarshal(dst []byte) (rem []byte, err error) {
|
func (b2 *Bech32) Unmarshal(dst []byte) (rem []byte, err error) {
|
||||||
var c []byte
|
var c []byte
|
||||||
if c, rem, err = text.UnmarshalQuoted(dst); chk.E(err) {
|
if c, rem, err = text.UnmarshalQuoted(dst); chk.E(err) {
|
||||||
|
|||||||
@@ -20,17 +20,20 @@ var Bools = map[bool][]byte{
|
|||||||
false: []byte(F),
|
false: []byte(F),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Marshal a Bool into JSON text (ie true/false)
|
||||||
func (b2 *Bool) Marshal(dst []byte) (b []byte) {
|
func (b2 *Bool) Marshal(dst []byte) (b []byte) {
|
||||||
b = dst
|
b = dst
|
||||||
b = append(b, Bools[b2.V]...)
|
b = append(b, Bools[b2.V]...)
|
||||||
return
|
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) {
|
func (b2 *Bool) Unmarshal(dst []byte) (rem []byte, err error) {
|
||||||
rem = dst
|
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 rem[0] == Bools[true][0] {
|
||||||
if len(rem) < len(T) {
|
if len(rem) < len(T) {
|
||||||
err = io.EOF
|
err = io.EOF
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
// Hex is a string representing binary data encoded as hexadecimal.
|
// Hex is a string representing binary data encoded as hexadecimal.
|
||||||
type Hex struct{ V []byte }
|
type Hex struct{ V []byte }
|
||||||
|
|
||||||
|
// Marshal a byte string into hexadecimal wrapped in double quotes.
|
||||||
func (h *Hex) Marshal(dst []byte) (b []byte) {
|
func (h *Hex) Marshal(dst []byte) (b []byte) {
|
||||||
b = dst
|
b = dst
|
||||||
b = append(b, '"')
|
b = append(b, '"')
|
||||||
@@ -16,6 +17,8 @@ func (h *Hex) Marshal(dst []byte) (b []byte) {
|
|||||||
return
|
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) {
|
func (h *Hex) Unmarshal(dst []byte) (rem []byte, err error) {
|
||||||
var c []byte
|
var c []byte
|
||||||
if c, rem, err = text.UnmarshalQuoted(dst); chk.E(err) {
|
if c, rem, err = text.UnmarshalQuoted(dst); chk.E(err) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ type KeyValue struct {
|
|||||||
Value codec.JSON
|
Value codec.JSON
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Marshal a KeyValue - ie, a JSON object key, from the provided byte string.
|
||||||
func (k *KeyValue) Marshal(dst []byte) (b []byte) {
|
func (k *KeyValue) Marshal(dst []byte) (b []byte) {
|
||||||
b = (&String{k.Key}).Marshal(dst)
|
b = (&String{k.Key}).Marshal(dst)
|
||||||
b = append(b, ':')
|
b = append(b, ':')
|
||||||
@@ -22,6 +23,7 @@ func (k *KeyValue) Marshal(dst []byte) (b []byte) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unmarshal a JSON object key from a provided byte string.
|
||||||
func (k *KeyValue) Unmarshal(dst []byte) (rem []byte, err error) {
|
func (k *KeyValue) Unmarshal(dst []byte) (rem []byte, err error) {
|
||||||
rem = dst
|
rem = dst
|
||||||
s := &String{}
|
s := &String{}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"golang.org/x/exp/constraints"
|
||||||
|
|
||||||
"realy.lol/ints"
|
"realy.lol/ints"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -21,8 +23,10 @@ import (
|
|||||||
// automatically converts it to the biggest type that is used in runtime.
|
// automatically converts it to the biggest type that is used in runtime.
|
||||||
type Signed struct{ V int64 }
|
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) {
|
func (s *Signed) Marshal(dst []byte) (b []byte) {
|
||||||
b = dst
|
b = dst
|
||||||
v := s.V
|
v := s.V
|
||||||
@@ -35,6 +39,7 @@ func (s *Signed) Marshal(dst []byte) (b []byte) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unmarshal a Signed in JSON form into its value.
|
||||||
func (s *Signed) Unmarshal(dst []byte) (rem []byte, err error) {
|
func (s *Signed) Unmarshal(dst []byte) (rem []byte, err error) {
|
||||||
rem = dst
|
rem = dst
|
||||||
var neg bool
|
var neg bool
|
||||||
|
|||||||
@@ -15,13 +15,16 @@ import (
|
|||||||
// golang strings to save the caller from doing so.
|
// golang strings to save the caller from doing so.
|
||||||
type String struct{ V []byte }
|
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) {
|
func (s *String) Marshal(dst []byte) (b []byte) {
|
||||||
b = text.AppendQuote(dst, s.V, text.NostrEscape)
|
b = text.AppendQuote(dst, s.V, text.NostrEscape)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unmarshal from a quoted JSON string into a String.
|
||||||
func (s *String) Unmarshal(dst []byte) (rem []byte, err error) {
|
func (s *String) Unmarshal(dst []byte) (rem []byte, err error) {
|
||||||
var c []byte
|
var c []byte
|
||||||
if c, rem, err = text.UnmarshalQuoted(dst); chk.E(err) {
|
if c, rem, err = text.UnmarshalQuoted(dst); chk.E(err) {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"golang.org/x/exp/constraints"
|
||||||
|
|
||||||
"realy.lol/ints"
|
"realy.lol/ints"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -16,14 +18,15 @@ import (
|
|||||||
// the internal uint64 type, saving the caller from needing to cast it in their code.
|
// the internal uint64 type, saving the caller from needing to cast it in their code.
|
||||||
type Unsigned struct{ V uint64 }
|
type Unsigned struct{ V uint64 }
|
||||||
|
|
||||||
func NewUnsigned[V int64 | int32 | int16 | int8 | uint64 | uint32 | uint16 |
|
// NewUnsigned creates a new Unsigned from any unsigned integer.
|
||||||
uint8](i V) *Signed {
|
func NewUnsigned[V constraints.Unsigned](i V) *Unsigned {
|
||||||
|
return &Unsigned{uint64(i)}
|
||||||
return &Signed{int64(i)}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Marshal an Unsigned into a byte string.
|
||||||
func (u *Unsigned) Marshal(dst []byte) (b []byte) { return ints.New(u.V).Marshal(dst) }
|
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) {
|
func (u *Unsigned) Unmarshal(dst []byte) (rem []byte, err error) {
|
||||||
rem = dst
|
rem = dst
|
||||||
n := ints.New(u.V)
|
n := ints.New(u.V)
|
||||||
|
|||||||
Reference in New Issue
Block a user