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 json2.Any('true').bool() == true
|
||||
// invalid conversions
|
||||
assert sample_data['int'] or { 0 }.bool() == false
|
||||
assert sample_data['i64'] or { 0 }.bool() == false
|
||||
assert sample_data['f32'] or { 0 }.bool() == false
|
||||
assert sample_data['f64'] or { 0 }.bool() == false
|
||||
assert sample_data['int'] or { 0 }.bool() == true
|
||||
assert sample_data['i64'] or { 0 }.bool() == true
|
||||
assert sample_data['f32'] or { 0 }.bool() == true
|
||||
assert sample_data['f64'] or { 0 }.bool() == true
|
||||
assert sample_data['null'] or { 0 }.bool() == false
|
||||
assert sample_data['arr'] or { 0 }.bool() == false
|
||||
assert sample_data['obj'] or { 0 }.bool() == false
|
||||
|
@ -3,43 +3,6 @@
|
||||
// that can be found in the LICENSE file.
|
||||
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 {
|
||||
return '[x.json2] ${msg} (${line}:${column})'
|
||||
}
|
||||
|
@ -16,8 +16,7 @@ pub struct Encoder {
|
||||
|
||||
pub const default_encoder = Encoder{}
|
||||
|
||||
// byte array versions of the most common tokens/chars
|
||||
// to avoid reallocations
|
||||
// byte array versions of the most common tokens/chars to avoid reallocations
|
||||
const null_in_bytes = 'null'.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)!
|
||||
}
|
||||
}
|
||||
int, u64, i64 {
|
||||
i8, i16, int, i64 {
|
||||
wr.write(val.str().bytes())!
|
||||
}
|
||||
u8, u16, u32, u64 {
|
||||
wr.write(val.str().bytes())!
|
||||
}
|
||||
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)!
|
||||
} $else $if T is []Any {
|
||||
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)!
|
||||
} $else $if T is Encodable {
|
||||
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
|
||||
|
||||
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.
|
||||
pub fn raw_decode(src string) !Any {
|
||||
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 {
|
||||
dump(err)
|
||||
default_encoder.encode_value<Null>(json2.null, mut sb) or {}
|
||||
default_encoder.encode_value<Null>(null, mut sb) or {}
|
||||
}
|
||||
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.
|
||||
pub fn (f Any) int() int {
|
||||
match 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 }
|
||||
}
|
||||
}
|
||||
@ -79,7 +51,7 @@ pub fn (f Any) int() int {
|
||||
pub fn (f Any) i64() i64 {
|
||||
match 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 }
|
||||
}
|
||||
}
|
||||
@ -88,7 +60,7 @@ pub fn (f Any) i64() i64 {
|
||||
pub fn (f Any) u64() u64 {
|
||||
match 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 }
|
||||
}
|
||||
}
|
||||
@ -97,20 +69,32 @@ pub fn (f Any) u64() u64 {
|
||||
pub fn (f Any) f32() f32 {
|
||||
match 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 }
|
||||
}
|
||||
}
|
||||
|
||||
// f64 uses `Any` as a float.
|
||||
// f64 uses `Any` as a 64-bit float.
|
||||
pub fn (f Any) f64() f64 {
|
||||
match 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 }
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
pub fn (f Any) arr() []Any {
|
||||
if f is []Any {
|
||||
@ -125,11 +109,18 @@ pub fn (f Any) arr() []Any {
|
||||
return [f]
|
||||
}
|
||||
|
||||
// bool uses `Any` as a bool
|
||||
pub fn (f Any) bool() bool {
|
||||
match f {
|
||||
bool { return f }
|
||||
string { return f.bool() }
|
||||
else { return false }
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
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