abradley2 / edn-parser / Edn.Parser

A parser for the Edn union type, for use with elm/parser. Supports full extensibility through custom data readers.

Main Functionality

edn : Parser Edn

Parser for the Edn datatype. You likely just want to use run instead and don't need the parser on its own like this.

run : String -> Result (List Parser.DeadEnd) Edn

Convenience function for using elm/parser to run the edn parser in this module against a given string


type alias Error =
List Parser.DeadEnd

Convenience type alias for elm/parser's List DeadEnd type

Extensibility


type alias Definitions error =
( String
, Dict String (Edn -> Result error Edn) 
)

Just as Clojure supports Edn extensibility through data_readers.clj maps, this parser supports supplying definitions to apply transformations to tagged values under a certain namespace. The Definitions type is a tuple of the namespace to interpret, and a dictionary of transforms for tags under that namespace.

Here is a short example of a "sum" tag under our application namespace that will sum up Edn integers in a list following it

applyDataReaders : Definitions error -> Edn -> Result error Edn

Apply a set of Defintions to an Edn value. Here is a full example of how we might add extensibility to Edn data consumed by our application

ednWithTags : String
ednWithTags =
    """{:sum #test-app/int-add (6 3)}"""

type TestAppError
    = InvalidIntSumArg Edn
    | ParserError Edn.Parser.Error

testAppDefinitions : Definitions TestAppError
testAppDefinitions =
    ( "test-app"
    , Dict.fromList
        [ ( "int-add"
          , \args ->
                case args of
                    EdnList ((EdnInt a) :: (EdnInt b) :: []) ->
                        Ok (EdnInt (a + b))

                    _ ->
                        Err (InvalidIntSumArg args)
          )
        ]
    )

result =
    ednWithTags
        |> (Edn.Parser.run >> Result.mapError ParserError)
        |> Result.map (Edn.Parser.applyDataReaders testAppDefinitions)