mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
x.json2: add support for i8, i16, u8, u16, u32 (fix #16484)
This commit is contained in:
parent
79b4cfb42a
commit
6b0743bb07
|
@ -108,10 +108,10 @@ fn test_bool() {
|
||||||
assert sample_data['bool'] or { 0 }.bool() == false
|
assert sample_data['bool'] or { 0 }.bool() == false
|
||||||
assert json2.Any('true').bool() == true
|
assert json2.Any('true').bool() == true
|
||||||
// invalid conversions
|
// invalid conversions
|
||||||
assert sample_data['int'] or { 0 }.bool() == false
|
assert sample_data['int'] or { 0 }.bool() == true
|
||||||
assert sample_data['i64'] or { 0 }.bool() == false
|
assert sample_data['i64'] or { 0 }.bool() == true
|
||||||
assert sample_data['f32'] or { 0 }.bool() == false
|
assert sample_data['f32'] or { 0 }.bool() == true
|
||||||
assert sample_data['f64'] or { 0 }.bool() == false
|
assert sample_data['f64'] or { 0 }.bool() == true
|
||||||
assert sample_data['null'] or { 0 }.bool() == false
|
assert sample_data['null'] or { 0 }.bool() == false
|
||||||
assert sample_data['arr'] or { 0 }.bool() == false
|
assert sample_data['arr'] or { 0 }.bool() == false
|
||||||
assert sample_data['obj'] or { 0 }.bool() == false
|
assert sample_data['obj'] or { 0 }.bool() == false
|
||||||
|
|
|
@ -3,43 +3,6 @@
|
||||||
// that can be found in the LICENSE file.
|
// that can be found in the LICENSE file.
|
||||||
module json2
|
module json2
|
||||||
|
|
||||||
// `Any` is a sum type that lists the possible types to be decoded and used.
|
|
||||||
pub type Any = Null
|
|
||||||
| []Any
|
|
||||||
| []int
|
|
||||||
| bool
|
|
||||||
| f32
|
|
||||||
| f64
|
|
||||||
| i64
|
|
||||||
| int
|
|
||||||
| map[string]Any
|
|
||||||
| string
|
|
||||||
| u64
|
|
||||||
|
|
||||||
// `Null` struct is a simple representation of the `null` value in JSON.
|
|
||||||
pub struct Null {
|
|
||||||
is_null bool = true
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum ValueKind {
|
|
||||||
unknown
|
|
||||||
array
|
|
||||||
object
|
|
||||||
string_
|
|
||||||
number
|
|
||||||
}
|
|
||||||
|
|
||||||
// str returns the string representation of the specific ValueKind
|
|
||||||
pub fn (k ValueKind) str() string {
|
|
||||||
return match k {
|
|
||||||
.unknown { 'unknown' }
|
|
||||||
.array { 'array' }
|
|
||||||
.object { 'object' }
|
|
||||||
.string_ { 'string' }
|
|
||||||
.number { 'number' }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn format_message(msg string, line int, column int) string {
|
fn format_message(msg string, line int, column int) string {
|
||||||
return '[x.json2] ${msg} (${line}:${column})'
|
return '[x.json2] ${msg} (${line}:${column})'
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,7 @@ pub struct Encoder {
|
||||||
|
|
||||||
pub const default_encoder = Encoder{}
|
pub const default_encoder = Encoder{}
|
||||||
|
|
||||||
// byte array versions of the most common tokens/chars
|
// byte array versions of the most common tokens/chars to avoid reallocations
|
||||||
// to avoid reallocations
|
|
||||||
const null_in_bytes = 'null'.bytes()
|
const null_in_bytes = 'null'.bytes()
|
||||||
|
|
||||||
const true_in_bytes = 'true'.bytes()
|
const true_in_bytes = 'true'.bytes()
|
||||||
|
@ -65,7 +64,10 @@ fn (e &Encoder) encode_any(val Any, level int, mut wr io.Writer) ! {
|
||||||
wr.write(json2.false_in_bytes)!
|
wr.write(json2.false_in_bytes)!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int, u64, i64 {
|
i8, i16, int, i64 {
|
||||||
|
wr.write(val.str().bytes())!
|
||||||
|
}
|
||||||
|
u8, u16, u32, u64 {
|
||||||
wr.write(val.str().bytes())!
|
wr.write(val.str().bytes())!
|
||||||
}
|
}
|
||||||
f32, f64 {
|
f32, f64 {
|
||||||
|
@ -140,7 +142,8 @@ fn (e &Encoder) encode_value_with_level<T>(val T, level int, mut wr io.Writer) !
|
||||||
e.encode_any(val, level, mut wr)!
|
e.encode_any(val, level, mut wr)!
|
||||||
} $else $if T is []Any {
|
} $else $if T is []Any {
|
||||||
e.encode_any(val, level, mut wr)!
|
e.encode_any(val, level, mut wr)!
|
||||||
} $else $if T is Null || T is bool || T is f32 || T is f64 || T is i64 || T is int || T is u64 {
|
} $else $if T is Null || T is bool || T is f32 || T is f64 || T is i8 || T is i16 || T is int
|
||||||
|
|| T is i64 || T is u8 || T is u16 || T is u32 || T is u64 {
|
||||||
e.encode_any(val, level, mut wr)!
|
e.encode_any(val, level, mut wr)!
|
||||||
} $else $if T is Encodable {
|
} $else $if T is Encodable {
|
||||||
wr.write(val.json_str().bytes())!
|
wr.write(val.json_str().bytes())!
|
||||||
|
|
53
vlib/x/json2/integer_primitives_test.v
Normal file
53
vlib/x/json2/integer_primitives_test.v
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import x.json2
|
||||||
|
|
||||||
|
struct IntegerValues {
|
||||||
|
mut:
|
||||||
|
ux8 u8
|
||||||
|
ux16 u16
|
||||||
|
ux32 u32
|
||||||
|
ux64 u64
|
||||||
|
sx8 i8
|
||||||
|
sx16 i16
|
||||||
|
sx32 int
|
||||||
|
sx64 i64
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut x IntegerValues) from_json(f json2.Any) {
|
||||||
|
fm := f.as_map()
|
||||||
|
if v := fm['ux8'] {
|
||||||
|
x.ux8 = u8(v.u64())
|
||||||
|
}
|
||||||
|
if v := fm['ux16'] {
|
||||||
|
x.ux16 = u16(v.u64())
|
||||||
|
}
|
||||||
|
if v := fm['ux32'] {
|
||||||
|
x.ux32 = u32(v.u64())
|
||||||
|
}
|
||||||
|
if v := fm['ux64'] {
|
||||||
|
x.ux64 = v.u64()
|
||||||
|
}
|
||||||
|
//
|
||||||
|
if v := fm['sx8'] {
|
||||||
|
x.sx8 = i8(v.i64())
|
||||||
|
}
|
||||||
|
if v := fm['sx16'] {
|
||||||
|
x.sx16 = i16(v.i64())
|
||||||
|
}
|
||||||
|
if v := fm['sx32'] {
|
||||||
|
x.sx32 = int(v.i64())
|
||||||
|
}
|
||||||
|
if v := fm['sx64'] {
|
||||||
|
x.sx64 = v.i64()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_all_primitive_integer_types_are_encodable_and_decodable() {
|
||||||
|
f := IntegerValues{1, 2, 3, 4, -1, -2, -3, -4}
|
||||||
|
s := json2.encode<IntegerValues>(f)
|
||||||
|
dump(s)
|
||||||
|
assert s == '{"ux8":1,"ux16":2,"ux32":3,"ux64":4,"sx8":-1,"sx16":-2,"sx32":-3,"sx64":-4}'
|
||||||
|
x := json2.decode<IntegerValues>(s)!
|
||||||
|
dump(x)
|
||||||
|
assert x == f
|
||||||
|
println('done')
|
||||||
|
}
|
|
@ -5,18 +5,6 @@ module json2
|
||||||
|
|
||||||
import strings
|
import strings
|
||||||
|
|
||||||
pub const (
|
|
||||||
null = Null{}
|
|
||||||
)
|
|
||||||
|
|
||||||
pub interface Decodable {
|
|
||||||
from_json(f Any)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub interface Encodable {
|
|
||||||
json_str() string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decodes a JSON string into an `Any` type. Returns an option.
|
// Decodes a JSON string into an `Any` type. Returns an option.
|
||||||
pub fn raw_decode(src string) !Any {
|
pub fn raw_decode(src string) !Any {
|
||||||
mut p := new_parser(src, true)
|
mut p := new_parser(src, true)
|
||||||
|
@ -45,32 +33,16 @@ pub fn encode<T>(val T) string {
|
||||||
}
|
}
|
||||||
default_encoder.encode_value(val, mut sb) or {
|
default_encoder.encode_value(val, mut sb) or {
|
||||||
dump(err)
|
dump(err)
|
||||||
default_encoder.encode_value<Null>(json2.null, mut sb) or {}
|
default_encoder.encode_value<Null>(null, mut sb) or {}
|
||||||
}
|
}
|
||||||
return sb.str()
|
return sb.str()
|
||||||
}
|
}
|
||||||
|
|
||||||
// as_map uses `Any` as a map.
|
|
||||||
pub fn (f Any) as_map() map[string]Any {
|
|
||||||
if f is map[string]Any {
|
|
||||||
return f
|
|
||||||
} else if f is []Any {
|
|
||||||
mut mp := map[string]Any{}
|
|
||||||
for i, fi in f {
|
|
||||||
mp['${i}'] = fi
|
|
||||||
}
|
|
||||||
return mp
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
'0': f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// int uses `Any` as an integer.
|
// int uses `Any` as an integer.
|
||||||
pub fn (f Any) int() int {
|
pub fn (f Any) int() int {
|
||||||
match f {
|
match f {
|
||||||
int { return f }
|
int { return f }
|
||||||
i64, f32, f64, bool { return int(f) }
|
i8, i16, i64, u8, u16, u32, u64, f32, f64, bool { return int(f) }
|
||||||
else { return 0 }
|
else { return 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +51,7 @@ pub fn (f Any) int() int {
|
||||||
pub fn (f Any) i64() i64 {
|
pub fn (f Any) i64() i64 {
|
||||||
match f {
|
match f {
|
||||||
i64 { return f }
|
i64 { return f }
|
||||||
int, f32, f64, bool { return i64(f) }
|
i8, i16, int, u8, u16, u32, u64, f32, f64, bool { return i64(f) }
|
||||||
else { return 0 }
|
else { return 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +60,7 @@ pub fn (f Any) i64() i64 {
|
||||||
pub fn (f Any) u64() u64 {
|
pub fn (f Any) u64() u64 {
|
||||||
match f {
|
match f {
|
||||||
u64 { return f }
|
u64 { return f }
|
||||||
int, i64, f32, f64, bool { return u64(f) }
|
u8, u16, u32, i8, i16, int, i64, f32, f64, bool { return u64(f) }
|
||||||
else { return 0 }
|
else { return 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,20 +69,32 @@ pub fn (f Any) u64() u64 {
|
||||||
pub fn (f Any) f32() f32 {
|
pub fn (f Any) f32() f32 {
|
||||||
match f {
|
match f {
|
||||||
f32 { return f }
|
f32 { return f }
|
||||||
int, i64, f64 { return f32(f) }
|
bool, i8, i16, int, i64, u8, u16, u32, u64, f64 { return f32(f) }
|
||||||
else { return 0.0 }
|
else { return 0.0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// f64 uses `Any` as a float.
|
// f64 uses `Any` as a 64-bit float.
|
||||||
pub fn (f Any) f64() f64 {
|
pub fn (f Any) f64() f64 {
|
||||||
match f {
|
match f {
|
||||||
f64 { return f }
|
f64 { return f }
|
||||||
int, i64, f32 { return f64(f) }
|
i8, i16, int, i64, u8, u16, u32, u64, f32 { return f64(f) }
|
||||||
else { return 0.0 }
|
else { return 0.0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bool uses `Any` as a bool.
|
||||||
|
pub fn (f Any) bool() bool {
|
||||||
|
match f {
|
||||||
|
bool { return f }
|
||||||
|
string { return f.bool() }
|
||||||
|
i8, i16, int, i64 { return i64(f) != 0 }
|
||||||
|
u8, u16, u32, u64 { return u64(f) != 0 }
|
||||||
|
f32, f64 { return f64(f) != 0.0 }
|
||||||
|
else { return false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// arr uses `Any` as an array.
|
// arr uses `Any` as an array.
|
||||||
pub fn (f Any) arr() []Any {
|
pub fn (f Any) arr() []Any {
|
||||||
if f is []Any {
|
if f is []Any {
|
||||||
|
@ -125,11 +109,18 @@ pub fn (f Any) arr() []Any {
|
||||||
return [f]
|
return [f]
|
||||||
}
|
}
|
||||||
|
|
||||||
// bool uses `Any` as a bool
|
// as_map uses `Any` as a map.
|
||||||
pub fn (f Any) bool() bool {
|
pub fn (f Any) as_map() map[string]Any {
|
||||||
match f {
|
if f is map[string]Any {
|
||||||
bool { return f }
|
return f
|
||||||
string { return f.bool() }
|
} else if f is []Any {
|
||||||
else { return false }
|
mut mp := map[string]Any{}
|
||||||
|
for i, fi in f {
|
||||||
|
mp['${i}'] = fi
|
||||||
|
}
|
||||||
|
return mp
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
'0': f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
56
vlib/x/json2/types.v
Normal file
56
vlib/x/json2/types.v
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
module json2
|
||||||
|
|
||||||
|
// `Any` is a sum type that lists the possible types to be decoded and used.
|
||||||
|
pub type Any = Null
|
||||||
|
| []Any
|
||||||
|
| []int
|
||||||
|
| bool
|
||||||
|
| f32
|
||||||
|
| f64
|
||||||
|
| i16
|
||||||
|
| i64
|
||||||
|
| i8
|
||||||
|
| int
|
||||||
|
| map[string]Any
|
||||||
|
| string
|
||||||
|
| u16
|
||||||
|
| u32
|
||||||
|
| u64
|
||||||
|
| u8
|
||||||
|
|
||||||
|
// Decodable is an interface, that allows custom implementations for decoding structs from JSON encoded values
|
||||||
|
pub interface Decodable {
|
||||||
|
from_json(f Any)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decodable is an interface, that allows custom implementations for encoding structs to their string based JSON representations
|
||||||
|
pub interface Encodable {
|
||||||
|
json_str() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// `Null` struct is a simple representation of the `null` value in JSON.
|
||||||
|
pub struct Null {
|
||||||
|
is_null bool = true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const null = Null{}
|
||||||
|
|
||||||
|
// ValueKind enumerates the kinds of possible values of the Any sumtype.
|
||||||
|
pub enum ValueKind {
|
||||||
|
unknown
|
||||||
|
array
|
||||||
|
object
|
||||||
|
string_
|
||||||
|
number
|
||||||
|
}
|
||||||
|
|
||||||
|
// str returns the string representation of the specific ValueKind
|
||||||
|
pub fn (k ValueKind) str() string {
|
||||||
|
return match k {
|
||||||
|
.unknown { 'unknown' }
|
||||||
|
.array { 'array' }
|
||||||
|
.object { 'object' }
|
||||||
|
.string_ { 'string' }
|
||||||
|
.number { 'number' }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user