Convert between type-safe Elm values and YAML.
This is temporarily forked from terezka/yaml while that package is dormant.
$ elm install MaybeJustJames/yaml
and import the library in an elm file like this
import Yaml.Decode -- for decoders
import Yaml.Encode -- for encoders
Find the documentation on Elm's package website.
Say you have some YAML which looks like this:
---
- name:
first: Marie
last: Curie
occupation: [ chemist, physicist ]
age: 66
children: [ Irène, Ève ]
- name:
first: Alva
last: Myrdal
occupation: [ sociologist, diplomat, politician ]
age: 84
children: []
- name:
first: Svetlana
last: Alexievich
occupation: [ journalist, historian ]
age: 72
children: []
...
to decode this, you could write
import Yaml.Decode exposing (..)
type alias Woman =
{ name : String
, occupation : List String
, age : Int
, children : Int -- number of children
}
decoder : Decoder Woman
decoder =
map4 Woman
(map2 (\first last -> first ++ " " ++ last)
(at ["name", "first"] string)
(at ["name", "last"] string))
(field "occupation" (list string))
(field "age" int)
(map List.length (field "children" (list string)))
fromString
(list decoder)
yamlString -- The string containing the YAML example above
Say you are manipulating Github Actions configuration files which you might model like so:
import Yaml.Encode exposing (..)
-- Top-level structure
type alias GHActions =
{ name : String
, trigger : List String
, jobs : List Action
}
type alias Action =
{ id : String
, name : String
, runsOn : String
, steps : List Step
}
type alias Step =
{ name : String
, uses : String
, run : String
}
-- top-level encoder
encodeGHA : GHActions -> Encoder
encodeGHA action =
record
[ ("name", string action.name)
, ("on", list (string action.trigger))
, ("jobs", encodeJobs action.jobs)
]
encodeJobs : List Action -> Encoder
encodeJobs actions =
actions
|> List.map (\action -> (action.id, encodeJob action))
|> record
encodeJob : Action -> Encoder
encodeJob action =
record
[ ("name", action.name)
, ("runs-on", action.runsOn)
, ("steps", list (encodeStep action.steps))
]
encodeStep : Step -> Encoder
record
[ ("name", step.name)
, ("uses", step.uses)
, ("run", step.run)
]
Now that you have modelled the data and defined encoders, encoding into a YAML formatted string is done like:
-- An example Elm value that we could encode:
myAction : GHActions
myAction =
{ name = "Tests"
, trigger = ["push", "pull_request"]
, jobs = [
{ id = "test"
, name = "Test with elm-test"
, runsOn = "ubuntu-latest"
, steps = [ { name = "Test"
, uses = ""
, run = "npx elm-test"
}
, { name = "Verify examples"
, uses = ""
, run = "npm elm-verify-examples --run-tests"
}
]
}
]
}
-- A function to do the encoding / conversion
outputGHAction : String
outputGHAction =
encodeGHA myAction
|> document
|> toString 2
This will result in the YAML String:
---
name: Tests
on:
- push
- pull_request
jobs:
test:
name: Test with elm-test
runs-on: ubuntu-latest
steps:
- name: Test
uses:
run: npx elm-test
- name: Verify examples
uses:
run: npx elm-verify-examples --run-tests
...
The branch parser-logging
contains a version of the
parser logger
by @Janiczek.
This, along with writing detailed tests using elm-test is how I've been developing this package.
Please feel encouraged and welcome to submit bugs, PRs, etc.
This package uses elm-test and elm-verify-examples.
- Testing against the official YAML test suite. #7
You are free to copy, modify, and distribute this package with attribution under the terms of the BSD-3-Clause license. See the LICENSE file for details.