/ yaml / loading.nim
loading.nim
 1  #            NimYAML - YAML implementation in Nim
 2  #        (c) Copyright 2015-2023 Felix Krause
 3  #
 4  #    See the file "copying.txt", included in this
 5  #    distribution, for details about the copyright.
 6  
 7  ## ===================
 8  ## Module yaml/loading
 9  ## ===================
10  ##
11  ## The loading API enables you to load a YAML character stream
12  ## into native Nim value. Along with the dumping API, this
13  ## forms the highest-level API of NimYAML.
14  
15  import std / [ streams ]
16  import native, parser, private/internal
17  export native, YamlConstructionError, YamlParserError
18  
19  proc load*[K](input: Stream | string, target: var K)
20      {.raises: [YamlConstructionError, IOError, OSError, YamlParserError].} =
21    ## Loads a Nim value from a YAML character stream.
22    try:
23      var
24        parser = initYamlParser()
25        events = parser.parse(input)
26        e = events.next()
27      yAssert(e.kind == yamlStartStream)
28      if events.peek().kind != yamlStartDoc:
29        raise constructionError(events, e.startPos, "stream contains no documents")
30      construct(events, target)
31      e = events.next()
32      if e.kind != yamlEndStream:
33        var ex = (ref YamlConstructionError)(
34          mark: e.startPos, msg: "stream contains multiple documents")
35        discard events.getLastTokenContext(ex.lineContent)
36        raise ex
37    except YamlStreamError as e:
38      if e.parent of IOError: raise (ref IOError)(e.parent)
39      if e.parent of OSError: raise (ref OSError)(e.parent)
40      elif e.parent of YamlParserError: raise (ref YamlParserError)(e.parent)
41      elif e.parent of YamlConstructionError: raise (ref YamlConstructionError)(e.parent)
42      else: internalError("Unexpected exception: " & $e.parent.name)
43  
44  proc loadAs*[K](input: Stream | string): K {.raises:
45      [YamlConstructionError, IOError, OSError, YamlParserError].} =
46    ## Loads the given YAML input to a value of the type K and returns it
47    load(input, result)
48  
49  proc loadMultiDoc*[K](input: Stream | string, target: var seq[K]) =
50    var
51      parser = initYamlParser()
52      events = parser.parse(input)
53      e = events.next()
54    yAssert(e.kind == yamlStartStream)
55    try:
56      while events.peek().kind == yamlStartDoc:
57        var item: K
58        construct(events, item)
59        target.add(item)
60      e = events.next()
61      yAssert(e.kind == yamlEndStream)
62    except YamlConstructionError as e:
63      discard events.getLastTokenContext(e.lineContent)
64      raise e
65    except YamlStreamError as e:
66      if e.parent of IOError: raise (ref IOError)(e.parent)
67      elif e.parent of OSError: raise (ref OSError)(e.parent)
68      elif e.parent of YamlParserError: raise (ref YamlParserError)(e.parent)
69      else: internalError("Unexpected exception: " & $e.parent.name)