Code Monkey home page Code Monkey logo

json-schema-to-elm's Introduction

Hi there ๐Ÿ‘‹

I'm Peter and I dabble in odd functional projects as shown in the pinned section below:

json-schema-to-elm's People

Contributors

albertored avatar dependabot-preview[bot] avatar dependabot[bot] avatar dragonwasrobot avatar henkpoley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

json-schema-to-elm's Issues

object refs and naming

I'm seeing some issues with the printer when using full object refs. The first issues is in the import where the "#" does not seem to be expanded to "root"|"Root". The 2nd issue is that the name space does not make it into the type alias.

oval.json

{
    "$schema": "http://json-schema.org/draft-04/schema",
    "title": "Oval",
    "id": "http://example.com/schema2/oval.json",
    "description": "Schema for a oval shape",
    "type": "object",
    "properties": {
        "attr": {
            "$ref": "http://example.com/schema2/attr.json#"
        }
    },
    "required": ["attr"]
}

attr.json

{
    "$schema": "http://json-schema.org/draft-04/schema",
    "title": "Attr",
    "id": "http://example.com/schema2/attr.json",
    "description": "Schema for shape attributes",
    "type": "object",
    "properties": {
        "color": {
            "id": "#color",
            "type": "string",
            "enum": [ "red", "yellow", "green", "blue" ]
        },
        "point": {
            "id": "#point",
            "type": "object",
            "properties": {
                "x": {
                    "type": "number"
                },
                "y": {
                    "type": "number"
                }
            },
            "required": [ "x", "y" ]
        }
    }
}

The first issue is

import Domain.Attr
    exposing
        ( #
        , #Decoder
        , encode#
        )

which if corrected by hand leads to the next issue

21 Jun 08:16:21 - info: compiled Oval.elm and 84 cached files into app.js in 403ms
Elm compile: Main.elm, in web/elm, to ../static/js/main.js
-- ALIAS PROBLEM ------------------------------------------- ././Domain/Oval.elm

This type alias is recursive, forming an infinite type!

46|>type alias Root =
47|>    { attr : Root
48|>    }

When I expand a recursive type alias, it just keeps getting bigger and bigger.
So dealiasing results in an infinitely large type! Try this instead:

    type Root
        = Root { attr : Root }

This is kind of a subtle distinction. I suggested the naive fix, but you can
often do something a bit nicer. So I would recommend reading more at:
<https://github.com/elm-lang/elm-compiler/blob/0.18.0/hints/recursive-alias.md>

The fix I see is to remove the imports of the function names and have them use the full namespace

suggested output for Oval.elm

module Domain.Oval exposing (..)

-- Schema for a oval shape

import Json.Decode as Decode
    exposing
        ( float
        , int
        , string
        , list
        , succeed
        , fail
        , map
        , maybe
        , field
        , at
        , andThen
        , oneOf
        , nullable
        , Decoder
        )
import Json.Decode.Pipeline
    exposing
        ( decode
        , required
        , optional
        , custom
        )
import Json.Encode as Encode
    exposing
        ( Value
        , float
        , int
        , string
        , list
        , object
        )

-- removed the clashing imported names
import Domain.Attr
    --exposing
        --( Root
        --, rootDecoder
        --, encodeRoot
        --)

-- added full names
type alias Root =
    { attr : Domain.Attr.Root
    }


rootDecoder : Decoder Root
rootDecoder =
    decode Root
       -- added full names
        |> required "attr" Domain.Attr.rootDecoder


encodeRoot : Root -> Value
encodeRoot root =
    let
        attr =
            -- added full names
            [ ( "attr", Domain.Attr.encodeRoot root.attr ) ]
    in
        object <|
            attr

Problem Elm Output

Domain/Oval.elm

module Domain.Oval exposing (..)

-- Schema for a oval shape

import Json.Decode as Decode
    exposing
        ( float
        , int
        , string
        , list
        , succeed
        , fail
        , map
        , maybe
        , field
        , at
        , andThen
        , oneOf
        , nullable
        , Decoder
        )
import Json.Decode.Pipeline
    exposing
        ( decode
        , required
        , optional
        , custom
        )
import Json.Encode as Encode
    exposing
        ( Value
        , float
        , int
        , string
        , list
        , object
        )
import Domain.Attr
    exposing
        ( #
        , #Decoder
        , encode#
        )


type alias Root =
    { attr : Root
    }


rootDecoder : Decoder Root
rootDecoder =
    decode Root
        |> required "attr" rootDecoder


encodeRoot : Root -> Value
encodeRoot root =
    let
        attr =
            [ ( "attr", encodeRoot root.attr ) ]
    in
        object <|
            attr

Encapsulate printers and parsers in their own contexts

Create two context folders: parser and printer containing all parsers and printers, respectively, along with one parser.ex and printer.ex acting as the facade for that context.

Also: get rid of all the import statements and use alias instead.

ideas

Hello,

I was just checking out your project and it seems to fit with an idea I've been playing with here: https://github.com/jschoch/jsonstruct

I built this to help elm-elixir interop and just got around to looking back at the elm side again.

Have you considered generating elixir struct definitions from the schemas?

Print types and decoders in separate files?

Investigate the possibility of printing types and decoders in separate files, such that we get

module Foo.Types
module Foo.Decoders
module Foo.Encoder

or perhaps at least group them by type in the outputted files.

Bool vs Boolean

it appears the generator specifies type "Boolean", but it should be "Bool"

Add Object printer

Add module that takes an ObjectType intermediate representation and prints out its corresponding Elm type and an Elm JSON Decoder.

Improve error handling

Add some helpful error messages for stuff like:

  • dangling references
  • missing/mandatory properties

Referenced allOf types not parsing

Hi Peter,

This is a great project! I'm still trying to get my head around how it works while trying to convert the very large and complicated FHIR schemas to elm.

I've noticed it keeps throwing an error when interpreting allOf type references, which are used in just about every FHIR definition (for example, http://hl7.org/fhir/Element.schema.json)


The value of "type" at '#/definitions/Element/allOf/0' did not match a known node type

    "type": nil
            ^^^

Was expecting one of the following types

    ["null", "boolean", "object", "array", "number", "integer", "string"]

Hint: See the specification section 6.25. "Validation keywords - type"
<http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25>

This happens when passing the entire schema directory to js2e as well as the individual file. Not sure if it's a problem with js2e or the FHIR group's definitions (which apparently do validate). Do you have any ideas how I could go about contributing to fix this?

Thanks!

Support Elixir 1.6

There is a breaking change in how to_string works on URI, and since json-schema-to-elm does a lot of URI comparison both parsed and to_string'ed things break unexpectedly.

Sanitise names in the JSON schema

We want to do the following in order to sanitise identifier in the outputted Elm code:

  • Replace all kebab-case, snake_case and space case with camelCase,
  • replace all (reasonable) special characters in identifiers with corresponding plain text version, e.g. ! becomes 'bang', @ becomes 'at', % becomes 'percent', / becomes 'slash', etc,
  • array indices should be replaced with their corresponding plain text versions, e.g. 0 becomes 'zero', 1 becomes 'one', etc, and
  • add a proper set of tests to ensure the code is called in all relevant instances.

Add preamble printer

  • Add a module which prints the preamble of the Elm file(s) containing the types and decoders.
  • It should also print imports from other Elm files, i.e. if a decoder or type depends on another decoder or type.

Support patternProperties

As far as I can tell, there is currently no support for patternProperties, arguably one of the more useful features of JSON schema.

Here is how I'd imagine to map things. Say we have two different patterns:

{
	"title": "main",

	"patternProperties": {
		"regexp1": {
			"title": "title1",
			...
		},
		"regexp2": {
			"title": "title2"
			...
		}
	}
}

This would translate to something like this:

type alias Main = 
	{ title1 : Dict String a
	, title2  : Dict String b
	}

Here, the string keys would be the JSON key (matching the respective regexp), and a resp. b would be the types defined by the resp. ....

Add array printer

Add module that takes an ArrayType intermediate representation and prints out its corresponding Elm type and an Elm JSON Decoder.

Support object and definitions in same file

At the moment definitions in the same json of main object leads to name collision errors.

Take for example

{
    "$schema": "http://json-schema.org/draft-04/schema",
    "title": "Wine",
    "id": "http://example.com/wine.json",
    "description": "Schema for wine",
    "type": "object",
    "properties": {
        "color": {
            "$ref": "#/definitions/color"
        }
    },
    "required": [
        "color"
    ],
    "definitions": {
        "color": {
            "id": "#color",
            "type": "string",
            "enum": [
                "red",
                "white"
            ]
        }
    }
}

I get

--- NAME COLLISION --------------- examples/wine/wine.json

Found more than one property with identifier '#/definitions/color'

--- NAME COLLISION --------------- examples/wine/wine.json

Found more than one property with identifier 'http://example.com/wine.json#color'

Maybe I'm doing something wrong in defining the schema?

Add ref printer

Add module that takes an TypeReference intermediate representation and prints out its corresponding Elm type and an Elm JSON Decoder.

Handle subschemas with both "definitions" and "type"

Currently, we don't recognise subschemas which may contain both a "definitions" property and a "type" property. The current assumption is that all definitions are contained in the "definitions" property of the root schema, which might be nested, while we should probably aim for something more generic that can parse arbitrarily nested schemas found in "definitions" and maybe also in the "properties" property of the root schema. First step is to check the JSON schema spec to find out exactly where "definitions" properties can be expected.

From discussion in #51
"""
In JS2E.Parsers.Util.determine_node_parser/3 there is a list of predicate functions:

predicate_node_type_pairs = [
{&AllOfParser.type?/1, &AllOfParser.parse/5},
{&AnyOfParser.type?/1, &AnyOfParser.parse/5},
{&ArrayParser.type?/1, &ArrayParser.parse/5},
{&DefinitionsParser.type?/1, &DefinitionsParser.parse/5}, // <-- the bad guy
{&EnumParser.type?/1, &EnumParser.parse/5},
{&ObjectParser.type?/1, &ObjectParser.parse/5},
{&OneOfParser.type?/1, &OneOfParser.parse/5},
{&PrimitiveParser.type?/1, &PrimitiveParser.parse/5},
{&TupleParser.type?/1, &TupleParser.parse/5},
{&TypeReferenceParser.type?/1, &TypeReferenceParser.parse/5},
{&UnionParser.type?/1, &UnionParser.parse/5}
]
which is used to determine what parser to call given a node object.

So when we parse a root node that contains both a "properties" and "definitions" property the following calls happen:
RootParser.ex::parse_schema/2 -> RootParser.ex::parse_root_object/3 -> Util.parse_type/4 -> Util.determine_node_parser/3 which calls DefinitionsParser.type? that looks like this:

def type?(%{"definitions" => definitions})
when is_map(definitions), do: true
def type?(_schema_node), do: false
which returns true, thus it never hits the ObjectParser.type?.

Since there is an example in the spec of nested "definitions" properties: http://json-schema.org/latest/json-schema-core.html#id-keyword - which means that a nested schema can probably also contain both "properties" and "definitions" on the same node.

Noting that "definitions" is a bit of a special case compared to the other node types, since it can co-exist with other node types on the same node (if that makes sense), it should probably be moved out of determine_node_parser and into parse_type such that parse_type checks each node if it also has a definitions property. While this sounds pretty straight forward to fix it does create a few too many extra checks to my liking.
"""

Add primitive printer

Add module that takes an PrimitiveType intermediate representation and prints out its corresponding Elm type and an Elm JSON Decoder.

JSON schema filename / URL as root schema alias?

We need a solution for handling the case where a $ref points to a filename/URL different from the URI specified in the JSON schema root "id" property. For example,

The real world JSON schema:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "http://hl7.org/fhir/json-schema/Element",
  "$ref": "#/definitions/Element",
  "description": "see http://hl7.org/fhir/json.html#schema for information about the FHIR Json Schemas",
  "definitions": {
    "Element": {
      "allOf": [
        {
          "description": "Base definition for all elements in a resource.",
          "properties": {
            "id": {
              "description": "unique id for the element within a resource (for internal references). This may be any string value that does not contain spaces.",
              "type": "string"
            },
            "_id": {
              "description": "Extensions for id",
              "$ref": "Element.schema.json#/definitions/Element"
            },
            "extension": {
              "description": "May be used to represent additional information that is not part of the basic definition of the element. In order to make the use of extensions safe and manageable, there is a strict set of governance  applied to the definition and use of extensions. Though any implementer is allowed to define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension.",
              "type": "array",
              "items": {
                "$ref": "Extension.schema.json#/definitions/Extension"
              }
            }
          }
        }
      ]
    }
  }
}

is located at http://hl7.org/fhir/Element.schema.json and includes a reference like "$ref": "Element.schema.json#/definitions/Element" but its root schema has the ID property "id": "http://hl7.org/fhir/json-schema/Element", which is obviously different from the actual location URL.

Consider a solution that adds the filename (or some URI merge of the id and filename) as an alias for a given JSON schema document.

Add JSON encoders

Add support for also printing JSON encoders besides types and JSON decoders.

  • Array types
  • Enum types
  • Object types
  • OneOf types
  • Union types
  • Add print_encoder to printer module.

Consider #25, when implementing this.

Add enum printer

Add module that takes an EnumType intermediate representation and prints out its corresponding Elm type and an Elm JSON Decoder.

arg of file with $ref creates error, arg of dir path works ok.

opening this because I can't re-open #36

oddly had this error, and for some reason decided to re-clone the repo and try again first thing in the morning. it worked on the example so I tried to run it on some of my project's schema files which threw an error. I added some debugging lines and eventually tried the example from the previous issue which also had errors. I then tried to clone a new copy of the repo on /tmp which also failed. Baffled I tried to run your unmodified example and this happened...


../../js2e circle.json

08:35:47.279 [debug] Arguments: ["circle.json"]

08:35:47.289 [debug] Files: ["circle.json"]

08:35:47.314 [debug] Parsing type with name: #, path: , and value: %{"$schema" => "http://json-schema.org/draft-04/schema", "description" => "Schema for a circle shape", "id" => "http://example.com/circle.json", "properties" => %{"center" => %{"$ref" => "http://example.com/definitions.json#point"}, "color" => %{"$ref" => "http://example.com/definitions.json#color"}, "radius" => %{"type" => "number"}}, "required" => ["center", "radius"], "title" => "Circle", "type" => "object"}

08:35:47.320 [debug] node_parser: &JS2E.Parsers.ObjectParser.parse/5

08:35:47.321 [debug] Parsing '["#"]' as ObjectType

08:35:47.324 [debug] Parsing type with name: center, path: #, and value: %{"$ref" => "http://example.com/definitions.json#point"}

08:35:47.324 [debug] node_parser: &JS2E.Parsers.TypeReferenceParser.parse/5

08:35:47.325 [debug] parsing '["#", "center"]' as TypeReference

08:35:47.330 [debug] Parsed type reference: %JS2E.Types.TypeReference{name: "center", path: %URI{authority: "example.com", fragment: "point", host: "example.com", path: "/definitions.json", port: 80, query: nil, scheme: "http", userinfo: nil}}

08:35:47.331 [debug] Parsing type with name: color, path: #, and value: %{"$ref" => "http://example.com/definitions.json#color"}

08:35:47.331 [debug] node_parser: &JS2E.Parsers.TypeReferenceParser.parse/5

08:35:47.331 [debug] parsing '["#", "color"]' as TypeReference

08:35:47.331 [debug] Parsed type reference: %JS2E.Types.TypeReference{name: "color", path: %URI{authority: "example.com", fragment: "color", host: "example.com", path: "/definitions.json", port: 80, query: nil, scheme: "http", userinfo: nil}}

08:35:47.331 [debug] Parsing type with name: radius, path: #, and value: %{"type" => "number"}

08:35:47.331 [debug] node_parser: &JS2E.Parsers.PrimitiveParser.parse/5

08:35:47.333 [debug] Parsing '["#", "radius"]' as primitive type

08:35:47.334 [debug] Parsed primitive type: %JS2E.Types.PrimitiveType{name: "radius", path: ["#", "radius"], type: "number"}

08:35:47.334 [debug] Descendants types dict: %{"#/center" => %JS2E.Types.TypeReference{name: "center", path: %URI{authority: "example.com", fragment: "point", host: "example.com", path: "/definitions.json", port: 80, query: nil, scheme: "http", userinfo: nil}}, "#/color" => %JS2E.Types.TypeReference{name: "color", path: %URI{authority: "example.com", fragment: "color", host: "example.com", path: "/definitions.json", port: 80, query: nil, scheme: "http", userinfo: nil}}, "#/radius" => %JS2E.Types.PrimitiveType{name: "radius", path: ["#", "radius"], type: "number"}}

08:35:47.334 [debug] Property ref dict: %{"center" => ["#", "center"], "color" => ["#", "color"], "radius" => ["#", "radius"]}

08:35:47.338 [debug] Parsed object type: %JS2E.Types.ObjectType{name: "#", path: ["#"], properties: %{"center" => ["#", "center"], "color" => ["#", "color"], "radius" => ["#", "radius"]}, required: ["center", "radius"]}

08:35:47.343 [debug] type_ref_uri: %URI{authority: "example.com", fragment: "color", host: "example.com", path: "/definitions.json", port: 80, query: nil, scheme: "http", userinfo: nil}

08:35:47.344 [debug] has_different_absolute_path? was true for: {%URI{authority: "example.com", fragment: "color", host: "example.com", path: "/definitions.json", port: 80, query: nil, scheme: "http", userinfo: nil}, %URI{authority: "example.com", fragment: nil, host: "example.com", path: "/circle.json", port: 80, query: nil, scheme: "http", userinfo: nil}}

08:35:47.345 [debug] type_ref_schema_uri = "http://example.com/definitions.json"

08:35:47.347 [debug] full schema dict =

%{"http://example.com/circle.json" => %JS2E.Types.SchemaDefinition{description: "Schema for a circle shape",
   id: %URI{authority: "example.com", fragment: nil, host: "example.com",
    path: "/circle.json", port: 80, query: nil, scheme: "http", userinfo: nil},
   title: "Circle",
   types: %{"#" => %JS2E.Types.ObjectType{name: "#", path: ["#"],
      properties: %{"center" => ["#", "center"], "color" => ["#", "color"],
        "radius" => ["#", "radius"]}, required: ["center", "radius"]},
     "#/center" => %JS2E.Types.TypeReference{name: "center",
      path: %URI{authority: "example.com", fragment: "point",
       host: "example.com", path: "/definitions.json", port: 80, query: nil,
       scheme: "http", userinfo: nil}},
     "#/color" => %JS2E.Types.TypeReference{name: "color",
      path: %URI{authority: "example.com", fragment: "color",
       host: "example.com", path: "/definitions.json", port: 80, query: nil,
       scheme: "http", userinfo: nil}},
     "#/radius" => %JS2E.Types.PrimitiveType{name: "radius",
      path: ["#", "radius"], type: "number"},
     "http://example.com/circle.json#" => %JS2E.Types.ObjectType{name: "#",
      path: ["#"],
      properties: %{"center" => ["#", "center"], "color" => ["#", "color"],
        "radius" => ["#", "radius"]}, required: ["center", "radius"]}}}}

08:35:47.347 [debug] type_ref_schema_def was: nil
** (UndefinedFunctionError) function nil.id/0 is undefined or private
    nil.id()
    (js2e) lib/printers/preamble_printer.ex:117: JS2E.Printers.PreamblePrinter.resolve_dependency/4
    (elixir) lib/enum.ex:1755: Enum."-reduce/3-lists^foldl/2-0-"/3
    (js2e) lib/printers/preamble_printer.ex:57: JS2E.Printers.PreamblePrinter.create_imports/3
    (js2e) lib/printers/preamble_printer.ex:35: JS2E.Printers.PreamblePrinter.print_preamble/3
    (js2e) lib/printer.ex:51: JS2E.Printer.print_schema/3
    (js2e) lib/printer.ex:33: anonymous fn/5 in JS2E.Printer.print_schemas/2
    (stdlib) lists.erl:1263: :lists.foldl/3

baffled as to how it got in this broken state. I'm sure it worked this morning but I can't get it to work now...

Add oneOf Printer

Add module that takes an OneOfType intermediate representation and prints out its corresponding Elm type and an Elm JSON Decoder.

Investigate parsing of generic 'array' and 'object' types

Investigate whether there is a reasonable type+parser+decoder that can be generated from the generic types:

{ "type": "object" }

and

{ "type": "array" }

i.e. maybe some kind of restricted versions of Dict and List like:

type SimpleType
   = SimpleBoolean Bool
   | SimpleFloat Float
   | SimpleInteger Int
   | SimpleIntegerArray (List Int)
   | SimpleFloatArray (List Float)

type SimpleDict =
    Dict String SimpleType

type SimpleList =
    List SimpleType

Online or executable version

Hello, this tool looks great and I would like to utilize this tool for one-off generation of Elm JSON decoders based on a source JSON Schema but I'm not an Elixir developer. Is there an online tool available at least for evaluating the behavior or an executable available that one could use without having to learn and manage the Erlang/Elixir tool-chain?

Add type definitions for the different type of values used in the json schema

Combine the definitions listed in section 4 of core spec and validation keywords in section 5 of the validation spec to form a list of type definitions covering what are a reasonable set of types that can be turned into elm types and decoders, something like this:

  • Object type ~ "properties"
  • Array type ~ "items"
  • Primitive type ~ ("number", "integer", "boolean" and "string")
  • Primitive union type ~ "enum"
  • Object union type ("oneOf", "anyOf", "allOf")

Support nested module names

Support nested module names:
--module_name Foo.Bar.Baz
Which should result in the folder structure:
Foo/Bar/Baz
and module name:
module Foo.Bar.Baz.

$ref as object

AFAIK this should work but perhaps it only works with the libraries I have been using.

y.json

{
    "$schema": "http://json-schema.org/draft-04/schema",
    "title": "Circle",
    "id": "http://example.com/y.json",
    "description": "Schema for a circle shape",
    "type": "object",
    "properties": {
        "x": {
            "$ref": "http://example.com/x.json"
        }
    },
    "required": ["x"]
}

x.json

{
    "$schema": "http://json-schema.org/draft-04/schema",
    "type": "object",
    "title": "x",
    "id": "http://example.com/x.json",
    "description": "Schema for common types",
    "properties": {
        "color": {
            "id": "#color",
            "type": "string",
            "enum": [ "red", "yellow", "green", "blue" ]
        },
        "point": {
            "id": "#point",
            "type": "object",
            "properties": {
                "x": {
                    "type": "number"
                },
                "y": {
                    "type": "number"
                }
            },
            "required": [ "x", "y" ]
        }
    }
}
js2e y.json
** (UndefinedFunctionError) function nil.id/0 is undefined or private
    nil.id()
    (js2e) lib/printers/preamble_printer.ex:112: JS2E.Printers.PreamblePrinter.resolve_dependency/4
    (elixir) lib/enum.ex:1755: Enum."-reduce/3-lists^foldl/2-0-"/3
    (js2e) lib/printers/preamble_printer.ex:57: JS2E.Printers.PreamblePrinter.create_imports/3
    (js2e) lib/printers/preamble_printer.ex:35: JS2E.Printers.PreamblePrinter.print_preamble/3
    (js2e) lib/printer.ex:51: JS2E.Printer.print_schema/3
    (js2e) lib/printer.ex:33: anonymous fn/5 in JS2E.Printer.print_schemas/2
    (stdlib) lists.erl:1263: :lists.foldl/3

Add support for tuple typing for the 'items' property

"When this attribute value is an array of schemas and the instance value is an array, each position in the instance array MUST conform to the schema in the corresponding position for this array. This called tuple typing. When tuple typing is used, additional items are allowed, disallowed, or constrained by the "additionalItems" (Section 5.6) attribute using the same rules as "additionalProperties" (Section 5.4) for objects."

See https://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.5

Parse strings according to JSON schema patterns

See http://json-schema.org/latest/json-schema-validation.html#format

For example, if we have the node

"datum": {
  "required: ["createdDate"]
  "properties": {
    "createdDate": {
      "type": "string",
      "format": "date-time"
    }
  }
}

we want it to generate the type

type alias Datum =
      { createdDate: Date
      }

rather than

type alias Datum =
      { createdDate: String
      }

Possible decoder for date-time could be:

dateDecoder : Decoder Date
dateDecoder =
    Decode.string
        |> Decode.andThen
            (\dateStr ->
                case Date.fromIsoString dateStr of
                    Ok date ->
                        Decode.succeed date

                    Err err ->
                        Decode.fail err
            )

Possible encoder

encodeDate : Date -> Value
encodeDate date =
    date
        |> Date.toIsoString
        |> Encode.string

However, the implications for the parser has to be checked first.

Add union printer

Add module that takes an UnionType intermediate representation and prints out its corresponding Elm type and an Elm JSON Decoder.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.