Document interrupt, ints and json

This commit is contained in:
2025-04-03 17:33:44 -01:06
parent 0beadcb7c9
commit 38aa17486a
12 changed files with 54 additions and 12 deletions

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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

View File

@@ -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) {

View File

@@ -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{}

View File

@@ -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

View File

@@ -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) {

View File

@@ -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)