/ doc / api.txt
api.txt
  1  ============
  2  API Overview
  3  ============
  4  
  5  .. importdoc::
  6    api/yaml/loading.nim, api/yaml/dumping.nim, api/yaml/native.nim,
  7    api/yaml/annotations.nim, api/yaml/taglib.nim, api/yaml/style.nim,
  8    api/yaml/dom.nim, api/yaml/tojson.nim,
  9    api/yaml/parser.nim, api/yaml/presenter.nim, api/yaml/data.nim,
 10    api/yaml/stream.nim 
 11  
 12  Introduction
 13  ============
 14  
 15  NimYAML advocates parsing YAML input into native Nim types. Basic Nim library
 16  types like integers, floats and strings, as well as all tuples, enums and
 17  objects without private fields are supported out-of-the-box. Reference types are
 18  also supported, and NimYAML is able to detect if a reference occurs more than
 19  once and will serialize it accordingly. This means that NimYAML is able to dump
 20  and load potentially cyclic objects.
 21  
 22  While loading into and dumping from native Nim types is the preferred way to use
 23  NimYAML, it also gives you complete control over each processing step, so that
 24  you can for example only use the parser and process its event stream yourself.
 25  The following diagram gives an overview of NimYAML's features based on the YAML
 26  processing pipeline. The items and terminology YAML defines is shown in
 27  *italic*, NimYAML's implementation name is shown in **bold**.
 28  
 29  .. image:: processing.svg
 30  
 31  Intermediate Representation
 32  ===========================
 33  
 34  The base of all YAML processing with NimYAML is the `YamlStream`_. This is an
 35  iterator over `Event`_ objects. Every proc that represents a single stage of
 36  the loading or dumping process will either take a ``YamlStream`` as input or
 37  return a ``YamlStream``. Procs that implement the whole process in one step
 38  hide the ``YamlStream`` from the caller. Every proc that returns a
 39  ``YamlStream`` guarantees that this stream is well-formed according to the
 40  YAML specification.
 41  
 42  This stream-oriented API can efficiently be used to parse large amounts of data.
 43  The drawback is that errors in the input are only discovered while processing
 44  the ``YamlStream``. If the ``YamlStream`` encounters an exception while
 45  producing the next event, it will throw a `YamlStreamError`_ which contains the
 46  original exception as ``parent``. The caller should know which exceptions are
 47  possible as parents of ``YamlStream`` because they know the source of the
 48  ``YamlStream`` they provided.
 49  
 50  Loading YAML
 51  ============
 52  
 53  If you want to load YAML character data directly into a native Nim variable,
 54  you can use `load`_. This is the easiest and recommended way to load YAML
 55  data. This section gives an overview about how ``load`` is implemented. It is
 56  absolutely possible to reimplement the loading step using the low-level API.
 57  
 58  For parsing, a `YamlParser`_ object is needed. This object stores some state
 59  while parsing that may be useful for error reporting to the user. The `parse`_
 60  proc implements the YAML processing step of the same name. All syntax errors in
 61  the input character stream are processed by ``parse``, which will raise a
 62  `YamlParserError`_ if it encounters a syntax error.
 63  
 64  Transforming a ``YamlStream`` to a native YAML object is done via
 65  `construct`_. It skips the **compose** step for efficiency reasons. As Nim is
 66  statically typed, you have to know the target type when you write your loading
 67  code. This is different from YAML APIs of dynamically typed languages. If you
 68  cannot know the type of your YAML input at compile time, you have to manually
 69  process the ``YamlStream`` to serve your needs.
 70  
 71  Dumping YAML
 72  ============
 73  
 74  Dumping is preferably done with `dump`_, which serializes a native Nim value
 75  to a character stream. As with ``load``, this section describes how
 76  ``dump`` is implemented using the low-level API.
 77  
 78  A Nim value is transformed into a ``YamlStream`` with `represent`_.
 79  Depending on the `AnchorStyle`_ you specify in the `SerializationOptions`_ of
 80  your `Dumper`_, this will transform ``ref`` variables with multiple instances
 81  into anchored elements and aliases (for ``asTidy`` and ``asAlways``) or write
 82  the same element into all places it occurs (for ``asNone``). Be aware that if
 83  you use ``asNone``, the value you serialize might not round-trip.
 84  
 85  Transforming a ``YamlStream`` into YAML character data is done with
 86  `present`_ which is customized by your Dumper's `PresentationOptions`_. The
 87  Dumper provides multiple presets, for example the `jsonDumper`_ dumps your
 88  value in JSON style (which is also valid YAML since YAML is a superset of
 89  JSON).
 90  
 91  The Document Object Model
 92  =========================
 93  
 94  Unlike XML, YAML does not define an official *document object model*. However,
 95  if you cannot or do not want to load a YAML input stream to native Nim types,
 96  you can load it into the predefined type `YamlNode`_. You can also use this
 97  type inside your native types to deserialize parts of the YAML input into it.
 98  Likewise, you can serialize a ``YamlNode`` into YAML. You can use this to
 99  preserve parts of YAML data you do not wish to or cannot fully deserialize.
100  
101  A ``YamlNode`` preserves its given tag and the tags of any child nodes, and
102  also its style (which means, unless you override style with Dumper options,
103  the node will be serialized with the same style it had originally).
104  However, anchors will be resolved during loading and re-added during
105  serialization. It is possible for a ``YamlNode`` to occur multiple times within
106  source/target root object, in which case it will be serialized once and
107  referred to afterwards via aliases.
108  
109  ``YamlNode`` is allocated on the heap and using it will be slower and consume
110  more memory than deserializing into native types.