Title here
Summary here
import json, streams
type
Response1 = object
page: int
fruits: seq[string]
Response2 = object
page {.jsonKey: "page".}: int
fruits {.jsonKey: "fruits".}: seq[string]
proc main() =
# First we'll look at encoding basic data types to
# JSON strings. Here are some examples for atomic
# values.
echo %* true
echo %* 1
echo %* 2.34
echo %* "gopher"
# And here are some for slices and maps, which encode
# to JSON arrays and objects as you'd expect.
let slcD = @["apple", "peach", "pear"]
echo %* slcD
let mapD = {"apple": 5, "lettuce": 7}.toTable
echo %* mapD
# The JSON module can automatically encode your
# custom data types. It will only include exported
# fields in the encoded output and will by default
# use those names as the JSON keys.
let res1D = Response1(page: 1, fruits: @["apple", "peach", "pear"])
echo %* res1D
# You can use pragma annotations on object field declarations
# to customize the encoded JSON key names. Check the
# definition of `Response2` above to see an example
# of such annotations.
let res2D = Response2(page: 1, fruits: @["apple", "peach", "pear"])
echo %* res2D
# Now let's look at decoding JSON data into Nim
# values. Here's an example for a generic data
# structure.
let byt = """{"num":6.13,"strs":["a","b"]}"""
# We need to provide a variable where the JSON
# module can put the decoded data. This
# `JsonNode` will hold a tree of JSON data.
let dat = parseJson(byt)
echo dat
# In order to use the values in the decoded JSON,
# we'll need to access them using the appropriate methods.
# For example here we get the value in `num` as a float.
let num = dat["num"].getFloat()
echo num
# Accessing nested data requires a series of
# method calls.
let str1 = dat["strs"][0].getStr()
echo str1
# We can also decode JSON into custom data types.
# This has the advantages of adding additional
# type-safety to our programs and eliminating the
# need for type assertions when accessing the decoded
# data.
let str = """{"page": 1, "fruits": ["apple", "peach"]}"""
var res = to(parseJson(str), Response2)
echo res
echo res.fruits[0]
# In the examples above we always used strings as
# intermediates between the data and JSON representation.
# We can also stream JSON encodings directly to streams
# like files or network connections.
let d = {"apple": 5, "lettuce": 7}.toTable
let stream = newFileStream(stdout)
stream.write($(%* d))
stream.close()
main()
This Nim code demonstrates JSON encoding and decoding, mirroring the functionality of the original Go example. Here’s a brief explanation of the key differences and Nim-specific features:
json
module for JSON operations.object
instead of struct
.{.jsonKey: "page".}
instead of struct tags.%*
for JSON encoding and parseJson
for decoding.JsonNode
is used as a generic JSON representation, similar to Go’s map[string]interface{}
.to
proc is used for decoding JSON into custom types.newFileStream
for creating a stream to stdout, similar to Go’s json.NewEncoder(os.Stdout)
.This code provides a comprehensive overview of JSON handling in Nim, covering encoding, decoding, and working with custom types, while maintaining the structure and explanations from the original Go example.