diff --git a/vlib/x/json2/decoder2/attributes_test.v b/vlib/x/json2/decoder2/attributes_test.v index 8458c63759..8fe9d9ce0a 100644 --- a/vlib/x/json2/decoder2/attributes_test.v +++ b/vlib/x/json2/decoder2/attributes_test.v @@ -38,6 +38,16 @@ struct StruWithRequiredAttribute { b int } +struct Foo { + a int @[required] +} + +fn test_last_field_requiered() { + assert json.decode[Foo]('{"a":0}')! == Foo{ + a: 0 + } +} + fn test_skip_and_rename_attributes() { assert json.decode[StruWithJsonAttribute]('{"name": "hola1", "a": 2, "b": 3}')! == StruWithJsonAttribute{ a: 2 diff --git a/vlib/x/json2/decoder2/decode.v b/vlib/x/json2/decoder2/decode.v index 086e8a3dba..b69bbd446b 100644 --- a/vlib/x/json2/decoder2/decode.v +++ b/vlib/x/json2/decoder2/decode.v @@ -904,8 +904,18 @@ fn (mut decoder Decoder) decode_enum[T](mut val T) ! { return } } - decoder.decode_error('Number value: ${result} does not match any field in enum: ${typeof(val).name}')! + decoder.decode_error('Number value: `${result}` does not match any field in enum: ${typeof(val).name}')! } else if enum_info.value_kind == .string { + mut result := '' + unsafe { decoder.decode_value(mut result)! } + + $for value in T.values { + if value.name == result { + val = value.value + return + } + } + decoder.decode_error('String value: `${result}` does not match any field in enum: ${typeof(val).name}')! } decoder.decode_error('Expected number or string value for enum, got: ${enum_info.value_kind}')! diff --git a/vlib/x/json2/decoder2/tests/decode_enum_test.v b/vlib/x/json2/decoder2/tests/decode_enum_test.v new file mode 100644 index 0000000000..9473ce1a7e --- /dev/null +++ b/vlib/x/json2/decoder2/tests/decode_enum_test.v @@ -0,0 +1,95 @@ +import x.json2.decoder2 as json + +enum Bar { + a + b + c = 10 +} + +type BarAlias = Bar + +fn test_number_decode() { + assert json.decode[Bar]('0')! == Bar.a + assert json.decode[Bar]('1')! == Bar.b + assert json.decode[Bar]('10')! == Bar.c + + assert json.decode[BarAlias]('0')! == Bar.a + assert json.decode[BarAlias]('1')! == Bar.b + assert json.decode[BarAlias]('10')! == Bar.c +} + +fn test_number_decode_fails() { + if _ := json.decode[Bar]('2') { + assert false + } else { + if err is json.JsonDecodeError { + assert err.line == 1 + assert err.character == 1 + assert err.message == 'Data: Number value: `2` does not match any field in enum: &Bar' + } + } + + if _ := json.decode[BarAlias]('2') { + assert false + } else { + if err is json.JsonDecodeError { + assert err.line == 1 + assert err.character == 1 + assert err.message == 'Data: Number value: `2` does not match any field in enum: &BarAlias' + } + } +} + +fn test_string_decode() { + assert json.decode[Bar]('"a"')! == Bar.a + assert json.decode[Bar]('"b"')! == Bar.b + assert json.decode[Bar]('"c"')! == Bar.c + + assert json.decode[BarAlias]('"a"')! == Bar.a + assert json.decode[BarAlias]('"b"')! == Bar.b + assert json.decode[BarAlias]('"c"')! == Bar.c +} + +fn test_string_decode_fails() { + if _ := json.decode[Bar]('"d"') { + assert false + } else { + if err is json.JsonDecodeError { + assert err.line == 1 + assert err.character == 1 + assert err.message == 'Data: String value: `d` does not match any field in enum: &Bar' + } + } + + if _ := json.decode[BarAlias]('"d"') { + assert false + } else { + if err is json.JsonDecodeError { + assert err.line == 1 + assert err.character == 1 + assert err.message == 'Data: String value: `d` does not match any field in enum: &BarAlias' + } + } +} + +fn test_invalid_decode_fails() { + if _ := json.decode[Bar]('true') { + assert false + } else { + if err is json.JsonDecodeError { + assert err.line == 1 + assert err.character == 1 + assert err.message == 'Data: Expected number or string value for enum, got: boolean' + } + } + + if _ := json.decode[BarAlias]('true') { + assert false + } else { + if err is json.JsonDecodeError { + assert err.line == 1 + assert err.character == 1 + assert err.message == 'Data: Expected number or string value for enum, got: boolean' + } + } +} diff --git a/vlib/x/json2/decoder2/tests/decode_escaped_string_test.v b/vlib/x/json2/decoder2/tests/decode_escaped_string_test.v index d3e437895a..59a65a8e94 100644 --- a/vlib/x/json2/decoder2/tests/decode_escaped_string_test.v +++ b/vlib/x/json2/decoder2/tests/decode_escaped_string_test.v @@ -3,7 +3,7 @@ import x.json2.decoder2 fn test_decode_escaped_string() { escaped_strings := ['test', 'test\\sd', 'test\nsd', '\ntest', 'test\\"', 'test\\', 'test\u1234ps', - 'test\u1234', '\u1234\\\t"', ''] + 'test\u1234', '\u1234\\\t"', '', '\uff0f', 'test \uff0f test', '😀', 'text 😀 text'] json_string := json2.encode[[]string](escaped_strings) decoded_strings := decoder2.decode[[]string](json_string)!