NimYAML

repository·devel·Indexed 42 days ago

https://github.com/flyx/nimyaml

A pure Nim implementation of the YAML format that requires only the Nim standard library. It provides a high-level API to serialize Nim objects to YAML streams and back, as well as a low-level event-based API. Version 2.0.0 introduces a redesigned Dumper object for configuration and supports Nim 2.0 features.

Tokens
2.9K
Snippets
9
Records
16
Agent score
53%

What's inside NimYAML

  1. Understand NimYAML serialization limitations

    devel

    NimYAML provides serialization (dumping) and deserialization (loading) for Nim objects, but currently has the following limitations for types used in loading and dumping:

    • Polymorphism: You cannot load a ref Child into a field defined with type ref Parent.
    • Generic objects: The auto-generated loading/dumping functions cannot process instances of generic objects within the type hierarchy.
    • Default values: NimYAML does not support default values introduced in Nim 2.0. It uses its own {.defaultVal: "foo".} pragma instead.
  2. Understand NimYAML parser and presenter error reporting

    devel

    When using the NimYAML web service, the output indicates the status of the processing via specific error codes:

    • Success (Code 0): The YAML is parsed and presented correctly. The output is displayed in black.
    • Parser Error (Code 1): An error occurred during the parsing phase. The output will specify the line, column, message, and detail of the error, and the text will be displayed in orange.
    • Presenter Error (Code 2): The YAML was parsed successfully, but an error occurred when attempting to present/format the data. The output will display the message and the text will be displayed in orange.
    • Server Unavailable (Status 0): The YAML parser server is not reachable. The output will be displayed in red.
  3. Understand NimYAML serialization tag shorthands

    devel

    NimYAML uses two specific tag shorthands to distinguish between standard YAML types and Nim-specific types:

    • !!: Expands to tag:yaml.org,2002:. This is used for types from the YAML failsafe, JSON, or core schemas.
    • !n!: Expands to tag:nimyaml.org,2016:. This is used for types from the Nim standard library.

    When dealing with generic types, NimYAML embeds the expanded tag of the generic parameter into the parent tag. To maintain YAML compliance, exclamation marks are removed from expanded tags and commas are replaced by semicolons.

  4. Configure NimYAML dependency for Nim 1.6.x

    devel

    NimYAML requires Nim 2.0.0 or later for the current version. If you are still using Nim 1.6.x, you must use version v1.1.0. Add the following requirement to your .nimble file:

    requires "yaml ^= 1.1.0"
  5. Map custom YAML types using setTagUri

    devel

    NimYAML does not support all standard YAML types (like !!int or !!float) out of the box to avoid ambiguity in a static type system. To use these types, you must:

    1. Create a distinct type derived from your desired base type (e.g., int32 or float64).
    2. Use the setTagUri function to assign the specific YAML tag to that type.

    Example logic:

    # Conceptual approach
    type MyInt = distinct int32
    setTagUri(MyInt, "!!int")
  6. Update module imports for NimYAML 2.x

    devel

    In NimYAML 2.x, import yaml only imports the high-level API for loading and dumping. If you require lower-level APIs, you must import them explicitly. The yaml/serialization module has been split into three distinct modules:

    • yaml/loading: Provides load and related procedures.
    • yaml/dumping: Provides dump and related procedures.
    • yaml/native: Provides low-level procedures like construct and represent.

    Note that import yaml automatically includes all of these.

  7. Migrate to NimYAML 2.x

    devel
    NimYAML 2.0.0 introduces breaking changes to support Nim 2.0 features (like default object field values) and to simplify the YAML dumping API for configuration file use cases. Key changes include a shift from direct function arguments to a Dumper object for configuration, and a more minimal default output style.
  8. Use the NimYAML Testing Ground to validate YAML input

    devel

    The NimYAML project provides a web-based 'Testing Ground' service that allows you to process YAML input on the fly. You can paste YAML snippets into the input field to see how the NimYAML parser and presenter handle them in real-time.

    Supported output styles include:

    • minimal
    • default
    • explanatory (checked by default)
    • block (Block Only)
    • json
    • tokens
  9. Configure default output style and directives

    devel

    NimYAML 2.x emits a minimal YAML style by default. The %YAML directive, %TAG directive, and the --- document separator are no longer emitted automatically.

    To restore or customize these:

    • Emit %YAML directive: Set dumper.presentation.outputVersion.
    • Emit %TAG directive: Set dumper.serialization.handles = initNimYamlTagHandle().
    • Emit --- separator: This is now only emitted if the root node has an anchor or tag. To force the tag on the root node, set dumper.serialization.tagStyle = tsRootOnly.
    # To emit %TAG directive
    dumper.serialization.handles = initNimYamlTagHandle()
    
    # To emit root tag
    dumper.serialization.tagStyle = tsRootOnly
  10. Update custom constructObject and representObject signatures

    devel

    If you implement custom constructors or representers, you must update their signatures to match the NimYAML 2.x requirements.

    constructObject changes: The YamlStream parameter is removed. Instead, access the stream via ctx.input within the ConstructionContext.

    representObject changes: The SerializationContext and TagStyle parameters have been consolidated into a single SerializationContext (named ctx).

    # New constructObject signature
    proc constructObject*(
      ctx: var ConstructionContext,
      result: var MyObject
    ) {.raises: [YamlConstructionError, YamlStreamError].}
    
    # New representObject signature
    proc representObject*(
      ctx: var SerializationContext,
      value: MyObject,
      tag: TagId
    ): {.raises: [YamlSerializationError].}