json

package
v0.0.0-...-d6038a4 Latest Latest
Warning

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

Go to latest
Published: Apr 21, 2025 License: CC0-1.0 Imports: 12 Imported by: 0

Documentation

Overview

Package json is a collection of primitives for fast encoding and decoding of minified JSON, intended to eventually replace most of the event and filter encoder and others, built as part of the beginnings of a Go NWC protocol implementation.

Index

Examples

Constants

View Source
const F = "false"
View Source
const T = "true"

Variables

View Source
var Bools = map[bool][]byte{
	// contains filtered or unexported fields
}

Functions

This section is empty.

Types

type Array

type Array struct{ V []codec.JSON }

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.

func (*Array) Marshal

func (a *Array) Marshal(dst []byte) (b []byte)

Marshal a list of values

func (*Array) Unmarshal

func (a *Array) Unmarshal(dst []byte) (rem []byte, err error)

Unmarshal decodes a byte string into an array, and returns the remainder after the end of the array.

type Base64

type Base64 struct{ V []byte }

Base64 is a string representing binary data encoded as base64.

func (*Base64) Marshal

func (b2 *Base64) Marshal(dst []byte) (b []byte)

Marshal encodes a byte string into base64. This uses standard encoding, not URL encoding.

Example
const (
	hexVal = "deadbeefcafe0123456789abcdef00deadbeefcafe0123456789abcdef00"
)
bin, err := hex.Dec(hexVal)
if err != nil {
	return
}
b1 := &Base64{bin}
var b []byte
b = b1.Marshal(nil)
fmt.Printf("%s\n", b)
b2 := &Base64{}
var rem []byte
rem, err = b2.Unmarshal(b)
if chk.E(err) || len(rem) != 0 {
	fmt.Printf("%s\n%s", err.Error(), rem)
	return
}
fmt.Printf("data: %0x\n", b2.V)
fmt.Printf("%v\n", bytes.Equal(bin, b2.V))
Output:

"3q2+78r+ASNFZ4mrze8A3q2+78r+ASNFZ4mrze8A"
data: deadbeefcafe0123456789abcdef00deadbeefcafe0123456789abcdef00
true

func (*Base64) Unmarshal

func (b2 *Base64) Unmarshal(dst []byte) (rem []byte, err error)

Unmarshal a base64 standard encoded string into a byte string.

type Bech32

type Bech32 struct{ HRP, V []byte }

Bech32 is a string encoded in bech32 format including a human-readable prefix and base32 encoded binary data. A key difference is the HRP prefix.

To create a new Bech32, load the HRP variable with the intended HRP for encoding.

When decoding, point this variable at the expected HRP, if it doesn't match in what is encoded, it returns an error.

func (*Bech32) Marshal

func (b2 *Bech32) Marshal(dst []byte) (b []byte)

Marshal a byte slice, with a given HRP prefix into a Bech32 string.

Example
const (
	hrp    = "herp"
	hexVal = "00deadbeefcafe0123456789abcdef00deadbeefcafe0123456789abcdef"
)
bin, err := hex.Dec(hexVal)
if err != nil {
	return
}
b32 := &Bech32{[]byte(hrp), bin}
b := b32.Marshal(nil)
fmt.Printf("%s\n", b)
b33 := &Bech32{HRP: []byte(hrp)}
var rem []byte
rem, err = b33.Unmarshal(b)
if chk.E(err) || len(rem) != 0 {
	return
}
fmt.Printf("hrp: %s\ndata: %0x\n", b33.HRP, b33.V)
fmt.Printf("%v\n", bytes.Equal(bin, b33.V))
Output:

"herp1qr02m0h0etlqzg69v7y6hn00qr02m0h0etlqzg69v7y6hn00jujvlj"
hrp: herp
data: 00deadbeefcafe0123456789abcdef00deadbeefcafe0123456789abcdef
true

func (*Bech32) Unmarshal

func (b2 *Bech32) Unmarshal(dst []byte) (rem []byte, err error)

Unmarshal a Bech32 string into raw bytes, and extract the HRP prefix.

type Bool

type Bool struct{ V bool }

Bool can be either `true` or `false` and only lower case. Initialize these values as follows:

truthValue := &json.Bool{}

to get a default value which is false.

func (*Bool) Marshal

func (b2 *Bool) Marshal(dst []byte) (b []byte)

Marshal a Bool into JSON text (ie true/false)

Example
var b []byte
bt := &Bool{true}
b = bt.Marshal(b)
fmt.Printf("%s\n", b)
bt2 := &Bool{}
rem, err := bt2.Unmarshal(b)
if err != nil || len(rem) != 0 {
	return
}
fmt.Printf("%v\n", bt2.V == true)
b = b[:0]
bf := &Bool{} // implicit initialized bool is false
b = bf.Marshal(b)
fmt.Printf("%s\n", b)
fmt.Printf("%v\n", bf.V == false)
Output:

true
true
false
true

func (*Bool) Unmarshal

func (b2 *Bool) Unmarshal(dst []byte) (rem []byte, err error)

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.

type Hex

type Hex struct{ V []byte }

Hex is a string representing binary data encoded as hexadecimal.

func (*Hex) Marshal

func (h *Hex) Marshal(dst []byte) (b []byte)

Marshal a byte string into hexadecimal wrapped in double quotes.

Example
const (
	hexVal = "deadbeefcafe0123456789abcdef00deadbeefcafe0123456789abcdef"
)
bin, err := hex.Dec(hexVal)
if err != nil {
	return
}
h := &Hex{bin}
b := h.Marshal(nil)
fmt.Printf("%s\n", b)
h2 := &Hex{}
var rem []byte
rem, err = h2.Unmarshal(b)
if chk.E(err) || len(rem) != 0 {
	fmt.Printf("%s\n%s", err.Error(), rem)
	return
}
fmt.Printf("data: %0x\n", h2.V)
fmt.Printf("%v\n", bytes.Equal(bin, h2.V))
Output:

"deadbeefcafe0123456789abcdef00deadbeefcafe0123456789abcdef"
data: deadbeefcafe0123456789abcdef00deadbeefcafe0123456789abcdef
true

func (*Hex) Unmarshal

func (h *Hex) Unmarshal(dst []byte) (rem []byte, err error)

Unmarshal a string wrapped in double quotes that should be a hexadecimal string. If it fails, it will return an error.

type KeyValue

type KeyValue struct {
	Key   []byte
	Value codec.JSON
}

A KeyValue is a field in an Object.

func (*KeyValue) Marshal

func (k *KeyValue) Marshal(dst []byte) (b []byte)

Marshal a KeyValue - ie, a JSON object key, from the provided byte string.

Example
const (
	// deliberately put whitespace here to make sure it parses. even garbage will parse, but
	// we aren't going to bother, mainly whitespace needs to be allowed.
	keyVal = `"key" :  		 
"value"`
)
kv := &KeyValue{Value: &String{}}
rem, err := kv.Unmarshal([]byte(keyVal))
if chk.E(err) || len(rem) != 0 {
	fmt.Printf("%s\n'%s'", err.Error(), rem)
	return
}
kv2 := &KeyValue{[]byte("key"), &String{[]byte("value")}}
var b, b2 []byte
b = kv.Marshal(b)
b2 = kv2.Marshal(b2)
fmt.Printf("%s\n%s\n%v\n", b, b2, bytes.Equal(b, b2))
Output:

"key":"value"
"key":"value"
true

func (*KeyValue) Unmarshal

func (k *KeyValue) Unmarshal(dst []byte) (rem []byte, err error)

Unmarshal a JSON object key from a provided byte string.

type Object

type Object struct{ V []KeyValue }

An Object is an (not necessarily) ordered list of KeyValue.

type Signed

type Signed struct{ V int64 }

Signed integers can be negative and thus a `-` prefix.

Initialize these values as follows:

num := &json.Signed{}

to get a default value which is zero.

Technically we are supporting negative numbers here but in fact in nostr message encodings there is no such thing as any negative integers, nor floating point, but this ensures if there is ever need for negative values they are supported. For the most part this will be used for timestamps.

There is a NewSigned function that accepts any type of generic signed integer value and automatically converts it to the biggest type that is used in runtime.

func NewSigned

func NewSigned[V constraints.Signed](i V) *Signed

NewSigned creates a new Signed integer value.

func (*Signed) Marshal

func (s *Signed) Marshal(dst []byte) (b []byte)

Marshal the Signed into a byte string in standard JSON formatting.

Example
var b []byte
s := &Signed{}
b = s.Marshal(b)
fmt.Printf("%s\n", b)
s2 := &Signed{}
rem, err := s2.Unmarshal(b)
if err != nil || len(rem) != 0 {
	return
}
fmt.Printf("%v\n", s2.V == 0)
s.V = 69420
b = b[:0]
b = s.Marshal(b)
fmt.Printf("%s\n", b)
rem, err = s2.Unmarshal(b)
if err != nil || len(rem) != 0 {
	return
}
fmt.Printf("%v\n", s2.V == s.V)
s.V *= -69420
b = b[:0]
b = s.Marshal(b)
fmt.Printf("%s\n", b)
rem, err = s2.Unmarshal(b)
if err != nil || len(rem) != 0 {
	return
}
fmt.Printf("%v\n", s2.V == s.V)
Output:

0
true
69420
true
-4819136400
true

func (*Signed) Unmarshal

func (s *Signed) Unmarshal(dst []byte) (rem []byte, err error)

Unmarshal a Signed in JSON form into its value.

type String

type String struct{ V []byte }

String is a regular string. Must be escaped as per nip-01. Bytes stored in it are not escaped, only must be escaped to output JSON.

Again like the other types, create a new String with:

str := json.String{}

There is also a convenience NewString function that generically automatically converts actual golang strings to save the caller from doing so.

func NewString

func NewString[V ~string | ~[]byte](s V) *String

NewString creates a new String from a string or byte string.

func (*String) Marshal

func (s *String) Marshal(dst []byte) (b []byte)

Marshal a String into a quoted byte string.

Example
var b []byte
const ex = `test with
	
newlines and hidden tab and spaces at the end    `
s := NewString(ex)
b = s.Marshal(b)
fmt.Printf("%s\n", b)
s2 := &String{}
rem, err := s2.Unmarshal(b)
if err != nil || len(rem) != 0 {
	return
}
fmt.Printf("%v\n", bytes.Equal(s2.V, []byte(ex)))
Output:

"test with\n\t\nnewlines and hidden tab and spaces at the end    "
true

func (*String) Unmarshal

func (s *String) Unmarshal(dst []byte) (rem []byte, err error)

Unmarshal from a quoted JSON string into a String.

type Unsigned

type Unsigned struct{ V uint64 }

Unsigned integers have no possible `-` prefix nor a decimal place.

Initialize these values as follows:

num := &json.Unsigned{}

to get a default value which is zero.

There is a generic NewUnsigned function which will automatically convert any integer type to the internal uint64 type, saving the caller from needing to cast it in their code.

func NewUnsigned

func NewUnsigned[V constraints.Unsigned](i V) *Unsigned

NewUnsigned creates a new Unsigned from any unsigned integer.

func (*Unsigned) Marshal

func (u *Unsigned) Marshal(dst []byte) (b []byte)

Marshal an Unsigned into a byte string.

Example
var b []byte
u := &Unsigned{}
b = u.Marshal(b)
fmt.Printf("%s\n", b)
u2 := &Unsigned{}
rem, err := u2.Unmarshal(b)
if err != nil || len(rem) != 0 {
	return
}
fmt.Printf("%v\n", u2.V == 0)
u.V = 69420
b = b[:0]
b = u.Marshal(b)
fmt.Printf("%s\n", b)
rem, err = u2.Unmarshal(b)
if err != nil || len(rem) != 0 {
	return
}
fmt.Printf("%v\n", u2.V == 69420)
Output:

0
true
69420
true

func (*Unsigned) Unmarshal

func (u *Unsigned) Unmarshal(dst []byte) (rem []byte, err error)

Unmarshal renders a number in ASCII into an Unsigned.

Jump to

Keyboard shortcuts

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