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

json2: small refactor (#16913)

This commit is contained in:
Hitalo Souza 2023-06-27 14:07:44 -03:00 committed by GitHub
parent d523bb0306
commit aeebb4f118
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 17 deletions

View File

@ -61,17 +61,17 @@ pub fn (err UnknownTokenError) msg() string {
struct Parser {
pub mut:
scanner &Scanner = unsafe { nil }
p_tok Token
prev_tok Token
tok Token
n_tok Token
next_tok Token
n_level int
convert_type bool = true
}
fn (mut p Parser) next() {
p.p_tok = p.tok
p.tok = p.n_tok
p.n_tok = p.scanner.scan()
p.prev_tok = p.tok
p.tok = p.next_tok
p.next_tok = p.scanner.scan()
}
fn (mut p Parser) next_with_err() ! {
@ -87,6 +87,9 @@ fn (mut p Parser) next_with_err() ! {
// TODO: copied from v.util to avoid the entire module and its functions
// from being imported. remove later once -skip-unused is enabled by default.
// skip_bom - skip Byte Order Mark (BOM)
// The UTF-8 BOM is a sequence of Bytes at the start of a text-stream (EF BB BF or \ufeff)
// that allows the reader to reliably determine if file is being encoded in UTF-8.
fn skip_bom(file_content string) string {
mut raw_text := file_content
// BOM check
@ -103,6 +106,7 @@ fn skip_bom(file_content string) string {
return raw_text
}
// new_parser - create a instance of Parser{}
fn new_parser(srce string, convert_type bool) Parser {
src := skip_bom(srce)
return Parser{
@ -113,7 +117,7 @@ fn new_parser(srce string, convert_type bool) Parser {
}
}
// decode decodes provided JSON
// decode - decodes provided JSON
pub fn (mut p Parser) decode() !Any {
p.next()
p.next_with_err()!
@ -133,9 +137,11 @@ fn (mut p Parser) decode_value() !Any {
}
}
match p.tok.kind {
// `[`
.lsbr {
return p.decode_array()
}
// `{`
.lcbr {
return p.decode_object()
}
@ -187,6 +193,7 @@ fn (mut p Parser) decode_array() !Any {
mut items := []Any{}
p.next_with_err()!
p.n_level++
// `]`
for p.tok.kind != .rsbr {
item := p.decode_value()!
items << item
@ -213,7 +220,9 @@ fn (mut p Parser) decode_object() !Any {
mut fields := map[string]Any{}
p.next_with_err()!
p.n_level++
// `}`
for p.tok.kind != .rcbr {
// step 1 -> key
if p.tok.kind != .str_ {
return InvalidTokenError{
token: p.tok
@ -223,6 +232,7 @@ fn (mut p Parser) decode_object() !Any {
cur_key := p.tok.lit.bytestr()
p.next_with_err()!
// step 2 -> colon separator
if p.tok.kind != .colon {
return InvalidTokenError{
token: p.tok
@ -231,6 +241,7 @@ fn (mut p Parser) decode_object() !Any {
}
p.next_with_err()!
// step 3 -> value
fields[cur_key] = p.decode_value()!
if p.tok.kind != .comma && p.tok.kind != .rcbr {
return UnknownTokenError{
@ -242,6 +253,7 @@ fn (mut p Parser) decode_object() !Any {
}
}
p.next_with_err()!
// step 4 -> eof (end)
p.n_level--
return Any(fields)
}

View File

@ -146,6 +146,8 @@ pub fn decode[T](src string) !T {
else {}
}
}
} $else {
return error("The type `${T.name}` can't be decoded.")
}
return typ
}

View File

@ -8,7 +8,7 @@ import strconv
struct Scanner {
mut:
text []u8
pos int
pos int // the position of the token in scanner text
line int
col int
}
@ -22,19 +22,19 @@ enum TokenKind {
null
bool_
eof
comma = 44
colon = 58
lsbr = 91
rsbr = 93
lcbr = 123
rcbr = 125
comma = 44 // ,
colon = 58 // :
lsbr = 91 // [
rsbr = 93 // ]
lcbr = 123 // {
rcbr = 125 // }
}
pub struct Token {
lit []u8
kind TokenKind
line int
col int
lit []u8 // literal representation of the token
kind TokenKind // the token number/enum; for quick comparisons
line int // the line in the source where the token occured
col int // the column in the source where the token occured
}
// full_col returns the full column information which includes the length
@ -256,6 +256,7 @@ fn (s Scanner) invalid_token() Token {
}
// scan returns a token based on the scanner's current position.
// used to set the next token
[manualfree]
fn (mut s Scanner) scan() Token {
if s.pos < s.text.len && (s.text[s.pos] == ` ` || s.text[s.pos] in json2.newlines) {