Quantcast
Channel: ReScript Forum - Latest posts
Viewing all articles
Browse latest Browse all 2592

Need help with binding to a function with a complex type

$
0
0

I overcomplicated things a bit by using a generalized abstract data type (or GADT) for parameterTypeKeys and objects for the parsing result, objects being the structural equivalent of records in ReScript. Don’t worry, this kind of type shenanigans is quite uncommon in ReScript and is just needed here because of the very dynamic nature of the javascript function you’re binding to.

Here is a simplified version that doesn’t require GADTs and that allows both objects and records for the result:

@tag("success")
type parseResult<'params> =
  | @as(true) Success({parameters: 'params})
  | @as(false) Failure({reply: string})

module S: {
  type t<'a>
  type helper = {string: string, float: float, int: int, boolean: bool}
  let object: (helper => 'a) => t<'a>
} = {
  type parameterDefinition = {
    name: string,
    @as("type") type_: string,
  }
  type t<'a> = array<parameterDefinition>
  type helper = {string: string, float: float, int: int, boolean: bool}
  let string = "string"
  external unsafeStringToFloat: string => float = "%identity"
  let float = "number"->unsafeStringToFloat
  external unsafeStringToInt: string => int = "%identity"
  let int = "number"->unsafeStringToInt
  external unsafeStringToBool: string => bool = "%identity"
  let boolean = "boolean"->unsafeStringToBool

  external schemaToDictString: 'a => dict<string> = "%identity"

  let object = f => {
    f({string, float, int, boolean})
    ->schemaToDictString
    ->Dict.toArray
    ->Array.map(((name, type_)) => {name, type_})
  }
}

@scope("utils") @val
external parseParametersFromArguments: (
  S.t<'a>,
  array<string>,
) => parseResult<'a> = "parseParametersFromArguments"

You use it like that:

type myRecord = {
  index: int,
  foo: string,
}

let parseMyRecord = args =>
  parseParametersFromArguments(
    S.object(s => {
      index: s.int,
      foo: s.string,
    }),
    args,
  )

switch parseMyRecord(["index:1", "foo:bar"]) {
| Success({parameters: {index: 1}}) => Console.log("great success!")
| _ => Console.log("oh nooo!")
}

Playground link


Viewing all articles
Browse latest Browse all 2592

Trending Articles