mirror of https://github.com/status-im/NimYAML.git
138 lines
31 KiB
HTML
138 lines
31 KiB
HTML
<!DOCTYPE html>
|
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<title>NimYAML - Serialization Overview</title>
|
|
|
|
<link href="docutils.css" rel="stylesheet" type="text/css"/>
|
|
<link href="style.css" rel="stylesheet" type="text/css"/>
|
|
|
|
<link href='http://fonts.googleapis.com/css?family=Raleway:400,600,900' rel='stylesheet' type='text/css'/>
|
|
<link href='http://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
|
|
</head>
|
|
<body>
|
|
<a href="https://github.com/flyx/NimYAML"><img style="position: fixed; top: 0; right: 0; border: 0; z-index: 10;" src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png"></a>
|
|
<header>
|
|
<a class="pagetitle" href="index.html">NimYAML</a>
|
|
<a href="index.html">Home</a>
|
|
<a href="testing.html">Testing Ground</a>
|
|
<span>Docs:</span>
|
|
<a href="api.html">Overview</a>
|
|
<a href="serialization.html">Serialization</a>
|
|
<a href="yaml.html">Module yaml</a>
|
|
</header>
|
|
<article id="documentId">
|
|
<div class="container">
|
|
<h1 class="title">Serialization Overview</h1>
|
|
|
|
<h1 id="introduction">Introduction</h1><p>NimYAML tries hard to make transforming YAML characters streams to native Nim types and vice versa as easy as possible. In simple scenarios, you might not need anything else than the two procs <a class="reference external" href="yaml.html#dump,K,Stream,PresentationStyle,TagStyle,AnchorStyle,int">dump</a> and <a class="reference external" href="yaml.html#load,Stream,K">load</a>. On the other side, the process should be as customizable as possible to allow the user to tightly control how the generated YAML character stream will look and how a YAML character stream is interpreted.</p>
|
|
<p>An important thing to remember in NimYAML is that unlike in interpreted languages like Ruby, Nim cannot load a YAML character stream without knowing the resulting type beforehand. For example, if you want to load this piece of YAML:</p>
|
|
<pre class = "listing"><span class="Directive">%YAML 1.2</span>
|
|
<span class="Keyword">---</span> <span class="TagStart">!nim:system:seq(nim:system:int8)</span>
|
|
<span class="Punctuation">-</span> <span class="DecNumber">1</span>
|
|
<span class="Punctuation">-</span> <span class="DecNumber">2</span>
|
|
<span class="Punctuation">-</span> <span class="DecNumber">3</span></pre><p>You would need to know that it will load a <tt class="docutils literal"><span class="pre">seq[int8]</span></tt> <em>at compile time</em>. This is not really a problem because without knowing which type you will load, you cannot do anything useful with the result afterwards in the code. But it may be unfamiliar for programmers who are used to the YAML libraries of Python or Ruby.</p>
|
|
|
|
<h1 id="supported-types">Supported Types</h1><p>NimYAML supports a growing number of types of Nim's <tt class="docutils literal"><span class="pre">system</span></tt> module and standard library, and it also supports user-defined object, tuple and enum types out of the box.</p>
|
|
<p><strong>Important</strong>: NimYAML currently does not support polymorphism or variant object types. This may be added in the future.</p>
|
|
<p>This also means that NimYAML is generally able to work with object, tuple and enum types defined in the standard library or a third-party library without further configuration.</p>
|
|
|
|
<h2 id="scalar-types">Scalar Types</h2><p>The following integer types are supported by NimYAML: <tt class="docutils literal"><span class="pre">int</span></tt>, <tt class="docutils literal"><span class="pre">int8</span></tt>, <tt class="docutils literal"><span class="pre">int16</span></tt>, <tt class="docutils literal"><span class="pre">int32</span></tt>, <tt class="docutils literal"><span class="pre">int64</span></tt>, <tt class="docutils literal"><span class="pre">uint8</span></tt>, <tt class="docutils literal"><span class="pre">uint16</span></tt>, <tt class="docutils literal"><span class="pre">uint32</span></tt>, <tt class="docutils literal"><span class="pre">uint64</span></tt>. Note that the <tt class="docutils literal"><span class="pre">int</span></tt> type has a variable size dependent on the target operation system. To make sure that it round-trips properly between 32-bit and 64-bit operating systems, it will be converted to an <tt class="docutils literal"><span class="pre">int32</span></tt> during loading and dumping. This will raise an exception for values outside of the range <tt class="docutils literal"><span class="pre">int32.low .. int32.high</span></tt>! If you define the types you serialize yourself, always consider using an integer type with explicit length. The same goes for <tt class="docutils literal"><span class="pre">uint</span></tt>.</p>
|
|
<p>The floating point types <tt class="docutils literal"><span class="pre">float</span></tt>, <tt class="docutils literal"><span class="pre">float32</span></tt> and <tt class="docutils literal"><span class="pre">float64</span></tt> are also supported. There is currently no problem with <tt class="docutils literal"><span class="pre">float</span></tt>, because it is always a <tt class="docutils literal"><span class="pre">float64</span></tt>.</p>
|
|
<p><tt class="docutils literal"><span class="pre">string</span></tt> is supported and one of the few Nim types which directly map to a standard YAML type. NimYAML is able to handle strings that are <tt class="docutils literal"><span class="pre">nil</span></tt>, they will be serialized with the special tag <tt class="docutils literal"><span class="pre">!nim:nil:string</span></tt>. <tt class="docutils literal"><span class="pre">char</span></tt> is also supported.</p>
|
|
<p>To support new scalar types, you must implement the <tt class="docutils literal"><span class="pre">constructObject()</span></tt> and <tt class="docutils literal"><span class="pre">representObject()</span></tt> procs on that type (see below).</p>
|
|
|
|
<h2 id="collection-types">Collection Types</h2><p>NimYAML supports Nim's <tt class="docutils literal"><span class="pre">array</span></tt>, <tt class="docutils literal"><span class="pre">set</span></tt>, <tt class="docutils literal"><span class="pre">seq</span></tt>, <tt class="docutils literal"><span class="pre">Table</span></tt> and <tt class="docutils literal"><span class="pre">OrderedTable</span></tt> types out of the box. Unlike the native YAML types <tt class="docutils literal"><span class="pre">!!seq</span></tt> and <tt class="docutils literal"><span class="pre">!!map</span></tt>, Nim's collection types define the type of all their contained items (or keys and values). So YAML objects with heterogeneous types in them cannot be loaded to Nim collection types. For example, this sequence:</p>
|
|
<pre class = "listing"><span class="Directive">%YAML 1.2</span>
|
|
<span class="Keyword">---</span> <span class="TagStart">!!seq</span>
|
|
<span class="Punctuation">-</span> <span class="TagStart">!!int</span> <span class="DecNumber">1</span>
|
|
<span class="Punctuation">-</span> <span class="TagStart">!!string</span> <span class="StringLit">foo</span></pre><p>Cannot be loaded to a Nim <tt class="docutils literal"><span class="pre">seq</span></tt>. For this reason, you cannot load YAML's native <tt class="docutils literal"><span class="pre">!!map</span></tt> and <tt class="docutils literal"><span class="pre">!!seq</span></tt> types directly into Nim types.</p>
|
|
<p>Nim <tt class="docutils literal"><span class="pre">seq</span></tt> types may be <tt class="docutils literal"><span class="pre">nil</span></tt>. This is handled by serializing them to an empty scalar with the tag <tt class="docutils literal"><span class="pre">!nim:nil:seq</span></tt>.</p>
|
|
|
|
<h2 id="reference-types">Reference Types</h2><p>A reference to any supported non-reference type (including user defined types, see below) is supported by NimYAML. A reference type will be treated like its base type, but NimYAML is able to detect multiple references to the same object and dump the structure properly with anchors and aliases in place. It is possible to dump and load cyclic data structures without further configuration. It is possible for reference types to hold a <tt class="docutils literal"><span class="pre">nil</span></tt> value, which will be mapped to the <tt class="docutils literal"><span class="pre">!!null</span></tt> YAML scalar type.</p>
|
|
<p>Pointer types are not supported because it seems dangerous to automatically allocate memory which the user must then manually deallocate.</p>
|
|
|
|
<h2 id="user-defined-types">User Defined Types</h2><p>For an object or tuple type to be directly usable with NimYAML, the following conditions must be met:</p>
|
|
<ul class="simple"><li>Every type contained in the object/tuple must be supported</li>
|
|
<li>All fields of an object type must be accessible from the code position where you call NimYAML. If an object has non-public member fields, it can only be processed in the module where it is defined.</li>
|
|
<li>The object may not contain a <tt class="docutils literal"><span class="pre">case</span></tt> clause.</li>
|
|
<li>The object may not have a generic parameter</li>
|
|
</ul>
|
|
<p>NimYAML will present enum types as YAML scalars, and tuple and object types as YAML maps. Some of the conditions above may be loosened in future releases.</p>
|
|
|
|
<h1 id="tags">Tags</h1><p>NimYAML uses local tags to represent Nim types that do not map directly to a YAML type. For example, <tt class="docutils literal"><span class="pre">int8</span></tt> is presented with the tag <tt class="docutils literal"><span class="pre">!nim:system:int8</span></tt>. Tags are mostly unnecessary when loading YAML data because the user already defines the target Nim type which usually defines all types of the structure. However, there is one case where a tag is necessary: A reference type with the value <tt class="docutils literal"><span class="pre">nil</span></tt> is represented in YAML as a <tt class="docutils literal"><span class="pre">!!null</span></tt> scalar. This will be automatically detected by type guessing, but if it is for example a reference to a string with the value <tt class="docutils literal"><span class="pre">"~"</span></tt>, it must be tagged with <tt class="docutils literal"><span class="pre">!!string</span></tt>, because otherwise, it would be loaded as <tt class="docutils literal"><span class="pre">nil</span></tt>.</p>
|
|
<p>As you might have noticed in the example above, the YAML tag of a <tt class="docutils literal"><span class="pre">seq</span></tt> depends on its generic type parameter. The same applies to <tt class="docutils literal"><span class="pre">Table</span></tt>. So, a table that maps <tt class="docutils literal"><span class="pre">int8</span></tt> to string sequences would be presented with the tag <tt class="docutils literal"><span class="pre">!nim:tables:Table(nim:system:int8,nim:system:seq(tag:yaml.org,2002:string))</span></tt>. These tags are generated on the fly based on the types you instantiate <tt class="docutils literal"><span class="pre">Table</span></tt> or <tt class="docutils literal"><span class="pre">seq</span></tt> with.</p>
|
|
<p>You may customize the tags used for your types by using the template <a class="reference external" href="yaml.html#setTagUri.t,typedesc,string">setTagUri</a>. It may not be applied to scalar and collection types implemented by NimYAML, but you can for example use it on a certain <tt class="docutils literal"><span class="pre">seq</span></tt> type:</p>
|
|
<pre class = "listing"><span class="Identifier">setTagUri</span><span class="Punctuation">(</span><span class="Identifier">seq</span><span class="Punctuation">[</span><span class="Identifier">string</span><span class="Punctuation">]</span><span class="Punctuation">,</span> <span class="StringLit">"!nim:my:seq"</span><span class="Punctuation">)</span></pre>
|
|
<h1 id="customize-serialization">Customize Serialization</h1><p>It is possible to customize the serialization of a type. For this, you need to implement two procs, <tt class="docutils literal"><span class="pre">constructObject̀</span></tt> and <tt class="docutils literal"><span class="pre">representObject</span></tt>. If you only need to process the type in one direction (loading or dumping), you can omit the other proc.</p>
|
|
|
|
<h2 id="constructobject">constructObject</h2><pre class = "listing"><span class="Keyword">proc</span> <span class="Identifier">constructObject</span><span class="Operator">*</span><span class="Punctuation">(</span><span class="Identifier">s</span><span class="Punctuation">:</span> <span class="Keyword">var</span> <span class="Identifier">YamlStream</span><span class="Punctuation">,</span> <span class="Identifier">c</span><span class="Punctuation">:</span> <span class="Identifier">ConstructionContext</span><span class="Punctuation">,</span>
|
|
<span class="Identifier">result</span><span class="Punctuation">:</span> <span class="Keyword">var</span> <span class="Identifier">MyObject</span><span class="Punctuation">)</span>
|
|
<span class="Punctuation">{</span><span class="Operator">.</span><span class="Identifier">raises</span><span class="Punctuation">:</span> <span class="Punctuation">[</span><span class="Identifier">YamlConstructionError</span><span class="Punctuation">,</span> <span class="Identifier">YamlStreamError</span><span class="Operator">.</span><span class="Punctuation">}</span></pre><p>This proc should construct the type from a <tt class="docutils literal"><span class="pre">YamlStream</span></tt>. Follow the following guidelines when implementing a custom <tt class="docutils literal"><span class="pre">constructObject</span></tt> proc:</p>
|
|
<ul class="simple"><li>For constructing a value from a YAML scalar, consider using the <tt class="docutils literal"><span class="pre">constructScalarItem</span></tt> template, which will automatically catch exceptions and wrap them with a <tt class="docutils literal"><span class="pre">YamlConstructionError</span></tt>, and also will assure that the item you use for construction is a <tt class="docutils literal"><span class="pre">yamlScalar</span></tt>. See below for an example.</li>
|
|
<li>For constructing a value from a YAML sequence or map, you <strong>must</strong> use the <tt class="docutils literal"><span class="pre">constructChild</span></tt> proc for child values if you want to use their <tt class="docutils literal"><span class="pre">constructObject</span></tt> implementation. This will check their tag and anchor. Always try to construct child values that way.</li>
|
|
<li>For non-scalars, make sure that the last value you remove from the stream is the object's ending event (<tt class="docutils literal"><span class="pre">yamlEndMap</span></tt> or <tt class="docutils literal"><span class="pre">yamlEndSequence</span></tt>)</li>
|
|
<li>Use <a class="reference external" href="yaml.html#peek,YamlStream">peek</a> for inspecting the next event in the <tt class="docutils literal"><span class="pre">YamlStream</span></tt> without removing it.</li>
|
|
<li>Never write a <tt class="docutils literal"><span class="pre">constructObject</span></tt> proc for a <tt class="docutils literal"><span class="pre">ref</span></tt> type. <tt class="docutils literal"><span class="pre">ref</span></tt> types are always handled by NimYAML itself. You can only customize the construction of the underlying object.</li>
|
|
</ul>
|
|
<p>The following example for constructing from a YAML scalar value is the actual implementation of constructing <tt class="docutils literal"><span class="pre">int</span></tt> types:</p>
|
|
<pre class = "listing"><span class="Keyword">proc</span> <span class="Identifier">constructObject</span><span class="Operator">*</span><span class="Punctuation">[</span><span class="Identifier">T</span><span class="Punctuation">:</span> <span class="Identifier">int8</span><span class="Operator">|</span><span class="Identifier">int16</span><span class="Operator">|</span><span class="Identifier">int32</span><span class="Operator">|</span><span class="Identifier">int64</span><span class="Punctuation">]</span><span class="Punctuation">(</span>
|
|
<span class="Identifier">s</span><span class="Punctuation">:</span> <span class="Keyword">var</span> <span class="Identifier">YamlStream</span><span class="Punctuation">,</span> <span class="Identifier">c</span><span class="Punctuation">:</span> <span class="Identifier">ConstructionContext</span><span class="Punctuation">,</span> <span class="Identifier">result</span><span class="Punctuation">:</span> <span class="Keyword">var</span> <span class="Identifier">T</span><span class="Punctuation">)</span>
|
|
<span class="Punctuation">{</span><span class="Operator">.</span><span class="Identifier">raises</span><span class="Punctuation">:</span> <span class="Punctuation">[</span><span class="Identifier">YamlConstructionError</span><span class="Punctuation">,</span> <span class="Identifier">YamlStreamError</span><span class="Punctuation">]</span><span class="Operator">.</span><span class="Punctuation">}</span> <span class="Operator">=</span>
|
|
<span class="Keyword">var</span> <span class="Identifier">item</span><span class="Punctuation">:</span> <span class="Identifier">YamlStreamEvent</span>
|
|
<span class="Identifier">constructScalarItem</span><span class="Punctuation">(</span><span class="Identifier">s</span><span class="Punctuation">,</span> <span class="Identifier">item</span><span class="Punctuation">,</span> <span class="Identifier">name</span><span class="Punctuation">(</span><span class="Identifier">T</span><span class="Punctuation">)</span><span class="Punctuation">)</span><span class="Punctuation">:</span>
|
|
<span class="Identifier">result</span> <span class="Operator">=</span> <span class="Identifier">T</span><span class="Punctuation">(</span><span class="Identifier">parseBiggestInt</span><span class="Punctuation">(</span><span class="Identifier">item</span><span class="Operator">.</span><span class="Identifier">scalarContent</span><span class="Punctuation">)</span><span class="Punctuation">)</span></pre><p>The following example for constructiong from a YAML non-scalar is the actual implementation of constructing <tt class="docutils literal"><span class="pre">seq</span></tt> types:</p>
|
|
<pre class = "listing"><span class="Keyword">proc</span> <span class="Identifier">constructObject</span><span class="Operator">*</span><span class="Punctuation">[</span><span class="Identifier">T</span><span class="Punctuation">]</span><span class="Punctuation">(</span><span class="Identifier">s</span><span class="Punctuation">:</span> <span class="Keyword">var</span> <span class="Identifier">YamlStream</span><span class="Punctuation">,</span> <span class="Identifier">c</span><span class="Punctuation">:</span> <span class="Identifier">ConstructionContext</span><span class="Punctuation">,</span>
|
|
<span class="Identifier">result</span><span class="Punctuation">:</span> <span class="Keyword">var</span> <span class="Identifier">seq</span><span class="Punctuation">[</span><span class="Identifier">T</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
|
|
<span class="Punctuation">{</span><span class="Operator">.</span><span class="Identifier">raises</span><span class="Punctuation">:</span> <span class="Punctuation">[</span><span class="Identifier">YamlConstructionError</span><span class="Punctuation">,</span> <span class="Identifier">YamlStreamError</span><span class="Punctuation">]</span><span class="Operator">.</span><span class="Punctuation">}</span> <span class="Operator">=</span>
|
|
<span class="Keyword">let</span> <span class="Identifier">event</span> <span class="Operator">=</span> <span class="Identifier">s</span><span class="Operator">.</span><span class="Identifier">next</span><span class="Punctuation">(</span><span class="Punctuation">)</span>
|
|
<span class="Keyword">if</span> <span class="Identifier">event</span><span class="Operator">.</span><span class="Identifier">kind</span> <span class="Operator">!=</span> <span class="Identifier">yamlStartSequence</span><span class="Punctuation">:</span>
|
|
<span class="Keyword">raise</span> <span class="Identifier">newException</span><span class="Punctuation">(</span><span class="Identifier">YamlConstructionError</span><span class="Punctuation">,</span> <span class="StringLit">"Expected sequence start"</span><span class="Punctuation">)</span>
|
|
<span class="Identifier">result</span> <span class="Operator">=</span> <span class="Identifier">newSeq</span><span class="Punctuation">[</span><span class="Identifier">T</span><span class="Punctuation">]</span><span class="Punctuation">(</span><span class="Punctuation">)</span>
|
|
<span class="Keyword">while</span> <span class="Identifier">s</span><span class="Operator">.</span><span class="Identifier">peek</span><span class="Punctuation">(</span><span class="Punctuation">)</span><span class="Operator">.</span><span class="Identifier">kind</span> <span class="Operator">!=</span> <span class="Identifier">yamlEndSequence</span><span class="Punctuation">:</span>
|
|
<span class="Keyword">var</span> <span class="Identifier">item</span><span class="Punctuation">:</span> <span class="Identifier">T</span>
|
|
<span class="Identifier">constructChild</span><span class="Punctuation">(</span><span class="Identifier">s</span><span class="Punctuation">,</span> <span class="Identifier">c</span><span class="Punctuation">,</span> <span class="Identifier">item</span><span class="Punctuation">)</span>
|
|
<span class="Identifier">result</span><span class="Operator">.</span><span class="Identifier">add</span><span class="Punctuation">(</span><span class="Identifier">item</span><span class="Punctuation">)</span>
|
|
<span class="Keyword">discard</span> <span class="Identifier">s</span><span class="Operator">.</span><span class="Identifier">next</span><span class="Punctuation">(</span><span class="Punctuation">)</span></pre>
|
|
<h2 id="representobject">representObject</h2><pre class = "listing"><span class="Keyword">proc</span> <span class="Identifier">representObject</span><span class="Operator">*</span><span class="Punctuation">(</span><span class="Identifier">value</span><span class="Punctuation">:</span> <span class="Identifier">MyObject</span><span class="Punctuation">,</span> <span class="Identifier">ts</span><span class="Punctuation">:</span> <span class="Identifier">TagStyle</span> <span class="Operator">=</span> <span class="Identifier">tsNone</span><span class="Punctuation">,</span>
|
|
<span class="Identifier">c</span><span class="Punctuation">:</span> <span class="Identifier">SerializationContext</span><span class="Punctuation">)</span><span class="Punctuation">:</span> <span class="Identifier">RawYamlStream</span> <span class="Punctuation">{</span><span class="Operator">.</span><span class="Identifier">raises</span><span class="Punctuation">:</span> <span class="Punctuation">[</span><span class="Punctuation">]</span><span class="Operator">.</span><span class="Punctuation">}</span></pre><p>This proc should return an iterator over <tt class="docutils literal"><span class="pre">YamlStreamEvent</span></tt> which represents the type. Follow the following guidelines when implementing a custom <tt class="docutils literal"><span class="pre">representObject</span></tt> proc:</p>
|
|
<ul class="simple"><li>You can use the helper template <a class="reference external" href="yaml.html#presentTag,typedesc,TagStyle">presentTag</a> for outputting the tag.</li>
|
|
<li>Always output the first tag with a <tt class="docutils literal"><span class="pre">yAnchorNone</span></tt>. Anchors will be set automatically by <tt class="docutils literal"><span class="pre">ref</span></tt> type handling.</li>
|
|
<li>When outputting non-scalar types, you should use the <tt class="docutils literal"><span class="pre">representObject</span></tt> implementation of the child types, if possible.</li>
|
|
<li>Check if the given <tt class="docutils literal"><span class="pre">TagStyle</span></tt> equals <tt class="docutils literal"><span class="pre">tsRootOnly</span></tt> and if yes, change it to <tt class="docutils literal"><span class="pre">tsNone</span></tt> for the child values.</li>
|
|
<li>Never write a <tt class="docutils literal"><span class="pre">representObject</span></tt> proc for <tt class="docutils literal"><span class="pre">ref</span></tt> types.</li>
|
|
</ul>
|
|
<p>The following example for representing to a YAML scalar is the actual implementation of representing <tt class="docutils literal"><span class="pre">int</span></tt> types:</p>
|
|
<pre class = "listing"><span class="Keyword">proc</span> <span class="Identifier">representObject</span><span class="Operator">*</span><span class="Punctuation">[</span><span class="Identifier">T</span><span class="Punctuation">:</span> <span class="Identifier">uint8</span><span class="Operator">|</span><span class="Identifier">uint16</span><span class="Operator">|</span><span class="Identifier">uint32</span><span class="Operator">|</span><span class="Identifier">uint64</span><span class="Punctuation">]</span><span class="Punctuation">(</span>
|
|
<span class="Identifier">value</span><span class="Punctuation">:</span> <span class="Identifier">T</span><span class="Punctuation">,</span> <span class="Identifier">ts</span><span class="Punctuation">:</span> <span class="Identifier">TagStyle</span><span class="Punctuation">,</span> <span class="Identifier">c</span><span class="Punctuation">:</span> <span class="Identifier">SerializationContext</span><span class="Punctuation">)</span><span class="Punctuation">:</span>
|
|
<span class="Identifier">RawYamlStream</span> <span class="Punctuation">{</span><span class="Operator">.</span><span class="Identifier">raises</span><span class="Punctuation">:</span> <span class="Punctuation">[</span><span class="Punctuation">]</span><span class="Operator">.</span><span class="Punctuation">}</span> <span class="Operator">=</span>
|
|
<span class="Identifier">result</span> <span class="Operator">=</span> <span class="Keyword">iterator</span><span class="Punctuation">(</span><span class="Punctuation">)</span><span class="Punctuation">:</span> <span class="Identifier">YamlStreamEvent</span> <span class="Operator">=</span>
|
|
<span class="Keyword">yield</span> <span class="Identifier">scalarEvent</span><span class="Punctuation">(</span><span class="Operator">$</span><span class="Identifier">value</span><span class="Punctuation">,</span> <span class="Identifier">presentTag</span><span class="Punctuation">(</span><span class="Identifier">T</span><span class="Punctuation">,</span> <span class="Identifier">ts</span><span class="Punctuation">)</span><span class="Punctuation">,</span> <span class="Identifier">yAnchorNone</span><span class="Punctuation">)</span></pre><p>The following example for representing to a YAML non-scalar is the actual implementation of representing <tt class="docutils literal"><span class="pre">seq</span></tt> types:</p>
|
|
<pre class = "listing"><span class="Keyword">proc</span> <span class="Identifier">representObject</span><span class="Operator">*</span><span class="Punctuation">[</span><span class="Identifier">T</span><span class="Punctuation">]</span><span class="Punctuation">(</span><span class="Identifier">value</span><span class="Punctuation">:</span> <span class="Identifier">seq</span><span class="Punctuation">[</span><span class="Identifier">T</span><span class="Punctuation">]</span><span class="Punctuation">,</span> <span class="Identifier">ts</span><span class="Punctuation">:</span> <span class="Identifier">TagStyle</span><span class="Punctuation">,</span>
|
|
<span class="Identifier">c</span><span class="Punctuation">:</span> <span class="Identifier">SerializationContext</span><span class="Punctuation">)</span><span class="Punctuation">:</span> <span class="Identifier">RawYamlStream</span> <span class="Punctuation">{</span><span class="Operator">.</span><span class="Identifier">raises</span><span class="Punctuation">:</span> <span class="Punctuation">[</span><span class="Punctuation">]</span><span class="Operator">.</span><span class="Punctuation">}</span> <span class="Operator">=</span>
|
|
<span class="Identifier">result</span> <span class="Operator">=</span> <span class="Keyword">iterator</span><span class="Punctuation">(</span><span class="Punctuation">)</span><span class="Punctuation">:</span> <span class="Identifier">YamlStreamEvent</span> <span class="Operator">=</span>
|
|
<span class="Keyword">let</span> <span class="Identifier">childTagStyle</span> <span class="Operator">=</span> <span class="Keyword">if</span> <span class="Identifier">ts</span> <span class="Operator">==</span> <span class="Identifier">tsRootOnly</span><span class="Punctuation">:</span> <span class="Identifier">tsNone</span> <span class="Keyword">else</span><span class="Punctuation">:</span> <span class="Identifier">ts</span>
|
|
<span class="Keyword">yield</span> <span class="Identifier">YamlStreamEvent</span><span class="Punctuation">(</span><span class="Identifier">kind</span><span class="Punctuation">:</span> <span class="Identifier">yamlStartSequence</span><span class="Punctuation">,</span>
|
|
<span class="Identifier">seqTag</span><span class="Punctuation">:</span> <span class="Identifier">presentTag</span><span class="Punctuation">(</span><span class="Identifier">seq</span><span class="Punctuation">[</span><span class="Identifier">T</span><span class="Punctuation">]</span><span class="Punctuation">,</span> <span class="Identifier">ts</span><span class="Punctuation">)</span><span class="Punctuation">,</span>
|
|
<span class="Identifier">seqAnchor</span><span class="Punctuation">:</span> <span class="Identifier">yAnchorNone</span><span class="Punctuation">)</span>
|
|
<span class="Keyword">for</span> <span class="Identifier">item</span> <span class="Keyword">in</span> <span class="Identifier">value</span><span class="Punctuation">:</span>
|
|
<span class="Keyword">var</span> <span class="Identifier">events</span> <span class="Operator">=</span> <span class="Identifier">representObject</span><span class="Punctuation">(</span><span class="Identifier">item</span><span class="Punctuation">,</span> <span class="Identifier">childTagStyle</span><span class="Punctuation">,</span> <span class="Identifier">c</span><span class="Punctuation">)</span>
|
|
<span class="Keyword">while</span> <span class="Identifier">true</span><span class="Punctuation">:</span>
|
|
<span class="Keyword">let</span> <span class="Identifier">event</span> <span class="Operator">=</span> <span class="Identifier">events</span><span class="Punctuation">(</span><span class="Punctuation">)</span>
|
|
<span class="Keyword">if</span> <span class="Identifier">finished</span><span class="Punctuation">(</span><span class="Identifier">events</span><span class="Punctuation">)</span><span class="Punctuation">:</span> <span class="Keyword">break</span>
|
|
<span class="Keyword">yield</span> <span class="Identifier">event</span>
|
|
<span class="Keyword">yield</span> <span class="Identifier">YamlStreamEvent</span><span class="Punctuation">(</span><span class="Identifier">kind</span><span class="Punctuation">:</span> <span class="Identifier">yamlEndSequence</span><span class="Punctuation">)</span></pre>
|
|
|
|
|
|
<div class="row">
|
|
<div class="twelve-columns footer">
|
|
<span class="nim-sprite"></span>
|
|
<br/>
|
|
<small>Made with Nim. Generated: 2016-04-21 19:00:52 UTC</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
</body>
|
|
</html>
|