Json in Nim

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:

  1. Nim uses the json module for JSON operations.
  2. Custom types are defined using object instead of struct.
  3. JSON key customization is done using pragmas like {.jsonKey: "page".} instead of struct tags.
  4. Nim uses %* for JSON encoding and parseJson for decoding.
  5. Nim’s JsonNode is used as a generic JSON representation, similar to Go’s map[string]interface{}.
  6. Nim’s to proc is used for decoding JSON into custom types.
  7. Nim uses 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.

查看推荐产品

Comments powered by Disqus