Module x.json2 stdlib

x.json2
Version:
0.3.3
License:
MIT
Dependencies from vmod:
0
Imports:
4
Imported by:
2
Repository:
OS-specific
Show selected OS-specific symbols.
Backend-specific
Show selected Backend-specific symbols.

Dependencies defined in v.mod

This section is empty.

Imports

Imported by

Overview

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 means examples 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 the JSON string representation of the value.
  4. Casting non-numeric values to int/float (int()/i64()/f32()/f64()) will return zero.

Aliases

This section is empty.

Constants

#constant default_encoder

pub const default_encoder = Encoder{}

#constant null

pub const null = Null{}

Sum types

#type Any

pub type Any = Null

Any is a sum type that lists the possible types to be decoded and used.

#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) json_str

manualfree
fn (f Any) json_str() string

json_str returns the JSON string representation of the Any type.

#fn (Any) prettify_json_str

manualfree
fn (f Any) prettify_json_str() string

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

#fn (Any) i8

fn (f Any) i8() i8

i8 - TODO

#fn (Any) i16

fn (f Any) i16() i16

i16 - TODO

#fn (Any) int

fn (f Any) int() int

int uses Any as an integer.

#fn (Any) i64

fn (f Any) i64() i64

i64 uses Any as a 64-bit integer.

#fn (Any) u64

fn (f Any) u64() u64

u64 uses Any as a 64-bit unsigned integer.

#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) bool

fn (f Any) bool() bool

bool uses Any as a bool.

#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) to_time

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

to_time uses Any as a time.Time.

Functions

#fn decode[T]

fn decode[T](src string) !T

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

#fn encode[T]

fn encode[T](val T) string

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

#fn encode_pretty[T]

fn encode_pretty[T](typed_data T) string

#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.

#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 ([]Any) str

fn (f []Any) str() string

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

Structs

#struct DecodeError

pub 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 InvalidTokenError

pub struct InvalidTokenError {
	DecodeError
	token    Token
	expected TokenKind
}

fn (err InvalidTokenError) code() int

code returns the error code of the InvalidTokenError

fn (err InvalidTokenError) msg() string

msg returns the message of the InvalidTokenError

#struct UnknownTokenError

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

fn (err UnknownTokenError) code() int

code returns the error code of the UnknownTokenError

fn (err UnknownTokenError) msg() string

msg returns the error message of the UnknownTokenError

#struct Encoder

pub 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[T]

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

encode_value encodes a value to the specific writer.

#fn (&Encoder) encode_newline

fn (e &Encoder) encode_newline(level int, mut wr &io.Writer) !

#fn (&Encoder) encode_any

fn (e &Encoder) encode_any(val Any, level int, mut wr &io.Writer) !

#fn (&Encoder) encode_map[T]

fn (e &Encoder) encode_map(value T, level int, mut wr &io.Writer) !

#fn (&Encoder) encode_value_with_level[T]

fn (e &Encoder) encode_value_with_level(val T, level int, mut wr &io.Writer) !

#fn (&Encoder) encode_struct[U]

fn (e &Encoder) encode_struct(val U, level int, mut wr &io.Writer) !

#fn (&Encoder) encode_array[U]

fn (e &Encoder) encode_array(val []U, level int, mut wr &io.Writer) !

#fn (&Encoder) encode_string

manualfree
fn (e &Encoder) encode_string(s string, mut wr &io.Writer) !

TODO - Need refactor. Is so slow. The longer the string, the lower the performance.

encode_string returns the JSON spec-compliant version of the string.

#struct Token

pub struct Token {
	lit  []u8
	kind TokenKind
	line int
	col  int
}

#fn (Token) full_col

fn (t Token) full_col() int

full_col returns the full column information which includes the length

#struct Null

pub struct Null {
	is_null bool = true
}

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

Interfaces

#interface Decodable

pub interface Decodable {
	from_json(f Any)
}

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

#interface Encodable

pub interface Encodable {
	json_str() string
}

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

Enums

#enum ValueKind

pub 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