rescript-rtype

    1.0.2 • Public • Published

    Rtype

    Rtype is a super-simple way of decoding unknown json.

    Install

    npm i rescript-rtype
    

    Then add rescript-rtype as a dependency to bsconfig.json:

    
    "bs-dependencies": [
      "rescript-rtype"
    ]
    
    

    How it works

    Let's create a value that the type system is unaware of...

    %%raw(`const unknown = { greeting: "hello world" }`)
    @val external unknown: 'a = "unknown"
    

    Using Rtype (short for for Runtime Type), we can match an unknown value against a given type.

    We start by creating the type that we are looking for. We'll call this the decoder-type.

    type decoder = {
      greeting: string
    }
    

    We can now create the actual decoder using Rtype.
    Note how similar the decoder is to the actual decoder-type above.
    Also the decoder has the same type as the decoder-type.

    open RescriptRtype.Rtype // Opening Rtype gives access to the match function, as well as common decoders
    
    let decoder: decoder = {
      greeting: string
    }
    

    Simply pass the unknown value into match(decoder) and switch on the outcome.
    If the value matches the decoder, the decoder-type type is inferred.

    unknown
      -> match(decoder)
      -> outcome => switch outcome {
        | Some(value) => Js.log(value.greeting)
        | None => Js.log(":(")
        }
    

    Built in decoders

    We can build decoders with

    • string, int, float, bool, as well as
    • array(...) where ... can be any other decoder
    • dict(...) where ... can be any other decoder
    • as well as...
    • gt, gte, lt, lte => eg. gt(10.0) will match if it gets a float greater than 10
    • And Tuple and Record decoders can be built from all of the above.

    Eg. Matching a dictionary

    type compileTimeCat = { name: string }
    type compileTimeDictionary = Js.Dict.t<compileTimeCat>
    
    let runTimeTypeDictionary: compileTimeDictionary = dict({ name: string })
    
    // create a value unknown. The type system is unaware of the actual type.
    %%raw(`const unknown2 = { charlie: { name: "charlie" }}`)
    @val external unknown2: 'a = "unknown2"
    
    unknown2 -> match(runTimeTypeDictionary) -> v => switch v {
    | Some(thing) => switch Js.Dict.get(thing, "charlie") {
      | Some(cat) => Js.log(cat.name)
      | None => Js.log(":(")
      }
    | None => Js.log(">:(")
    }
    

    Eg. Matching a tuple

    type myTuple = (string, int, bool)
    
    let myTuple: myTuple = (string, int, bool)
    
    %%raw(`const unknown3 = ["hi", 7, true]`)
    @val external unknown3: 'a = "unknown3"
    
    unknown3
      -> match(myTuple)
      -> outcome => switch outcome {
        | Some(str, _, _) => Js.log(str ++ " there") // hi there
        | None => Js.log(":(")
        }
    

    Matching on literals

    "hello world"
      -> match("hello world")
      -> outcome => switch outcome {
        | Some(greeting) => Js.log(greeting) // hello world
        | None => Js.log(":(")
        }
    

    Install

    npm i rescript-rtype

    DownloadsWeekly Downloads

    2

    Version

    1.0.2

    License

    ISC

    Unpacked Size

    11.3 kB

    Total Files

    5

    Last publish

    Collaborators

    • attack-monkey