• Stars
    star
    170
  • Rank 223,357 (Top 5 %)
  • Language
    Elixir
  • License
    MIT License
  • Created over 9 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Yaml parser for Elixir based on native Erlang implementation

YAML Parser for Elixir

Build Status Module Version Hex Docs Total Download License Last Updated

This is a wrapper for yamerl - a native Erlang YAML parser which brings all of the functionalities to Elixir language.

Installation

Add :yaml_elixir as a dependency in your mix.exs file.

defp deps do
  [
     # ...
    {:yaml_elixir, "~> x.x"},
  ]
end

Where x.x.x equals the version in mix.exs (you can omit the last x). Always make sure to use the latest version.

Once you've done that, run mix deps.get in your command line to fetch the dependency.

Usage

With YamlElixir you have an access to two functionalities: one for parsing a string and an another one for parsing a file.

Run iex -S mix in your terminal to try how their works.

Parsing a string

yaml = """
  a: a
  b: 1
  c: true
  d: ~
  e: nil
"""
"  a: a\n  b: 1\n  c: true\n  d: ~\n  e: nil\n"
YamlElixir.read_from_string(yaml)
{:ok, %{"a" => "a", "b" => 1, "c" => true, "d" => nil, "e" => "nil"}}

Parsing a file

path = Path.join(File.cwd!(), "test/fixtures/flat.yml")
"/Users/KamilLelonek/Development/yaml-elixir/test/fixtures/flat.yml"
YamlElixir.read_from_file(path)
{:ok, %{"a" => "a", "b" => 1, "c" => true, "d" => nil, "e" => []}}

Support for atoms

By default, all map keys are processed as strings, as are all bareword or quoted values.

If you prefer to autodetect keys and values that begin with : as atoms, this can be accomplished by passing atoms: true as an option to any of the read_* functions.

yaml = """
  a: a
  b: 1
  c: true
  d: ~
  e: nil
  :f: :atom
"""
"  a: a\n  b: 1\n  c: true\n  d: ~\n  e: nil\n"
YamlElixir.read_from_string(yaml, atoms: true)
{:ok, %{:f => :atom, "a" => "a", "b" => 1, "c" => true, "d" => nil, "e" => "nil"}}

Atoms are not garbage collected by BEAM, so be careful with this option, and don't use it with user-supplied input.

If you enable autodetection of atoms, any string values entered (e.g. ":not_really_an_atom") will be converted to atoms, as well. If you only need to support a few atom values, it might be better to enable yamerl's custom tag for atoms:

:yamerl_app.set_param(:node_mods, [:yamerl_node_erlang_atom])

and then using the somewhat inconvenient syntax for it:

atom_key: !<tag:yamerl,2012:atom> atom_value

Support for keyword lists

Keyword lists can be returned in two ways. Either all maps can be transformed into keyword lists via the option maps_as_keywords: true or individually with a tag. To mark a block as a keyword list you must first pass in the node module which can process the tokens:

:yamerl_app.set_param(:node_mods, [YamlElixir.Node.KeywordList])

and then tag the desired block:

prod:
  foo: !<tag:yaml_elixir,2019:keyword_list>
    foo: bar
    bar: foo

This will return:

%{"prod" => %{"foo" => [{"bar", "foo"}, {"foo", "bar"}]}}

Note that due to a quirk in how yamerl parses YAML documents, using the flow style with this tag will not work. Do not expect your document to be processed if you write your YAML like this:

prod:
  foo: !<tag:yaml_elixir,2019:keyword_list> {foo: bar, bar: foo}

Elixir Sigil

The YamlElixir.Sigil module provides the ~y sigil that can be useful for example for keeping short configurations or other inlined YAML.

import YamlElixir.Sigil

@config ~y"""
debug: false
port: 9200
files:
  - some/file.csv
  - another/file.csv
"""

Use the a sigil modifier to turn on atom values from YAML:

~y":answer: yes"a

You can find more examples in test directory.

Merging anchors

In case your YAML contains anchors, you can have these resolved by passing merge_anchors: true:

yaml = """
  foo: &foo
    bar: 42
  baz:
    <<: *foo
"""
"  foo: &foo\n    bar: 42\n  baz:\n    <<: *foo\n"
YamlElixir.read_from_string(yaml, merge_anchors: true)

will result in

%{"yaml" => %{"foo" => %{"bar" => 42}, "baz" => %{"bar" => 42}}}

Mix tasks

Sometimes, you may want to use yaml_elixir in your mix tasks. To do that, you must ensure that the application has started.

Application.ensure_all_started(:yaml_elixir)

After that, you will be able to use :yaml-elixir in your mix tasks.

Contribution

In case of any problems or suggestions do not hesitate and create a pull request.

Credits

Copyright and License

Copyright (c) 2022 Kamil Lelonek

This library is MIT licensed. See the LICENSE for details.

More Repositories

1

exnumerator

Enumerable type in Elixir
Elixir
65
star
2

elixir-http-json-api

Minimal Elixir HTTP server with RESTful JSON API endpoint
Elixir
58
star
3

ex_wallet

A Bitcoin Wallet implementation in Elixir
Elixir
49
star
4

active_nothing

Ruby gem for emulating Smalltalk’s Conditionals in Ruby
Ruby
24
star
5

postgres-pubsub-elixir

PostgreSQL async notification via the LISTEN and NOTIFY in Elixir.
Elixir
21
star
6

healthchex

A set of Plugs to be used for Kubernetes healthchecks.
Elixir
19
star
7

k8s-gcp-terraform

Provisioning GKE with Terraform
HCL
18
star
8

circleci-cli

CLI for CircleCI REST API in Elixir lang
Elixir
15
star
9

ruby-tuples

Ruby implementation for tuples known from functional programming
Ruby
12
star
10

recurring_events

Recurring Events in Elixir
Elixir
10
star
11

Ansible-Ruby-DirectoryStatus

Ruby library for Ansible that checks given directory status
Ruby
10
star
12

figaro-elixir

Environmental variables manager based on Figaro for Elixir projects
Elixir
10
star
13

elixir-islands-engine

A simple game written in Elixir
Elixir
8
star
14

postgres-visualizer

PostgreSQL database visualizer with LucidChart
Shell
6
star
15

czy-i--na-wyk-ad

Algorytm decyzyjny pomagający zdecydować studentowi czy danego dnia należy pójść na wykład.
HTML
4
star
16

ansible-with-clojure

An example of Ansible module in Clojure
Shell
4
star
17

ex_postmark

Postmark adapter for sending template emails in Elixir
Elixir
4
star
18

cqs-in-elixir

An example of using CQS in Elixir
Elixir
4
star
19

ruby-motion-facebook

RubyMotion Facebook application
Ruby
4
star
20

ansible-playground

An example setup for Ansible automation
Nginx
4
star
21

ex_cors

An Elixir Plug-based CORS middleware for Phoenix Framework.
Elixir
3
star
22

elixir-api

Elixir API for frontend/mobile client
Elixir
3
star
23

ex_watcher

An Elixir file change watcher
Elixir
3
star
24

scala-vs-ruby

Comparison of Scala and Ruby examples
Scala
3
star
25

plug-validation

An example of validation in Elixir Plug layer.
Elixir
2
star
26

crystal-twitter-client

An example of Twitter client written in Crystal Language
Crystal
2
star
27

rabbit-elixir-ruby

A proof of concept - connecting Ruby with Elixir via RabbitMQ
Elixir
2
star
28

elixir_data_dog

A simple library for sending metrics to DataDog
Elixir
2
star
29

MS-RCPSP

Modeling Sheduling Problem in Constraint Programming
Scala
2
star
30

grpc-with-go

An example implementation of gRPC in Go
Go
2
star
31

ansible-dokku

Ansible infrastructure for Dokku installation
Vim Script
2
star
32

rails-new-way

A new approach to designing Rails application
Ruby
1
star
33

Hexagonal-BasicAuth

BasicAuth using Hexagonal Architecture
JavaScript
1
star
34

CookiesOrStorage

Persistency library for saving Cookies with LocalStorage fallback
CoffeeScript
1
star
35

ex_luminati

An Elixir client for https://luminati.io/.
Elixir
1
star
36

crystal-examples

Examples for Crystal Language
Crystal
1
star
37

elixir-graphql-blog

A blog engine with Elixir & GraphQL API
Elixir
1
star
38

squid3-cache-proxies

Configuring squid3 with Ansible on Vagrant VMs
1
star
39

brunch-coffee-sass-chai-mocha-karma

Brunch.io with coffeescript and sass for development and karma with chai and mocha for tests.
CoffeeScript
1
star
40

StorageOrCookies

Persistency library for saving LocalStorage with Cookies fallback
CoffeeScript
1
star
41

Hexagonal-oAuth

oAuth using Hexagonal Architecture
JavaScript
1
star