Document interrupt, ints and json
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
13
ints/ints.go
13
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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{}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user