1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

x.json2: add customized JSON output capability via Encoder (#13654)

This commit is contained in:
Ned
2022-03-04 19:39:23 +08:00
committed by GitHub
parent 74d5106e8f
commit 437fa02f27
6 changed files with 275 additions and 168 deletions

View File

@@ -236,13 +236,13 @@ fn to_alexcrichton(value ast.Value, array_type int) string {
match value {
ast.Quoted {
json_text := json2.Any(value.text).json_str()
return '{ "type": "string", "value": "$json_text" }'
return '{ "type": "string", "value": $json_text }'
}
ast.DateTime {
// Normalization for json
mut json_text := json2.Any(value.text).json_str().to_upper().replace(' ',
'T')
typ := if json_text.ends_with('Z') || json_text.all_after('T').contains('-')
typ := if json_text.ends_with('Z"') || json_text.all_after('T').contains('-')
|| json_text.all_after('T').contains('+') {
'datetime'
} else {
@@ -252,16 +252,16 @@ fn to_alexcrichton(value ast.Value, array_type int) string {
// It seems it's implementation specific how time and
// date-time values are represented in detail. For now we follow the BurntSushi format
// that expands to 6 digits which is also a valid RFC 3339 representation.
json_text = to_alexcrichton_time(json_text)
json_text = to_alexcrichton_time(json_text[1..json_text.len - 1])
return '{ "type": "$typ", "value": "$json_text" }'
}
ast.Date {
json_text := json2.Any(value.text).json_str()
return '{ "type": "date", "value": "$json_text" }'
return '{ "type": "date", "value": $json_text }'
}
ast.Time {
mut json_text := json2.Any(value.text).json_str()
json_text = to_alexcrichton_time(json_text)
json_text = to_alexcrichton_time(json_text[1..json_text.len - 1])
return '{ "type": "time", "value": "$json_text" }'
}
ast.Bool {
@@ -270,12 +270,12 @@ fn to_alexcrichton(value ast.Value, array_type int) string {
}
ast.Null {
json_text := json2.Any(value.text).json_str()
return '{ "type": "null", "value": "$json_text" }'
return '{ "type": "null", "value": $json_text }'
}
ast.Number {
text := value.text
if text.contains('inf') || text.contains('nan') {
return '{ "type": "float", "value": "$value.text" }'
return '{ "type": "float", "value": $value.text }'
}
if !text.starts_with('0x') && (text.contains('.') || text.to_lower().contains('e')) {
mut val := ''
@@ -297,7 +297,7 @@ fn to_alexcrichton(value ast.Value, array_type int) string {
mut str := '{ '
for key, val in value {
json_key := json2.Any(key).json_str()
str += ' "$json_key": ${to_alexcrichton(val, array_type)},'
str += ' $json_key: ${to_alexcrichton(val, array_type)},'
}
str = str.trim_right(',')
str += ' }'

View File

@@ -199,26 +199,30 @@ fn to_burntsushi(value ast.Value) string {
match value {
ast.Quoted {
json_text := json2.Any(value.text).json_str()
return '{ "type": "string", "value": "$json_text" }'
return '{ "type": "string", "value": $json_text }'
}
ast.DateTime {
// Normalization for json
json_text := json2.Any(value.text).json_str().to_upper().replace(' ', 'T')
typ := if json_text.ends_with('Z') || json_text.all_after('T').contains('-')
// NB: Since encoding strings in JSON now automatically includes quotes,
// I added a somewhat a workaround by adding an ending quote in order to
// recognize properly the date time type. - Ned
typ := if json_text.ends_with('Z"') || json_text.all_after('T').contains('-')
|| json_text.all_after('T').contains('+') {
'datetime'
} else {
'datetime-local'
}
return '{ "type": "$typ", "value": "$json_text" }'
return '{ "type": "$typ", "value": $json_text }'
}
ast.Date {
json_text := json2.Any(value.text).json_str()
return '{ "type": "date-local", "value": "$json_text" }'
return '{ "type": "date-local", "value": $json_text }'
}
ast.Time {
json_text := json2.Any(value.text).json_str()
return '{ "type": "time-local", "value": "$json_text" }'
return '{ "type": "time-local", "value": $json_text }'
}
ast.Bool {
json_text := json2.Any(value.text.bool()).json_str()
@@ -226,7 +230,7 @@ fn to_burntsushi(value ast.Value) string {
}
ast.Null {
json_text := json2.Any(value.text).json_str()
return '{ "type": "null", "value": "$json_text" }'
return '{ "type": "null", "value": $json_text }'
}
ast.Number {
if value.text.contains('inf') || value.text.contains('nan') {
@@ -251,7 +255,7 @@ fn to_burntsushi(value ast.Value) string {
mut str := '{ '
for key, val in value {
json_key := json2.Any(key).json_str()
str += ' "$json_key": ${to_burntsushi(val)},'
str += ' $json_key: ${to_burntsushi(val)},'
}
str = str.trim_right(',')
str += ' }'

View File

@@ -288,15 +288,15 @@ fn to_iarna(value ast.Value, skip_value_map bool) string {
ast.Quoted {
json_text := json2.Any(value.text).json_str()
if skip_value_map {
return '"$json_text"'
return json_text
}
return '{ "type": "string", "value": "$json_text" }'
return '{ "type": "string", "value": $json_text }'
}
ast.DateTime {
// Normalization for json
mut json_text := json2.Any(value.text).json_str().to_upper().replace(' ',
'T')
typ := if json_text.ends_with('Z') || json_text.all_after('T').contains('-')
typ := if json_text.ends_with('Z"') || json_text.all_after('T').contains('-')
|| json_text.all_after('T').contains('+') {
'datetime'
} else {
@@ -306,40 +306,41 @@ fn to_iarna(value ast.Value, skip_value_map bool) string {
// It seems it's implementation specific how time and
// date-time values are represented in detail. For now we follow the BurntSushi format
// that expands to 6 digits which is also a valid RFC 3339 representation.
json_text = to_iarna_time(json_text)
json_text = to_iarna_time(json_text[1..json_text.len - 1])
if skip_value_map {
return '"$json_text"'
return json_text
}
return '{ "type": "$typ", "value": "$json_text" }'
}
ast.Date {
json_text := json2.Any(value.text).json_str()
if skip_value_map {
return '"$json_text"'
return json_text
}
return '{ "type": "date", "value": "$json_text" }'
return '{ "type": "date", "value": $json_text }'
}
ast.Time {
mut json_text := json2.Any(value.text).json_str()
json_text = to_iarna_time(json_text)
// NB: Removes the quotes of the encoded JSON string - Ned
json_text = to_iarna_time(json_text[1..json_text.len - 1])
if skip_value_map {
return '"$json_text"'
return json_text
}
return '{ "type": "time", "value": "$json_text" }'
}
ast.Bool {
json_text := json2.Any(value.text.bool()).json_str()
if skip_value_map {
return '$json_text'
return json_text
}
return '{ "type": "bool", "value": "$json_text" }'
}
ast.Null {
json_text := json2.Any(value.text).json_str()
if skip_value_map {
return '$json_text'
return json_text
}
return '{ "type": "null", "value": "$json_text" }'
return '{ "type": "null", "value": $json_text }'
}
ast.Number {
if value.text.contains('inf') {
@@ -384,7 +385,7 @@ fn to_iarna(value ast.Value, skip_value_map bool) string {
mut str := '{ '
for key, val in value {
json_key := json2.Any(key).json_str()
str += ' "$json_key": ${to_iarna(val, skip_value_map)},'
str += ' $json_key: ${to_iarna(val, skip_value_map)},'
}
str = str.trim_right(',')
str += ' }'