Re: NimYAML 0.7.0 released

2016-12-03 Thread moigagoo
Thanks a ton!


Re: NimYAML 0.7.0 released

2016-11-28 Thread flyx
`loadToJson` ignores tags because the JSON structures do not know anything 
about tags. You have several options:

**Using the serialization API with an implicit variant object**

First, you need to define the type for the tag `!remote`. You need to tell 
NimYAML how to load that type. Then, you define a variant object type that can 
hold either normal strings or `!remote` values. You then tell NimYAML to treat 
this variant object type implicitly for loading the chapters. Example code:


import yaml.serialization, yaml.taglib

type
  Remote = distinct string
  ChapterKind = enum
ckLocal, ckRemote
  Chapter = object
case kind: ChapterKind
of ckLocal:
  lValue: string
of ckRemote:
  rValue: Remote
  Root = object
chapters: seq[Chapter]

proc constructObject*(s: var YamlStream, c: ConstructionContext,
  result: var Remote) =
  # construct a Remote like a string
  constructObject(s, c, string(result))

setTagUri(Remote, "!remote")
markAsImplicit(Chapter)

var root: Root
load("""
chapters:
  - foo
  - bar
  - !remote http://example.com/somefile
""", root)

echo "Parsed chapters:"
for c in root.chapters:
  case c.kind
  of ckLocal: echo "[Local] ", c.lValue
  of ckRemote: echo "[Remote] ", string(c.rValue)


Sadly, you cannot simply transform the chapter values into some `tuple[value: 
String, remote: bool]` because NimYAML's serialization API uses tags to denote 
types, not annotations.

**Using the DOM API**

Perhaps simpler for simple use cases:


import yaml.dom

var document = loadDOM("""
chapters:
- foo
- bar
- !remote http://example.com/somefile
""")

echo "Parsed chapters:"
for c in document.root.pairs[0].value.children:
  echo if c.tag == "!remote": "[Remote] " else: "[Local] ", c.content


The DOM API needs some love; currently mappings are parsed into a 
`seq[tuple[key, value: YamlNode]]` which is not ideal for accessing specific 
subtrees. A Table would make more sense. Pull requests are welcome :).

**Using the sequential API**

This may be useful for use cases where you need to process the input 
sequentially since it doesn't load everything in an object and therefore is 
faster:


import yaml.parser, yaml.taglib, yaml.stream

var
  myTagLib = initCoreTagLibrary()
  yTagRemote = myTagLib.registerUri("!remote")
  p = newYamlParser(myTagLib)
  events = p.parse("""
chapters:
  - foo
  - bar
  - !remote http://example.com/somefile
""")

doAssert events.next().kind == yamlStartDoc
doAssert events.next().kind == yamlStartMap
let key = events.next()
doAssert key.kind == yamlScalar
doAssert key.scalarContent == "chapters"
doAssert events.next().kind == yamlStartSeq
var cur = events.next()
echo "Parsed chapters:"
while cur.kind != yamlEndSeq:
  doAssert cur.kind == yamlScalar
  echo if cur.scalarTag == yTagRemote: "[Remote] " else: "[Local] ", 
cur.scalarContent
  cur = events.next()
doAssert events.next().kind == yamlEndMap
doAssert events.next().kind == yamlEndDoc
doAssert events.finished()




Re: NimYAML 0.7.0 released

2016-11-25 Thread moigagoo
Hi @flyx!

I'm using NimYAML to parse a config file. I want to use custom tags but can't 
figure out form the docs how to do it.

Here's a glimpse of what I want to be able to handle:


chapters:
  - foo
  - bar
  - !remote http://example.com/somefile


When I load this content with `loadToJson` and iterate over `[0]["chapters"]` 
the tag is ignored. I tried registering the tag URI but I don't know what to 
with with the TagId I get from it.

Could you please help me with that?


Re: NimYAML 0.7.0 released

2016-11-08 Thread flyx
NimYAML 0.8.0 is now available. Its focus was on making it more capable of 
being used for configuration files:

  * You can now set default values of object fields with `setDefaultValue`.
  * You can now mark object fields as transient with `markAsTransient` so that 
they are not serialized or expected in YAML input.
  * You can now ignore input keys with `ignoreInputKey`. This makes it easier 
to parse YAML input that contains data which is not of interest.



Moreover, timestamps can now be parsed into `Time` values. However, this is 
only usable with most recent Nim devel version, since timezones are broken in 
0.15.2. 


NimYAML 0.7.0 released

2016-10-01 Thread flyx
Since we have Nim 0.15.0 now, NimYAML 0.7.0 follows. This list is relevant for 
upgrading from a previous version:

  * The API has been split over several modules. Importing the [base 
package](http://forum.nim-lang.org///flyx.github.io/NimYAML/yaml.html) imports 
all subpackages, so this change is backwards-compatible. However, you are 
encouraged to import only those parts of the API you need.
  * It is possible to call all loading procs with a `string` instead of a 
`Stream` input. Loading YAML directly from a string will enable NimYAML to 
include correct line content in its parsing exceptions. This is not always 
possible with using Streams, where it will return an empty string instead if 
the line content is not available.
  * The API for writing custom represent/construct procs has changed. 
[representObject](http://forum.nim-lang.org///flyx.github.io/NimYAML/serialization.html#representobject)
 does not return a `YamlStreamEvent` iterator anymore. Instead, the 
implementation shall put its generated event(s) into the 
`SerializationContext`. You have to update existing code if you use that 
functionality.



Major new features are:

  * The serialization API features better checks and error messages in case of 
invalid input. This makes NimYAML feasible for user-written configuration files.
  * Usage of first-class iterators has been removed to make compiling to JS 
possible. However, finishing this is still blocked by a Nim compiler bug, see 
[here](https://github.com/flyx/NimYAML/issues/24).
  * YAML compliance has been improved.



A complete list of changes is available 
[here](https://github.com/flyx/NimYAML/blob/devel/CHANGELOG.md). NimYAML 0.7.0 
requires Nim 0.15.0.