yaml

A simple YAML parsing and stringifying library for MoonBit, support a simplified YAML subset which can be convert to JSON.

moon add moonbit-community/yaml@0.0.6
Download zip
Version
0.0.6
License
MIT
Last updated
last month
Downloads
53K
README

#YAML

A simple YAML parsing and stringifying library for MoonBit, support a simplified YAML subset which can be convert to JSON.

This library is ported from yaml-rust2.

#Usage

#Basic Example

///|
test {
let source =
#|%YAML 1.2
#|---
#|YAML: YAML Ain't Markup Language™
#|
#|What It Is:
#| YAML is a human-friendly data serialization
#| language for all programming languages.
#|
#|YAML Resources:
#| YAML Specifications:
#| - YAML 1.2:
#| - Revision 1.2.2 # Oct 1, 2021 *New*
#| - Revision 1.2.1 # Oct 1, 2009
#| - Revision 1.2.0 # Jul 21, 2009
#| - YAML 1.1
#| - YAML 1.0
json_inspect(@yaml.Yaml::load_from_string(source), content=[
{
"YAML": "YAML Ain't Markup Language™",
"What It Is": "YAML is a human-friendly data serialization language for all programming languages.",
"YAML Resources": {
"YAML Specifications": [
{ "YAML 1.2": ["Revision 1.2.2", "Revision 1.2.1", "Revision 1.2.0"] },
"YAML 1.1",
"YAML 1.0",
],
},
},
])
}

#YAML

A simple YAML parsing and stringifying library for MoonBit, support a simplified YAML subset which can be convert to JSON.

This library is ported from yaml-rust2.

#Usage

#Basic Example

///|
test {
let source =
#|%YAML 1.2
#|---
#|YAML: YAML Ain't Markup Language™
#|
#|What It Is:
#| YAML is a human-friendly data serialization
#| language for all programming languages.
#|
#|YAML Resources:
#| YAML Specifications:
#| - YAML 1.2:
#| - Revision 1.2.2 # Oct 1, 2021 *New*
#| - Revision 1.2.1 # Oct 1, 2009
#| - Revision 1.2.0 # Jul 21, 2009
#| - YAML 1.1
#| - YAML 1.0
json_inspect(@yaml.Yaml::load_from_string(source), content=[
{
"YAML": "YAML Ain't Markup Language™",
"What It Is": "YAML is a human-friendly data serialization language for all programming languages.",
"YAML Resources": {
"YAML Specifications": [
{ "YAML 1.2": ["Revision 1.2.2", "Revision 1.2.1", "Revision 1.2.0"] },
"YAML 1.1",
"YAML 1.0",
],
},
},
])
}

#
EventReceiver

pub trait EventReceiver {
on_event(Self, event : Event) -> Unit
}

Trait to be implemented in order to use the low-level parsing API.

The low-level parsing API is event-based (a push parser), calling EventReceiver::on_event for each YAML Event that occurs. The EventReceiver trait only receives events. In order to receive both events and their location in the source, use MarkedEventReceiver. Note that EventReceivers implement MarkedEventReceiver automatically.

Event hierarchy

The event stream starts with an Event::StreamStart event followed by an Event::DocumentStart event. If the YAML document starts with a mapping (an object), an Event::MappingStart event is emitted. If it starts with a sequence (an array), an Event::SequenceStart event is emitted. Otherwise, an Event::Scalar event is emitted.

In a mapping, key-values are sent as consecutive events. The first event after an Event::MappingStart will be the key, and following its value. If the mapping contains no sub-mapping or sub-sequence, then even events (starting from 0) will always be keys and odd ones will always be values. The mapping ends when an Event::MappingEnd event is received.

In a sequence, values are sent consecutively until the Event::SequenceEnd event.

If a value is a sub-mapping or a sub-sequence, an Event::MappingStart or Event::SequenceStart event will be sent respectively. Following events until the associated Event::MappingStart or Event::SequenceEnd (beware of nested mappings or sequences) will be part of the value and not another key-value pair or element in the sequence.

For instance, the following yaml:
a: b c: d: e f: - g - h
will emit (indented and commented for lisibility):
StreamStart, DocumentStart, MappingStart, Scalar("a", ..), Scalar("b", ..) Scalar("c", ..), MappingStart, Scalar("d", ..), Scalar("e", ..), MappingEnd, Scalar("f", ..), SequenceStart, Scalar("g", ..), Scalar("h", ..), SequenceEnd, MappingEnd, DocumentEnd, StreamEnd

#
MarkedEventReceiver

pub trait MarkedEventReceiver {
on_event(Self, event : Event, _mark : Marker) -> Unit
}

#
YamlError

pub suberror YamlError {
YamlError(Marker, String)
}

impl Show for YamlError

#
Event

pub enum Event {
StreamStart
StreamEnd
DocumentStart
DocumentEnd
Alias(Int)
Scalar(String, TScalarStyle, Int, Tag?)
SequenceStart(Int, Tag?)
SequenceEnd
MappingStart(Int, Tag?)
MappingEnd
}

impl Eq for Event
impl Show for Event

#
Marker

pub struct Marker {
index : Int
line : Int
col : Int
}

impl Eq for Marker
impl Show for Marker

#
Parser

type Parser

#
Parser::keep_tags

fn Parser::keep_tags(self : Parser, value : Bool) -> Unit

Whether to keep tags across multiple documents when parsing.

This behavior is non-standard as per the YAML specification but can be encountered in the wild. This boolean allows enabling this non-standard extension. This would result in the parser accepting input from test QLJ7 of the yaml-test-suite:

%TAG !prefix! tag:example.com,2011: --- !prefix!A a: b --- !prefix!B c: d --- !prefix!C e: f

With keep_tags set to false, the above YAML is rejected. As per the specification, tags only apply to the document immediately following them. This would error on !prefix!B.

With keep_tags set to true, the above YAML is accepted by the parser.

#
Parser::load

fn[R : MarkedEventReceiver] Parser::load(self : Parser, recv : R, multi : Bool) -> Unit raise YamlError

Load the YAML from the stream in self, pushing events into recv.

The contents of the stream are parsed and the corresponding events are sent into the recveiver. For detailed explanations about how events work, see EventReceiver.

If multi is set to true, the parser will allow parsing of multiple YAML documents inside the stream.

Note that any EventReceiver is also a MarkedEventReceiver, so implementing the former is enough to call this function.

Errors

Returns YamlError when loading fails.

#
Parser::new

fn Parser::new(str : StringView) -> Parser

#
TScalarStyle

pub enum TScalarStyle {
Plain
SingleQuoted
DoubleQuoted
Literal
Folded
}

impl Eq for TScalarStyle

#
Tag

pub struct Tag {
handle : String
suffix : String
}

impl Eq for Tag
impl Show for Tag

#
Yaml

pub(all) enum Yaml {
Real(Double, String)
Integer(Int64)
String(String)
Boolean(Bool)
Array(Array[Yaml])
Map(Map[String, Yaml])
Null
BadValue
}

YAML data structure representation
impl Eq for Yaml
impl Show for Yaml
impl ToJson for Yaml

#
Yaml::dump

fn Yaml::dump(self : Yaml) -> String

Convenience helper to dump a Yaml value into a string using default settings.

#
Yaml::load_from_parser

fn Yaml::load_from_parser(parser : Parser) -> Array[Yaml] raise YamlError

#
Yaml::load_from_string

fn Yaml::load_from_string(source : StringView) -> Array[Yaml] raise YamlError

#
YamlEmitter

type YamlEmitter

The YAML serializer.

This is a simplified emitter that matches the parser features supported by this package.

Example

let input = "a: b\nc: d"
let docs = Yaml::load_from_string(input)
let emitter = YamlEmitter::new()
emitter.dump(docs[0])
let output = emitter.to_string()
// output == "---\na: b\nc: d"

#
YamlEmitter::compact

fn YamlEmitter::compact(self : YamlEmitter, compact : Bool) -> Unit

Set "compact inline notation" on or off for block sequences and mappings.

In this form, blocks cannot have any properties (such as anchors or tags), which should be OK, because this emitter doesn't emit those anyways.

#
YamlEmitter::dump

fn YamlEmitter::dump(self : YamlEmitter, doc : Yaml) -> Unit

Dump a YAML document into the internal buffer.

#
YamlEmitter::multiline_strings

fn YamlEmitter::multiline_strings(self : YamlEmitter, multiline_strings : Bool) -> Unit

Render strings containing multiple lines in literal block style.

Example

let input = "{foo: \"bar!\\nbar!\", baz: 42}"
let parsed = Yaml::load_from_string(input)
let emitter = YamlEmitter::new()
emitter.multiline_strings(true)
emitter.dump(parsed[0])
let output = emitter.to_string()
// output is:
// ---
// foo: |-
// bar!
// bar!
// baz: 42

#
YamlEmitter::new

fn YamlEmitter::new(writer? : StringBuilder) -> YamlEmitter

Create a new emitter serializing into writer.

#
YamlEmitter::to_string

fn YamlEmitter::to_string(self : YamlEmitter) -> String

Get the current emitted output as a string.