Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatic decoders for primitive types and records #23

Merged
merged 6 commits into from
Jun 6, 2018
Merged

Conversation

gdotdesign
Copy link
Member

@gdotdesign gdotdesign commented Jun 3, 2018

This PR adds automatic decoding to the language for primitive types (Array(a), Maybe(a), String, Number, Bool, Time) and records.

  • Parser
  • Compiler
  • Type Checker
  • Formatter
  • Update runtime
  • Tests

The problem

Converting any JavaScript object to a typed structure is difficult, currently Mint solves this the same way as Elm using decoders which can be very verbose:

record Author {
  bio : String,
  following : Bool,
  image : String,
  username : String
}

module Author {
  fun empty : Author {
    {
      bio = "",
      following = false,
      image = "",
      username = ""
    }
  }

  fun decode (object : Object) : Result(Object.Error, Author) {
    with Object.Decode {
      try {
        bio =
          field("bio", string, object)
          |> Result.withDefault("")

        image =
          field("image", string, object)

        following =
          field("following", boolean, object)

        username =
          field("username", string, object)

        Result.ok(
          {
            bio = bio,
            image = image,
            following = following,
            username = username
          })
      } catch Object.Error => error {
        Result.error(error)
      }
    }
  }
}

The use cases are to decode JSON Http requests or websocket messages.

The solution

The solution is to generate decoders for primitive types and records (which only contain primitive types and records), and adding a language construct to decode them.

The syntax looks like this:

decode expression as Type

where the expression must evaluate to Object and the type must be a primitive type or record. The return value is the same as would be for manual decoding Result(Object.Error, a)

Examples

Decoding string from an object:

decode input as String

Decoding a record:

record Entity {
  name: String,
  email: String,
  id: Number
}
...
decode input as Entity

Decoding a record where values come from different keys:

record Entity {
  name: String from "users_name",
  email: String from "users_email",
  id: Number
}
...
decode input as Entity

@gdotdesign gdotdesign changed the title [WIP] Automatic decoders for primitive types and records Automatic decoders for primitive types and records Jun 6, 2018
@gdotdesign gdotdesign merged commit 4d36872 into master Jun 6, 2018
@gdotdesign gdotdesign deleted the decode branch June 6, 2018 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1 participant