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

Rescript frustration

$
0
0

I find results work best when they work on the same type – something like validating a string in a form.

For something like processing args in a CLI app, if you create some kind of context object to use instead of retaining values in a function scope, writing the functions you need gets much easier and then you end up with the nice “railway”

type errors =
  | DuplicatedArgumentError(array<string>)
  | UnrecognizedArguments(array<string>)

type mode = Production | Development

type options = {
  cache: bool,
  mode: mode,
}

type cmd = {
  argv: array<string>,
  options: options,
}

let defaultOptions = {
  cache: false,
  mode: Production,
}

let processArgs = args => {
  let argv = String.split(args, " ")
  Array.reverse(argv)
  {argv, options: defaultOptions}
}

let noDuplicateArgs = cmd =>
  switch duplicates(cmd.argv) {
  | [] => Ok(cmd)
  | duplicates => Error(DuplicateArgumentError(duplicates))
  }

let allArgsUsed = cmd =>
  switch cmd.argv {
  | [] => Ok(cmd)
  | items => Error(UnrecognizedArguments(items))
  }

let flag = (tag, f) => cmd => {
  argv: cmd.argv->Array.filter(x => x !== tag),
  flags: if cmd.argv->Array.includes(tag) {
    f(cmd.flags)
  } else {
    cmd.flags
  },
}

let getCacheOption = flag("--cached", flags => {...flags, cache: true})

let getModeOption = flag("--dev", flags => {...flags, mode: Development})

let parseArgs = args =>
  processArgs(args)
  ->noDuplicateArgs
  ->Result.map(getCacheOption)
  ->Result.map(getModeOption)
  ->Result.flatMap(allArgsUsed)
  ->Result.map(cmd => cmd.options)

Viewing all articles
Browse latest Browse all 2592

Trending Articles