Skip to content

x.json2 #

The name json2 was chosen to avoid any unwanted potential conflicts with the > existing codegen tailored for the main json module which is powered by CJSON.

x.json2 is an experimental JSON parser written from scratch on V.

Usage

encode[T]

import x.json2
import time

struct Person {
mut:
name     string
age      ?int = 20
birthday time.Time
deathday ?time.Time
}

fn main() {
mut person := Person{
name: 'Bob'
birthday: time.now()
}
person_json := json2.encode[Person](person)
// person_json == {"name": "Bob", "age": 20, "birthday": "2022-03-11T13:54:25.000Z"}
}

decode[T]

import x.json2
import time

struct Person {
mut:
name     string
age      ?int = 20
birthday time.Time
deathday ?time.Time
}

fn main() {
resp :='{"name": "Bob", "age": 20, "birthday": "${time.now()}"}'
person := json2.decode[Person](resp)!
//
struct Person {
mut:
name "Bob"
age  20
birthday "2022-03-11 13:54:25"
}

}

decode[T] is smart and can auto-convert the types of struct fields - this meansexamples below will have the same result

json2.decode[Person]('{"name": "Bob", "age": 20, "birthday": "2022-03-11T13:54:25.000Z"}')!
json2.decode[Person]('{"name": "Bob", "age": 20, "birthday": "2022-03-11 13:54:25.000"}')!
json2.decode[Person]('{"name": "Bob", "age": "20", "birthday": 1647006865}')!
json2.decode[Person]('{"name": "Bob", "age": "20", "birthday": "1647006865"}}')!

raw decode

import x.json2
import net.http

fn main() {
resp := http.get('https://reqres.in/api/products/1')!

// This returns an Any type
raw_product := json2.raw_decode(resp.body)!
}

Casting Any type / Navigating

import x.json2
import net.http

fn main() {
resp := http.get('https://reqres.in/api/products/1')!

raw_product := json2.raw_decode(resp.body)!

product := raw_product.as_map()
data := product['data'] as map[string]json2.Any

id := data['id'].int() // 1
name := data['name'].str() // cerulean
year := data['year'].int() // 2000
}

Constructing an Any type

import x.json2

fn main() {
mut me := map[string]json2.Any{}
me['name'] = 'Bob'
me['age'] = 18

mut arr := []json2.Any{}
arr << 'rock'
arr << 'papers'
arr << json2.null
arr << 12

me['interests'] = arr

mut pets := map[string]json2.Any{}
pets['Sam'] = 'Maltese Shitzu'
me['pets'] = pets

// Stringify to JSON
println(me.str())
//{
//   "name":"Bob",
//   "age":18,
//   "interests":["rock","papers","scissors",null,12],
//   "pets":{"Sam":"Maltese"}
//}
}

Null Values

x.json2 has a separate Null type for differentiating an undefined value and a null value.To verify that the field you're accessing is a Null, use [typ] is json2.Null.

fn (mut p Person) from_json(f json2.Any) {
obj := f.as_map()
if obj['age'] is json2.Null {
// use a default value
p.age = 10
}
}

Casting a value to an incompatible type

x.json2 provides methods for turning Any types into usable types.The following list shows the possible outputs when casting a value to an incompatible type.

  1. Casting non-array values as array (arr()) will return an array with the value as the content.
  2. Casting non-map values as map (as_map()) will return a map with the value as the content.
  3. Casting non-string values to string (str()) will return theJSON string representation of the value.
  4. Casting non-numeric values to int/float (int()/i64()/f32()/f64()) will return zero.

Constants #

const default_encoder = Encoder{}
const null = Null{}

fn decode #

fn decode[T](src string) !T

decode is a generic function that decodes a JSON string into the target type.

fn encode #

fn encode[T](val T) string

encode is a generic function that encodes a type into a JSON string.

fn encode_pretty #

fn encode_pretty[T](typed_data T) string

encode_pretty ...

fn fast_raw_decode #

fn fast_raw_decode(src string) !Any

Same with raw_decode, but skips the type conversion for certain types when decoding a certain value.

fn raw_decode #

fn raw_decode(src string) !Any

Decodes a JSON string into an Any type. Returns an option.

interface Decodable #

interface Decodable {
	from_json(f Any)
}

Decodable is an interface, that allows custom implementations for decoding structs from JSON encoded values

interface Encodable #

interface Encodable {
	json_str() string
}

Decodable is an interface, that allows custom implementations for encoding structs to their string based JSON representations

fn ([]Any) str #

fn (f []Any) str() string

str returns the JSON string representation of the []Any type.

fn (Any) arr #

fn (f Any) arr() []Any

arr uses Any as an array.

fn (Any) as_map #

fn (f Any) as_map() map[string]Any

as_map uses Any as a map.

fn (Any) bool #

fn (f Any) bool() bool

bool uses Any as a bool.

fn (Any) f32 #

fn (f Any) f32() f32

f32 uses Any as a 32-bit float.

fn (Any) f64 #

fn (f Any) f64() f64

f64 uses Any as a 64-bit float.

fn (Any) i16 #

fn (f Any) i16() i16

i16 - TODO

fn (Any) i64 #

fn (f Any) i64() i64

i64 uses Any as a 64-bit integer.

fn (Any) i8 #

fn (f Any) i8() i8

i8 - TODO

fn (Any) int #

fn (f Any) int() int

int uses Any as an integer.

fn (Any) json_str #

fn (f Any) json_str() string

json_str returns the JSON string representation of the Any type.

fn (Any) prettify_json_str #

fn (f Any) prettify_json_str() string

prettify_json_str returns the pretty-formatted JSON string representation of the Any type.

fn (Any) str #

fn (f Any) str() string

str returns the string representation of the Any type. Use the json_str method if you want to use the escaped str() version of the Any type.

fn (Any) to_time #

fn (f Any) to_time() !time.Time

to_time uses Any as a time.Time.

fn (Any) u64 #

fn (f Any) u64() u64

u64 uses Any as a 64-bit unsigned integer.

fn (map[string]Any) str #

fn (f map[string]Any) str() string

str returns the JSON string representation of the map[string]Any type.

fn (Parser) decode #

fn (mut p Parser) decode() !Any

decode - decodes provided JSON

enum ValueKind #

enum ValueKind {
	unknown
	array
	object
	string_
	number
}

ValueKind enumerates the kinds of possible values of the Any sumtype.

fn (ValueKind) str #

fn (k ValueKind) str() string

str returns the string representation of the specific ValueKind

struct DecodeError #

struct DecodeError {
	line    int
	column  int
	message string
}

fn (DecodeError) code #

fn (err DecodeError) code() int

code returns the error code of DecodeError

fn (DecodeError) msg #

fn (err DecodeError) msg() string

msg returns the message of the DecodeError

struct Encoder #

struct Encoder {
	newline              u8
	newline_spaces_count int
	escape_unicode       bool = true
}

Encoder encodes the an Any type into JSON representation. It provides parameters in order to change the end result.

fn (Encoder) encode_value #

fn (e &Encoder) encode_value[T](val T, mut wr io.Writer) !

encode_value encodes a value to the specific writer.

struct InvalidTokenError #

struct InvalidTokenError {
	DecodeError
	token    Token
	expected TokenKind
}

fn (InvalidTokenError) code #

fn (err InvalidTokenError) code() int

code returns the error code of the InvalidTokenError

fn (InvalidTokenError) msg #

fn (err InvalidTokenError) msg() string

msg returns the message of the InvalidTokenError

struct Null #

struct Null {
	is_null bool = true
}

Null struct is a simple representation of the null value in JSON.

struct Token #

struct Token {
	lit  []u8      // literal representation of the token
	kind TokenKind // the token number/enum; for quick comparisons
	line int       // the line in the source where the token occurred
	col  int       // the column in the source where the token occurred
}

fn (Token) full_col #

fn (t Token) full_col() int

full_col returns the full column information which includes the length

struct UnknownTokenError #

struct UnknownTokenError {
	DecodeError
	token Token
	kind  ValueKind = .unknown
}

fn (UnknownTokenError) code #

fn (err UnknownTokenError) code() int

code returns the error code of the UnknownTokenError

fn (UnknownTokenError) msg #

fn (err UnknownTokenError) msg() string

msg returns the error message of the UnknownTokenError