Updated from master

This commit is contained in:
Felix Krause 2016-02-15 22:56:36 +01:00
parent 029df0fe26
commit 26c8b6ceb1
5 changed files with 241 additions and 160 deletions

View File

@ -2,7 +2,7 @@
<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 - Module api</title>
<title>NimYAML - API Overview</title>
<link href="docutils.css" rel="stylesheet" type="text/css"/>
<link href="style.css" rel="stylesheet" type="text/css"/>
@ -15,27 +15,28 @@
<a class="pagetitle" href="/">NimYAML</a>
<a href="index.html">Home</a>
<a href="testing.html">Testing Ground</a>
<span>API:</span>
<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">Module api</h1>
=== API ===
<h1 id="overview">Overview</h1><p>NimYAML advocates parsing YAML input into native Nim types. Basic Nim library types like integers, floats and strings, as well as all tuples, enums and objects without private fields are supported out-of-the-box. Reference types are also supported, and NimYAML is able to detect if a reference occurs more than once and will serialize it accordingly. This means that NimYAML is able to dump and load potentially cyclic objects.</p>
<h1 class="title">API Overview</h1>
<h1 id="introduction">Introduction</h1><p>NimYAML advocates parsing YAML input into native Nim types. Basic Nim library types like integers, floats and strings, as well as all tuples, enums and objects without private fields are supported out-of-the-box. Reference types are also supported, and NimYAML is able to detect if a reference occurs more than once and will serialize it accordingly. This means that NimYAML is able to dump and load potentially cyclic objects.</p>
<p>While loading into and dumping from native Nim types is the preferred way to use NimYAML, it also gives you complete control over each processing step, so that you can for example only use the parser and process its event stream yourself. The following diagram gives an overview of NimYAML's features based on the YAML processing pipeline. The items and terminology YAML defines is shown in <em>italic</em>, NimYAML's implementation name is shown in <strong>bold</strong>.</p>
<object data="processing.svg" type="image/svg+xml" ></object>
<h1 id="intermediate-representation">Intermediate Representation</h1><p>The base of all YAML processing with NimYAML is the <a class="reference external" href="yaml.html#YamlStream">YamlStream</a>. This is basically an iterator over <a class="reference external" href="yaml.html#YamlStreamEvent">YamlStreamEvent</a> objects. Every proc that represents a single stage of the loading or dumping process will either take a <tt class="docutils literal"><span class="pre">YamlStream</span></tt> as input or return a <tt class="docutils literal"><span class="pre">YamlStream</span></tt>. Procs that implement the whole process in one step hide the <tt class="docutils literal"><span class="pre">YamlStream</span></tt> from the user. Every proc that returns a <tt class="docutils literal"><span class="pre">YamlStream</span></tt> guarantees that this stream is well-formed according to the YAML specification.</p>
<p>This stream-oriented API can efficiently be used to parse large amounts of data. The drawback is that errors in the input are only discovered while processing the <tt class="docutils literal"><span class="pre">YamlStream</span></tt>. If the <tt class="docutils literal"><span class="pre">YamlStream</span></tt> encounters an exception while producing the next event, it will throw a <tt class="docutils literal"><span class="pre">YamlStreamError</span></tt> which contains the original exception as <tt class="docutils literal"><span class="pre">parent</span></tt>. The caller should know which exceptions are possible as parents of <tt class="docutils literal"><span class="pre">YamlStream</span></tt> because they know the source of the <tt class="docutils literal"><span class="pre">YamlStream</span></tt> they provided.</p>
<h1 id="loading-yaml">Loading YAML</h1><p>If you want to load YAML character data directly into a native Nim variable, you can use <a class="reference external" href="yaml.html#load,Stream,K">load</a>. This is the easiest and recommended way to load YAML data. The following paragraphs will explain the steps involved.</p>
<p>For parsing, a <a class="reference external" href="yaml.html#YamlParser">YamlParser</a> object is needed. This object stores some state while parsing that may be useful for error reporting to the user. The <a class="reference external" href="yaml.html#present,YamlStream,Stream,TagLibrary,PresentationStyle,int">parse</a> proc implements the YAML processing step of the same name. All syntax errors in the input character stream are processed by <tt class="docutils literal"><span class="pre">parse</span></tt>, which will raise a <tt class="docutils literal"><span class="pre">YamlParserError</span></tt> if it encounters a syntax error.</p>
<p>For parsing, a <a class="reference external" href="yaml.html#YamlParser">YamlParser</a> object is needed. This object stores some state while parsing that may be useful for error reporting to the user. The <a class="reference external" href="yaml.html#parse,YamlParser,Stream">parse</a> proc implements the YAML processing step of the same name. All syntax errors in the input character stream are processed by <tt class="docutils literal"><span class="pre">parse</span></tt>, which will raise a <tt class="docutils literal"><span class="pre">YamlParserError</span></tt> if it encounters a syntax error.</p>
<p>Transforming a <tt class="docutils literal"><span class="pre">YamlStream</span></tt> to a native YAML object is done via <tt class="docutils literal"><span class="pre">construct</span></tt>. It skips the <tt class="docutils literal"><span class="pre">compose</span></tt> step for efficiency reasons. As Nim is statically typed, you have to know the target type when you write your loading code. This is different from YAML APIs of dynamically typed languages. If you cannot know the type of your YAML input at compile time, you have to manually process the <tt class="docutils literal"><span class="pre">YamlStream</span></tt> to serve your needs.</p>
<h1 id="dumping-yaml">Dumping YAML</h1><p>Dumping is preferredly done with <a class="reference external" href="yaml.html#dump,K,Stream,PresentationStyle,TagStyle,AnchorStyle,int">dump</a>, which serializes a native Nim variable to a character stream. Like <tt class="docutils literal"><span class="pre">load</span></tt>, you can use the steps involved separately.</p>
<p>You transform a variable into a <tt class="docutils literal"><span class="pre">YamlStream</span></tt> with <a class="reference external" href="yaml.html#represent,T,TagStyle,AnchorStyle">represent</a>. Depending on the <tt class="docutils literal"><span class="pre">AnchorStyle</span></tt> you specify, this will transform <tt class="docutils literal"><span class="pre">ref</span></tt> variables with multiple instances into anchored elements and aliases (for <tt class="docutils literal"><span class="pre">asTidy</span></tt> and <tt class="docutils literal"><span class="pre">asAlways</span></tt>) or write the same element into all places it occurs (for <tt class="docutils literal"><span class="pre">asNone</span></tt>). Be aware that if you use <tt class="docutils literal"><span class="pre">asNone</span></tt>, the value you serialize might not round-trip.</p>
<p>Transforming a <tt class="docutils literal"><span class="pre">YamlStream</span></tt> into YAML character data is done with <a class="reference external" href="yaml.html#present,YamlStream,Stream,TagLibrary,PresentationStyle,int">present</a>. You can choose from multiple presentation styles. <tt class="docutils literal"><span class="pre">psJson</span></tt> is not able to process some features of <tt class="docutils literal"><span class="pre">YamlStream``s, the other styles support all features and are guaranteed to round-trip to the same ``YamlStream</span></tt> if you parse the generated YAML character stream again. </p>
<p>Transforming a <tt class="docutils literal"><span class="pre">YamlStream</span></tt> into YAML character data is done with <a class="reference external" href="yaml.html#present,YamlStream,Stream,TagLibrary,PresentationStyle,int">present</a>. You can choose from multiple presentation styles. <tt class="docutils literal"><span class="pre">psJson</span></tt> is not able to process some features of <tt class="docutils literal"><span class="pre">YamlStream</span></tt> s, the other styles support all features and are guaranteed to round-trip to the same <tt class="docutils literal"><span class="pre">YamlStream</span></tt> if you parse the generated YAML character stream again. </p>
@ -43,7 +44,7 @@
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small>Made with Nim. Generated: 2016-02-15 19:50:47 UTC</small>
<small>Made with Nim. Generated: 2016-02-15 22:56:21 UTC</small>
</div>
</div>
</div>

View File

@ -15,8 +15,9 @@
<a class="pagetitle" href="/">NimYAML</a>
<a href="index.html">Home</a>
<a href="testing.html">Testing Ground</a>
<span>API:</span>
<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">
@ -85,7 +86,7 @@
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small>Made with Nim. Generated: 2016-02-15 19:50:47 UTC</small>
<small>Made with Nim. Generated: 2016-02-15 22:56:21 UTC</small>
</div>
</div>
</div>

77
serialization.html Normal file
View File

@ -0,0 +1,77 @@
<!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>
<header>
<a class="pagetitle" href="/">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">%YAML 1.2
--- !nim:system:seq(nim:system:int8)
- 1
- 2
- 3</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">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 is <em>not</em> supported, since its sice varies based on the target operation system. This makes it unfit for usage within NimYAML, because a value might not round-trip between a binary for a 32-bit OS and another binary for a 64-bit OS. 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">float32</span></tt> and <tt class="docutils literal"><span class="pre">float64</span></tt> are also supported, but <tt class="docutils literal"><span class="pre">float</span></tt> is not, for the same reason.</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. <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">seq</span></tt> and <tt class="docutils literal"><span class="pre">Table</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>, <tt class="docutils literal"><span class="pre">seq</span></tt> and <tt class="docutils literal"><span class="pre">Table</span></tt> define the type of all their 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">%YAML 1.2
--- !!seq
- !!int 1
- !!string foo</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>
<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">&quot;~&quot;</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#setTagUriForType.t,typedesc,string">setTagUriForType</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">setTagUriForType</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">&quot;!nim:my:seq&quot;</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-02-15 22:56:21 UTC</small>
</div>
</div>
</div>
</article>
</body>
</html>

View File

@ -15,8 +15,9 @@
<a class="pagetitle" href="/">NimYAML</a>
<a href="index.html">Home</a>
<a href="testing.html">Testing Ground</a>
<span>API:</span>
<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">

299
yaml.html

File diff suppressed because it is too large Load Diff