Skip to content

Commit

Permalink
refactor(flag parsing): remove duplicate error layering
Browse files Browse the repository at this point in the history
  • Loading branch information
TanklesXL committed Aug 14, 2023
1 parent bb6b692 commit 9381c1b
Showing 1 changed file with 32 additions and 28 deletions.
60 changes: 32 additions & 28 deletions src/glint/flag.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import snag.{Result, Snag}
import gleam/option.{None, Option, Some}
import gleam/function.{apply1}
import glint/flag/constraint.{Constraint}
import gleam

/// Flag inputs must start with this prefix
///
Expand Down Expand Up @@ -223,66 +224,69 @@ fn compute_flag(with input: String, given default: Value) -> Result(Value) {
}

// Parser functions
type Parser(a) =
fn(String) -> Result(a)

fn parse(internal: Internal(a), parser: Parser(a)) -> Parser(Internal(a)) {
type Parser(a, b) =
fn(String) -> gleam.Result(a, b)

type FlagParser(a) =
Parser(Internal(a), Snag)

fn parse(
internal: Internal(a),
kind: String,
parser: fn(String) -> gleam.Result(a, _),
) -> FlagParser(a) {
fn(value) {
use val <- result.try(parser(value))
use val <- result.try(
value
|> parser
|> result.replace_error(cannot_parse(value, kind)),
)
apply_constraints(val, internal.constraints)
|> result.replace(Internal(..internal, value: Some(val)))
}
}

fn parse_int(internal: Internal(Int)) -> Parser(Internal(Int)) {
use val <- parse(internal)
int.parse(val)
|> result.replace_error(cannot_parse(val, "int"))
fn parse_int(internal: Internal(Int)) -> FlagParser(Int) {
parse(internal, "int", int.parse)
}

fn parse_int_list(internal: Internal(List(Int))) -> Parser(Internal(List(Int))) {
use val <- parse(internal)
fn parse_int_list(internal: Internal(List(Int))) -> FlagParser(List(Int)) {
use val <- parse(internal, "int list")
val
|> string.split(",")
|> list.try_map(int.parse)
|> result.replace_error(cannot_parse(val, "int list"))
}

// fn xxx(key,val,constraints){apply_constraints(key, li, internal.constraints)|> }
fn parse_float(internal: Internal(Float)) -> Parser(Internal(Float)) {
use val <- parse(internal)
float.parse(val)
|> result.replace_error(cannot_parse(val, "float"))
fn parse_float(internal: Internal(Float)) -> FlagParser(Float) {
parse(internal, "float", float.parse)
}

fn parse_float_list(
internal: Internal(List(Float)),
) -> Parser(Internal(List(Float))) {
use val <- parse(internal)
fn parse_float_list(internal: Internal(List(Float))) -> FlagParser(List(Float)) {
use val <- parse(internal, "float list")
val
|> string.split(",")
|> list.try_map(float.parse)
|> result.replace_error(cannot_parse(val, "float list"))
}

fn parse_bool(internal: Internal(Bool)) -> Parser(Internal(Bool)) {
use val <- parse(internal)
fn parse_bool(internal: Internal(Bool)) -> FlagParser(Bool) {
use val <- parse(internal, "bool")
case string.lowercase(val) {
"true" | "t" -> Ok(True)
"false" | "f" -> Ok(False)
_ -> Error(cannot_parse(val, "bool"))
_ -> Error(Nil)
}
}

fn parse_string(internal: Internal(String)) -> Parser(Internal(String)) {
use val <- parse(internal)
Ok(val)
fn parse_string(internal: Internal(String)) -> FlagParser(String) {
parse(internal, "string", Ok)
}

fn parse_string_list(
internal: Internal(List(String)),
) -> Parser(Internal(List(String))) {
use val <- parse(internal)
) -> FlagParser(List(String)) {
use val <- parse(internal, "string list")
Ok(string.split(val, ","))
}

Expand Down

0 comments on commit 9381c1b

Please sign in to comment.