more modules updated
This commit is contained in:
parent
e07b833439
commit
e12f9518cc
3 changed files with 62 additions and 62 deletions
|
|
@ -82,7 +82,7 @@ type
|
||||||
stateEof, stateStart, stateObject, stateArray, stateExpectArrayComma,
|
stateEof, stateStart, stateObject, stateArray, stateExpectArrayComma,
|
||||||
stateExpectObjectComma, stateExpectColon, stateExpectValue
|
stateExpectObjectComma, stateExpectColon, stateExpectValue
|
||||||
|
|
||||||
JsonParser* = object of TBaseLexer ## the parser object.
|
JsonParser* = object of BaseLexer ## the parser object.
|
||||||
a: string
|
a: string
|
||||||
tok: TTokKind
|
tok: TTokKind
|
||||||
kind: JsonEventKind
|
kind: JsonEventKind
|
||||||
|
|
@ -119,7 +119,7 @@ const
|
||||||
"{", "}", "[", "]", ":", ","
|
"{", "}", "[", "]", ":", ","
|
||||||
]
|
]
|
||||||
|
|
||||||
proc open*(my: var JsonParser, input: PStream, filename: string) =
|
proc open*(my: var JsonParser, input: Stream, filename: string) =
|
||||||
## initializes the parser with an input stream. `Filename` is only used
|
## initializes the parser with an input stream. `Filename` is only used
|
||||||
## for nice error messages.
|
## for nice error messages.
|
||||||
lexbase.open(my, input)
|
lexbase.open(my, input)
|
||||||
|
|
@ -224,7 +224,7 @@ proc parseString(my: var JsonParser): TTokKind =
|
||||||
if handleHexChar(buf[pos], r): inc(pos)
|
if handleHexChar(buf[pos], r): inc(pos)
|
||||||
if handleHexChar(buf[pos], r): inc(pos)
|
if handleHexChar(buf[pos], r): inc(pos)
|
||||||
if handleHexChar(buf[pos], r): inc(pos)
|
if handleHexChar(buf[pos], r): inc(pos)
|
||||||
add(my.a, toUTF8(TRune(r)))
|
add(my.a, toUTF8(Rune(r)))
|
||||||
else:
|
else:
|
||||||
# don't bother with the error
|
# don't bother with the error
|
||||||
add(my.a, buf[pos])
|
add(my.a, buf[pos])
|
||||||
|
|
@ -402,7 +402,7 @@ proc next*(my: var JsonParser) =
|
||||||
case tk
|
case tk
|
||||||
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
||||||
my.state[i] = stateEof # expect EOF next!
|
my.state[i] = stateEof # expect EOF next!
|
||||||
my.kind = TJsonEventKind(ord(tk))
|
my.kind = JsonEventKind(ord(tk))
|
||||||
of tkBracketLe:
|
of tkBracketLe:
|
||||||
my.state.add(stateArray) # we expect any
|
my.state.add(stateArray) # we expect any
|
||||||
my.kind = jsonArrayStart
|
my.kind = jsonArrayStart
|
||||||
|
|
@ -418,7 +418,7 @@ proc next*(my: var JsonParser) =
|
||||||
case tk
|
case tk
|
||||||
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
||||||
my.state.add(stateExpectColon)
|
my.state.add(stateExpectColon)
|
||||||
my.kind = TJsonEventKind(ord(tk))
|
my.kind = JsonEventKind(ord(tk))
|
||||||
of tkBracketLe:
|
of tkBracketLe:
|
||||||
my.state.add(stateExpectColon)
|
my.state.add(stateExpectColon)
|
||||||
my.state.add(stateArray)
|
my.state.add(stateArray)
|
||||||
|
|
@ -437,7 +437,7 @@ proc next*(my: var JsonParser) =
|
||||||
case tk
|
case tk
|
||||||
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
||||||
my.state.add(stateExpectArrayComma) # expect value next!
|
my.state.add(stateExpectArrayComma) # expect value next!
|
||||||
my.kind = TJsonEventKind(ord(tk))
|
my.kind = JsonEventKind(ord(tk))
|
||||||
of tkBracketLe:
|
of tkBracketLe:
|
||||||
my.state.add(stateExpectArrayComma)
|
my.state.add(stateExpectArrayComma)
|
||||||
my.state.add(stateArray)
|
my.state.add(stateArray)
|
||||||
|
|
@ -488,7 +488,7 @@ proc next*(my: var JsonParser) =
|
||||||
case tk
|
case tk
|
||||||
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull:
|
||||||
my.state[i] = stateExpectObjectComma
|
my.state[i] = stateExpectObjectComma
|
||||||
my.kind = TJsonEventKind(ord(tk))
|
my.kind = JsonEventKind(ord(tk))
|
||||||
of tkBracketLe:
|
of tkBracketLe:
|
||||||
my.state[i] = stateExpectObjectComma
|
my.state[i] = stateExpectObjectComma
|
||||||
my.state.add(stateArray)
|
my.state.add(stateArray)
|
||||||
|
|
@ -505,7 +505,7 @@ proc next*(my: var JsonParser) =
|
||||||
# ------------- higher level interface ---------------------------------------
|
# ------------- higher level interface ---------------------------------------
|
||||||
|
|
||||||
type
|
type
|
||||||
TJsonNodeKind* = enum ## possible JSON node types
|
JsonNodeKind* = enum ## possible JSON node types
|
||||||
JNull,
|
JNull,
|
||||||
JBool,
|
JBool,
|
||||||
JInt,
|
JInt,
|
||||||
|
|
@ -514,9 +514,9 @@ type
|
||||||
JObject,
|
JObject,
|
||||||
JArray
|
JArray
|
||||||
|
|
||||||
PJsonNode* = ref TJsonNode ## JSON node
|
JsonNode* = ref JsonNodeObj ## JSON node
|
||||||
TJsonNode* {.final, pure, acyclic.} = object
|
JsonNodeObj* {.acyclic.} = object
|
||||||
case kind*: TJsonNodeKind
|
case kind*: JsonNodeKind
|
||||||
of JString:
|
of JString:
|
||||||
str*: string
|
str*: string
|
||||||
of JInt:
|
of JInt:
|
||||||
|
|
@ -528,104 +528,104 @@ type
|
||||||
of JNull:
|
of JNull:
|
||||||
nil
|
nil
|
||||||
of JObject:
|
of JObject:
|
||||||
fields*: seq[tuple[key: string, val: PJsonNode]]
|
fields*: seq[tuple[key: string, val: JsonNode]]
|
||||||
of JArray:
|
of JArray:
|
||||||
elems*: seq[PJsonNode]
|
elems*: seq[JsonNode]
|
||||||
|
|
||||||
JsonParsingError* = object of ValueError ## is raised for a JSON error
|
JsonParsingError* = object of ValueError ## is raised for a JSON error
|
||||||
|
|
||||||
{.deprecated: [EJsonParsingError: JsonParsingError, TJsonNode: JsonNodeObj,
|
{.deprecated: [EJsonParsingError: JsonParsingError, TJsonNode: JsonNodeObj,
|
||||||
PJsonNode: JsonNode, TJsonNodeKind: JsonNodeKind].}
|
PJsonNode: JsonNode, TJsonNodeKind: JsonNodeKind].}
|
||||||
|
|
||||||
proc raiseParseErr*(p: TJsonParser, msg: string) {.noinline, noreturn.} =
|
proc raiseParseErr*(p: JsonParser, msg: string) {.noinline, noreturn.} =
|
||||||
## raises an `EJsonParsingError` exception.
|
## raises an `EJsonParsingError` exception.
|
||||||
raise newException(EJsonParsingError, errorMsgExpected(p, msg))
|
raise newException(JsonParsingError, errorMsgExpected(p, msg))
|
||||||
|
|
||||||
proc newJString*(s: string): PJsonNode =
|
proc newJString*(s: string): JsonNode =
|
||||||
## Creates a new `JString PJsonNode`.
|
## Creates a new `JString PJsonNode`.
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = JString
|
result.kind = JString
|
||||||
result.str = s
|
result.str = s
|
||||||
|
|
||||||
proc newJStringMove(s: string): PJsonNode =
|
proc newJStringMove(s: string): JsonNode =
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = JString
|
result.kind = JString
|
||||||
shallowCopy(result.str, s)
|
shallowCopy(result.str, s)
|
||||||
|
|
||||||
proc newJInt*(n: BiggestInt): PJsonNode =
|
proc newJInt*(n: BiggestInt): JsonNode =
|
||||||
## Creates a new `JInt PJsonNode`.
|
## Creates a new `JInt PJsonNode`.
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = JInt
|
result.kind = JInt
|
||||||
result.num = n
|
result.num = n
|
||||||
|
|
||||||
proc newJFloat*(n: float): PJsonNode =
|
proc newJFloat*(n: float): JsonNode =
|
||||||
## Creates a new `JFloat PJsonNode`.
|
## Creates a new `JFloat PJsonNode`.
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = JFloat
|
result.kind = JFloat
|
||||||
result.fnum = n
|
result.fnum = n
|
||||||
|
|
||||||
proc newJBool*(b: bool): PJsonNode =
|
proc newJBool*(b: bool): JsonNode =
|
||||||
## Creates a new `JBool PJsonNode`.
|
## Creates a new `JBool PJsonNode`.
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = JBool
|
result.kind = JBool
|
||||||
result.bval = b
|
result.bval = b
|
||||||
|
|
||||||
proc newJNull*(): PJsonNode =
|
proc newJNull*(): JsonNode =
|
||||||
## Creates a new `JNull PJsonNode`.
|
## Creates a new `JNull PJsonNode`.
|
||||||
new(result)
|
new(result)
|
||||||
|
|
||||||
proc newJObject*(): PJsonNode =
|
proc newJObject*(): JsonNode =
|
||||||
## Creates a new `JObject PJsonNode`
|
## Creates a new `JObject PJsonNode`
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = JObject
|
result.kind = JObject
|
||||||
result.fields = @[]
|
result.fields = @[]
|
||||||
|
|
||||||
proc newJArray*(): PJsonNode =
|
proc newJArray*(): JsonNode =
|
||||||
## Creates a new `JArray PJsonNode`
|
## Creates a new `JArray PJsonNode`
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = JArray
|
result.kind = JArray
|
||||||
result.elems = @[]
|
result.elems = @[]
|
||||||
|
|
||||||
|
|
||||||
proc `%`*(s: string): PJsonNode =
|
proc `%`*(s: string): JsonNode =
|
||||||
## Generic constructor for JSON data. Creates a new `JString PJsonNode`.
|
## Generic constructor for JSON data. Creates a new `JString PJsonNode`.
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = JString
|
result.kind = JString
|
||||||
result.str = s
|
result.str = s
|
||||||
|
|
||||||
proc `%`*(n: BiggestInt): PJsonNode =
|
proc `%`*(n: BiggestInt): JsonNode =
|
||||||
## Generic constructor for JSON data. Creates a new `JInt PJsonNode`.
|
## Generic constructor for JSON data. Creates a new `JInt PJsonNode`.
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = JInt
|
result.kind = JInt
|
||||||
result.num = n
|
result.num = n
|
||||||
|
|
||||||
proc `%`*(n: float): PJsonNode =
|
proc `%`*(n: float): JsonNode =
|
||||||
## Generic constructor for JSON data. Creates a new `JFloat PJsonNode`.
|
## Generic constructor for JSON data. Creates a new `JFloat PJsonNode`.
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = JFloat
|
result.kind = JFloat
|
||||||
result.fnum = n
|
result.fnum = n
|
||||||
|
|
||||||
proc `%`*(b: bool): PJsonNode =
|
proc `%`*(b: bool): JsonNode =
|
||||||
## Generic constructor for JSON data. Creates a new `JBool PJsonNode`.
|
## Generic constructor for JSON data. Creates a new `JBool PJsonNode`.
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = JBool
|
result.kind = JBool
|
||||||
result.bval = b
|
result.bval = b
|
||||||
|
|
||||||
proc `%`*(keyVals: openArray[tuple[key: string, val: PJsonNode]]): PJsonNode =
|
proc `%`*(keyVals: openArray[tuple[key: string, val: JsonNode]]): JsonNode =
|
||||||
## Generic constructor for JSON data. Creates a new `JObject PJsonNode`
|
## Generic constructor for JSON data. Creates a new `JObject PJsonNode`
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = JObject
|
result.kind = JObject
|
||||||
newSeq(result.fields, keyVals.len)
|
newSeq(result.fields, keyVals.len)
|
||||||
for i, p in pairs(keyVals): result.fields[i] = p
|
for i, p in pairs(keyVals): result.fields[i] = p
|
||||||
|
|
||||||
proc `%`*(elements: openArray[PJsonNode]): PJsonNode =
|
proc `%`*(elements: openArray[JsonNode]): JsonNode =
|
||||||
## Generic constructor for JSON data. Creates a new `JArray PJsonNode`
|
## Generic constructor for JSON data. Creates a new `JArray PJsonNode`
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = JArray
|
result.kind = JArray
|
||||||
newSeq(result.elems, elements.len)
|
newSeq(result.elems, elements.len)
|
||||||
for i, p in pairs(elements): result.elems[i] = p
|
for i, p in pairs(elements): result.elems[i] = p
|
||||||
|
|
||||||
proc `==`* (a,b: PJsonNode): bool =
|
proc `==`* (a,b: JsonNode): bool =
|
||||||
## Check two nodes for equality
|
## Check two nodes for equality
|
||||||
if a.isNil:
|
if a.isNil:
|
||||||
if b.isNil: return true
|
if b.isNil: return true
|
||||||
|
|
@ -649,7 +649,7 @@ proc `==`* (a,b: PJsonNode): bool =
|
||||||
of JObject:
|
of JObject:
|
||||||
a.fields == b.fields
|
a.fields == b.fields
|
||||||
|
|
||||||
proc hash* (n:PJsonNode): THash =
|
proc hash* (n:JsonNode): THash =
|
||||||
## Compute the hash for a JSON node
|
## Compute the hash for a JSON node
|
||||||
case n.kind
|
case n.kind
|
||||||
of JArray:
|
of JArray:
|
||||||
|
|
@ -667,7 +667,7 @@ proc hash* (n:PJsonNode): THash =
|
||||||
of JNull:
|
of JNull:
|
||||||
result = hash(0)
|
result = hash(0)
|
||||||
|
|
||||||
proc len*(n: PJsonNode): int =
|
proc len*(n: JsonNode): int =
|
||||||
## If `n` is a `JArray`, it returns the number of elements.
|
## If `n` is a `JArray`, it returns the number of elements.
|
||||||
## If `n` is a `JObject`, it returns the number of pairs.
|
## If `n` is a `JObject`, it returns the number of pairs.
|
||||||
## Else it returns 0.
|
## Else it returns 0.
|
||||||
|
|
@ -676,7 +676,7 @@ proc len*(n: PJsonNode): int =
|
||||||
of JObject: result = n.fields.len
|
of JObject: result = n.fields.len
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
proc `[]`*(node: PJsonNode, name: string): PJsonNode =
|
proc `[]`*(node: JsonNode, name: string): JsonNode =
|
||||||
## Gets a field from a `JObject`, which must not be nil.
|
## Gets a field from a `JObject`, which must not be nil.
|
||||||
## If the value at `name` does not exist, returns nil
|
## If the value at `name` does not exist, returns nil
|
||||||
assert(not isNil(node))
|
assert(not isNil(node))
|
||||||
|
|
@ -686,35 +686,35 @@ proc `[]`*(node: PJsonNode, name: string): PJsonNode =
|
||||||
return item
|
return item
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
proc `[]`*(node: PJsonNode, index: int): PJsonNode =
|
proc `[]`*(node: JsonNode, index: int): JsonNode =
|
||||||
## Gets the node at `index` in an Array. Result is undefined if `index`
|
## Gets the node at `index` in an Array. Result is undefined if `index`
|
||||||
## is out of bounds
|
## is out of bounds
|
||||||
assert(not isNil(node))
|
assert(not isNil(node))
|
||||||
assert(node.kind == JArray)
|
assert(node.kind == JArray)
|
||||||
return node.elems[index]
|
return node.elems[index]
|
||||||
|
|
||||||
proc hasKey*(node: PJsonNode, key: string): bool =
|
proc hasKey*(node: JsonNode, key: string): bool =
|
||||||
## Checks if `key` exists in `node`.
|
## Checks if `key` exists in `node`.
|
||||||
assert(node.kind == JObject)
|
assert(node.kind == JObject)
|
||||||
for k, item in items(node.fields):
|
for k, item in items(node.fields):
|
||||||
if k == key: return true
|
if k == key: return true
|
||||||
|
|
||||||
proc existsKey*(node: PJsonNode, key: string): bool {.deprecated.} = node.hasKey(key)
|
proc existsKey*(node: JsonNode, key: string): bool {.deprecated.} = node.hasKey(key)
|
||||||
## Deprecated for `hasKey`
|
## Deprecated for `hasKey`
|
||||||
|
|
||||||
proc add*(father, child: PJsonNode) =
|
proc add*(father, child: JsonNode) =
|
||||||
## Adds `child` to a JArray node `father`.
|
## Adds `child` to a JArray node `father`.
|
||||||
assert father.kind == JArray
|
assert father.kind == JArray
|
||||||
father.elems.add(child)
|
father.elems.add(child)
|
||||||
|
|
||||||
proc add*(obj: PJsonNode, key: string, val: PJsonNode) =
|
proc add*(obj: JsonNode, key: string, val: JsonNode) =
|
||||||
## Adds ``(key, val)`` pair to the JObject node `obj`. For speed
|
## Adds ``(key, val)`` pair to the JObject node `obj`. For speed
|
||||||
## reasons no check for duplicate keys is performed!
|
## reasons no check for duplicate keys is performed!
|
||||||
## But ``[]=`` performs the check.
|
## But ``[]=`` performs the check.
|
||||||
assert obj.kind == JObject
|
assert obj.kind == JObject
|
||||||
obj.fields.add((key, val))
|
obj.fields.add((key, val))
|
||||||
|
|
||||||
proc `[]=`*(obj: PJsonNode, key: string, val: PJsonNode) =
|
proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) =
|
||||||
## Sets a field from a `JObject`. Performs a check for duplicate keys.
|
## Sets a field from a `JObject`. Performs a check for duplicate keys.
|
||||||
assert(obj.kind == JObject)
|
assert(obj.kind == JObject)
|
||||||
for i in 0..obj.fields.len-1:
|
for i in 0..obj.fields.len-1:
|
||||||
|
|
@ -723,14 +723,14 @@ proc `[]=`*(obj: PJsonNode, key: string, val: PJsonNode) =
|
||||||
return
|
return
|
||||||
obj.fields.add((key, val))
|
obj.fields.add((key, val))
|
||||||
|
|
||||||
proc `{}`*(node: PJsonNode, key: string): PJsonNode =
|
proc `{}`*(node: JsonNode, key: string): JsonNode =
|
||||||
## Transverses the node and gets the given value. If any of the
|
## Transverses the node and gets the given value. If any of the
|
||||||
## names does not exist, returns nil
|
## names does not exist, returns nil
|
||||||
result = node
|
result = node
|
||||||
if isNil(node): return nil
|
if isNil(node): return nil
|
||||||
result = result[key]
|
result = result[key]
|
||||||
|
|
||||||
proc `{}=`*(node: PJsonNode, names: varargs[string], value: PJsonNode) =
|
proc `{}=`*(node: JsonNode, names: varargs[string], value: JsonNode) =
|
||||||
## Transverses the node and tries to set the value at the given location
|
## Transverses the node and tries to set the value at the given location
|
||||||
## to `value` If any of the names are missing, they are added
|
## to `value` If any of the names are missing, they are added
|
||||||
var node = node
|
var node = node
|
||||||
|
|
@ -740,7 +740,7 @@ proc `{}=`*(node: PJsonNode, names: varargs[string], value: PJsonNode) =
|
||||||
node = node[names[i]]
|
node = node[names[i]]
|
||||||
node[names[names.len-1]] = value
|
node[names[names.len-1]] = value
|
||||||
|
|
||||||
proc delete*(obj: PJsonNode, key: string) =
|
proc delete*(obj: JsonNode, key: string) =
|
||||||
## Deletes ``obj[key]`` preserving the order of the other (key, value)-pairs.
|
## Deletes ``obj[key]`` preserving the order of the other (key, value)-pairs.
|
||||||
assert(obj.kind == JObject)
|
assert(obj.kind == JObject)
|
||||||
for i in 0..obj.fields.len-1:
|
for i in 0..obj.fields.len-1:
|
||||||
|
|
@ -749,7 +749,7 @@ proc delete*(obj: PJsonNode, key: string) =
|
||||||
return
|
return
|
||||||
raise newException(IndexError, "key not in object")
|
raise newException(IndexError, "key not in object")
|
||||||
|
|
||||||
proc copy*(p: PJsonNode): PJsonNode =
|
proc copy*(p: JsonNode): JsonNode =
|
||||||
## Performs a deep copy of `a`.
|
## Performs a deep copy of `a`.
|
||||||
case p.kind
|
case p.kind
|
||||||
of JString:
|
of JString:
|
||||||
|
|
@ -800,7 +800,7 @@ proc escapeJson*(s: string): string =
|
||||||
result.add(toHex(r, 4))
|
result.add(toHex(r, 4))
|
||||||
result.add("\"")
|
result.add("\"")
|
||||||
|
|
||||||
proc toPretty(result: var string, node: PJsonNode, indent = 2, ml = true,
|
proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
|
||||||
lstArr = false, currIndent = 0) =
|
lstArr = false, currIndent = 0) =
|
||||||
case node.kind
|
case node.kind
|
||||||
of JObject:
|
of JObject:
|
||||||
|
|
@ -855,34 +855,34 @@ proc toPretty(result: var string, node: PJsonNode, indent = 2, ml = true,
|
||||||
if lstArr: result.indent(currIndent)
|
if lstArr: result.indent(currIndent)
|
||||||
result.add("null")
|
result.add("null")
|
||||||
|
|
||||||
proc pretty*(node: PJsonNode, indent = 2): string =
|
proc pretty*(node: JsonNode, indent = 2): string =
|
||||||
## Converts `node` to its JSON Representation, with indentation and
|
## Converts `node` to its JSON Representation, with indentation and
|
||||||
## on multiple lines.
|
## on multiple lines.
|
||||||
result = ""
|
result = ""
|
||||||
toPretty(result, node, indent)
|
toPretty(result, node, indent)
|
||||||
|
|
||||||
proc `$`*(node: PJsonNode): string =
|
proc `$`*(node: JsonNode): string =
|
||||||
## Converts `node` to its JSON Representation on one line.
|
## Converts `node` to its JSON Representation on one line.
|
||||||
result = ""
|
result = ""
|
||||||
toPretty(result, node, 1, false)
|
toPretty(result, node, 1, false)
|
||||||
|
|
||||||
iterator items*(node: PJsonNode): PJsonNode =
|
iterator items*(node: JsonNode): JsonNode =
|
||||||
## Iterator for the items of `node`. `node` has to be a JArray.
|
## Iterator for the items of `node`. `node` has to be a JArray.
|
||||||
assert node.kind == JArray
|
assert node.kind == JArray
|
||||||
for i in items(node.elems):
|
for i in items(node.elems):
|
||||||
yield i
|
yield i
|
||||||
|
|
||||||
iterator pairs*(node: PJsonNode): tuple[key: string, val: PJsonNode] =
|
iterator pairs*(node: JsonNode): tuple[key: string, val: JsonNode] =
|
||||||
## Iterator for the child elements of `node`. `node` has to be a JObject.
|
## Iterator for the child elements of `node`. `node` has to be a JObject.
|
||||||
assert node.kind == JObject
|
assert node.kind == JObject
|
||||||
for key, val in items(node.fields):
|
for key, val in items(node.fields):
|
||||||
yield (key, val)
|
yield (key, val)
|
||||||
|
|
||||||
proc eat(p: var TJsonParser, tok: TTokKind) =
|
proc eat(p: var JsonParser, tok: TTokKind) =
|
||||||
if p.tok == tok: discard getTok(p)
|
if p.tok == tok: discard getTok(p)
|
||||||
else: raiseParseErr(p, tokToStr[tok])
|
else: raiseParseErr(p, tokToStr[tok])
|
||||||
|
|
||||||
proc parseJson(p: var TJsonParser): PJsonNode =
|
proc parseJson(p: var JsonParser): JsonNode =
|
||||||
## Parses JSON from a JSON Parser `p`.
|
## Parses JSON from a JSON Parser `p`.
|
||||||
case p.tok
|
case p.tok
|
||||||
of tkString:
|
of tkString:
|
||||||
|
|
@ -931,20 +931,20 @@ proc parseJson(p: var TJsonParser): PJsonNode =
|
||||||
raiseParseErr(p, "{")
|
raiseParseErr(p, "{")
|
||||||
|
|
||||||
when not defined(js):
|
when not defined(js):
|
||||||
proc parseJson*(s: PStream, filename: string): PJsonNode =
|
proc parseJson*(s: Stream, filename: string): JsonNode =
|
||||||
## Parses from a stream `s` into a `PJsonNode`. `filename` is only needed
|
## Parses from a stream `s` into a `PJsonNode`. `filename` is only needed
|
||||||
## for nice error messages.
|
## for nice error messages.
|
||||||
var p: TJsonParser
|
var p: JsonParser
|
||||||
p.open(s, filename)
|
p.open(s, filename)
|
||||||
discard getTok(p) # read first token
|
discard getTok(p) # read first token
|
||||||
result = p.parseJson()
|
result = p.parseJson()
|
||||||
p.close()
|
p.close()
|
||||||
|
|
||||||
proc parseJson*(buffer: string): PJsonNode =
|
proc parseJson*(buffer: string): JsonNode =
|
||||||
## Parses JSON from `buffer`.
|
## Parses JSON from `buffer`.
|
||||||
result = parseJson(newStringStream(buffer), "input")
|
result = parseJson(newStringStream(buffer), "input")
|
||||||
|
|
||||||
proc parseFile*(filename: string): PJsonNode =
|
proc parseFile*(filename: string): JsonNode =
|
||||||
## Parses `file` into a `PJsonNode`.
|
## Parses `file` into a `PJsonNode`.
|
||||||
var stream = newFileStream(filename, fmRead)
|
var stream = newFileStream(filename, fmRead)
|
||||||
if stream == nil:
|
if stream == nil:
|
||||||
|
|
@ -1062,8 +1062,8 @@ when isMainModule:
|
||||||
echo(pretty(parsed2))
|
echo(pretty(parsed2))
|
||||||
try:
|
try:
|
||||||
echo(parsed["key2"][12123])
|
echo(parsed["key2"][12123])
|
||||||
raise newException(EInvalidValue, "That line was expected to fail")
|
raise newException(ValueError, "That line was expected to fail")
|
||||||
except EInvalidIndex: echo()
|
except IndexError: echo()
|
||||||
|
|
||||||
let testJson = parseJson"""{ "a": [1, 2, 3, 4], "b": "asd" }"""
|
let testJson = parseJson"""{ "a": [1, 2, 3, 4], "b": "asd" }"""
|
||||||
# nil passthrough
|
# nil passthrough
|
||||||
|
|
@ -1075,12 +1075,12 @@ when isMainModule:
|
||||||
try:
|
try:
|
||||||
let a = testJson["a"][9]
|
let a = testJson["a"][9]
|
||||||
assert(false, "EInvalidIndex not thrown")
|
assert(false, "EInvalidIndex not thrown")
|
||||||
except EInvalidIndex:
|
except IndexError:
|
||||||
discard
|
discard
|
||||||
try:
|
try:
|
||||||
let a = testJson["a"][-1]
|
let a = testJson["a"][-1]
|
||||||
assert(false, "EInvalidIndex not thrown")
|
assert(false, "EInvalidIndex not thrown")
|
||||||
except EInvalidIndex:
|
except IndexError:
|
||||||
discard
|
discard
|
||||||
try:
|
try:
|
||||||
assert(testJson["a"][0].num == 1, "Index doesn't correspond to its value")
|
assert(testJson["a"][0].num == 1, "Index doesn't correspond to its value")
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@ when not defined(windows):
|
||||||
gFG = 0
|
gFG = 0
|
||||||
gBG = 0
|
gBG = 0
|
||||||
|
|
||||||
proc setStyle*(style: set[TStyle]) =
|
proc setStyle*(style: set[Style]) =
|
||||||
## sets the terminal style
|
## sets the terminal style
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
var a = 0'i16
|
var a = 0'i16
|
||||||
|
|
@ -229,7 +229,7 @@ proc setStyle*(style: set[TStyle]) =
|
||||||
for s in items(style):
|
for s in items(style):
|
||||||
stdout.write("\e[" & $ord(s) & 'm')
|
stdout.write("\e[" & $ord(s) & 'm')
|
||||||
|
|
||||||
proc writeStyled*(txt: string, style: set[TStyle] = {styleBright}) =
|
proc writeStyled*(txt: string, style: set[Style] = {styleBright}) =
|
||||||
## writes the text `txt` in a given `style`.
|
## writes the text `txt` in a given `style`.
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
var old = getAttributes()
|
var old = getAttributes()
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ template suite*(name: expr, body: stmt): stmt {.immediate, dirty.} =
|
||||||
|
|
||||||
proc testDone(name: string, s: TestStatus) =
|
proc testDone(name: string, s: TestStatus) =
|
||||||
if s == FAILED:
|
if s == FAILED:
|
||||||
program_result += 1
|
programResult += 1
|
||||||
|
|
||||||
if OutputLevel != PRINT_NONE and (OutputLevel == PRINT_ALL or s == FAILED):
|
if OutputLevel != PRINT_NONE and (OutputLevel == PRINT_ALL or s == FAILED):
|
||||||
template rawPrint() = echo("[", $s, "] ", name, "\n")
|
template rawPrint() = echo("[", $s, "] ", name, "\n")
|
||||||
|
|
@ -105,7 +105,7 @@ template fail* =
|
||||||
when declared(TestStatusIMPL):
|
when declared(TestStatusIMPL):
|
||||||
TestStatusIMPL = FAILED
|
TestStatusIMPL = FAILED
|
||||||
else:
|
else:
|
||||||
program_result += 1
|
programResult += 1
|
||||||
|
|
||||||
checkpoints = @[]
|
checkpoints = @[]
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue