Current section
Files
Jump to
Current section
Files
src/diced.gleam
import gleam/int
import gleam/result
import gleam/string
pub type RollVariant {
Advantage
Disadvantage
Normal
}
pub type Dice {
Dice(amount: Int, value: Int, variant: RollVariant)
}
pub type DiceError {
InvalidAmount
InvalidString
InvalidValue
}
pub fn dice_from_string(string string: String) -> Result(Dice, DiceError) {
use #(amount_string, value_string) <- result.try(split_dice(string))
use amount <- result.try(parse_amount(amount_string))
use #(value, variant) <- result.try(parse_value(value_string))
Ok(Dice(amount:, value:, variant:))
}
fn parse_amount(amount: String) -> Result(Int, DiceError) {
case amount {
"" -> Ok(1)
_ -> amount |> int.parse |> result.replace_error(InvalidAmount)
}
}
fn parse_value(value: String) -> Result(#(Int, RollVariant), DiceError) {
let variant = Normal
let #(value, variant) = case value |> string.ends_with("kh") {
True -> #(value |> string.drop_end(2), Advantage)
False -> #(value, variant)
}
let #(value, variant) = case value |> string.ends_with("kl") {
True -> #(value |> string.drop_end(2), Disadvantage)
False -> #(value, variant)
}
case value |> int.parse {
Ok(num) -> Ok(#(num, variant))
_ -> Error(InvalidValue)
}
}
fn split_dice(string: String) -> Result(#(String, String), DiceError) {
case string |> int.parse {
Ok(_) -> Ok(#(string, string))
_ -> string |> string.split_once("d") |> result.replace_error(InvalidString)
}
}