[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/codegod100/basic-cli/main/platform/EnvDecoding.roc [Back]  [Original]

module [
    EnvFormat,
    format,
]

EnvFormat := {} implements [
        DecoderFormatting {
            u8: env_u8,
            u16: env_u16,
            u32: env_u32,
            u64: env_u64,
            u128: env_u128,
            i8: env_i8,
            i16: env_i16,
            i32: env_i32,
            i64: env_i64,
            i128: env_i128,
            f32: env_f32,
            f64: env_f64,
            dec: env_dec,
            bool: env_bool,
            string: env_string,
            list: env_list,
            record: env_record,
            tuple: env_tuple,
        },
    ]

format : {} -> EnvFormat
format = |{}| @EnvFormat({})

decode_bytes_to_num = |bytes, transformer|
    when Str.from_utf8(bytes) is
        Ok(s) ->
            when transformer(s) is
                Ok(n) -> { result: Ok(n), rest: [] }
                Err(_) -> { result: Err(TooShort), rest: bytes }

        Err(_) -> { result: Err(TooShort), rest: bytes }

env_u8 = Decode.custom(|bytes, @EnvFormat({})| decode_bytes_to_num(bytes, Str.to_u8))
env_u16 = Decode.custom(|bytes, @EnvFormat({})| decode_bytes_to_num(bytes, Str.to_u16))
env_u32 = Decode.custom(|bytes, @EnvFormat({})| decode_bytes_to_num(bytes, Str.to_u32))
env_u64 = Decode.custom(|bytes, @EnvFormat({})| decode_bytes_to_num(bytes, Str.to_u64))
env_u128 = Decode.custom(|bytes, @EnvFormat({})| decode_bytes_to_num(bytes, Str.to_u128))
env_i8 = Decode.custom(|bytes, @EnvFormat({})| decode_bytes_to_num(bytes, Str.to_i8))
env_i16 = Decode.custom(|bytes, @EnvFormat({})| decode_bytes_to_num(bytes, Str.to_i16))
env_i32 = Decode.custom(|bytes, @EnvFormat({})| decode_bytes_to_num(bytes, Str.to_i32))
env_i64 = Decode.custom(|bytes, @EnvFormat({})| decode_bytes_to_num(bytes, Str.to_i64))
env_i128 = Decode.custom(|bytes, @EnvFormat({})| decode_bytes_to_num(bytes, Str.to_i128))
env_f32 = Decode.custom(|bytes, @EnvFormat({})| decode_bytes_to_num(bytes, Str.to_f32))
env_f64 = Decode.custom(|bytes, @EnvFormat({})| decode_bytes_to_num(bytes, Str.to_f64))
env_dec = Decode.custom(|bytes, @EnvFormat({})| decode_bytes_to_num(bytes, Str.to_dec))

env_bool = Decode.custom(
    |bytes, @EnvFormat({})|
        when Str.from_utf8(bytes) is
            Ok("true") -> { result: Ok(Bool.true), rest: [] }
            Ok("false") -> { result: Ok(Bool.false), rest: [] }
            _ -> { result: Err(TooShort), rest: bytes },
)

env_string = Decode.custom(
    |bytes, @EnvFormat({})|
        when Str.from_utf8(bytes) is
            Ok(s) -> { result: Ok(s), rest: [] }
            Err(_) -> { result: Err(TooShort), rest: bytes },
)

env_list = |decode_elem|
    Decode.custom(
        |bytes, @EnvFormat({})|
            # Per our supported methods of decoding, this is either a list of strings or
            # a list of numbers; in either case, the list of bytes must be Utf-8
            # decodable. So just parse it as a list of strings and pass each chunk to
            # the element decoder. By construction, our element decoders expect to parse
            # a whole list of bytes anyway.
            decode_elems = |all_bytes, accum|
                { to_parse, remainder } =
                    when List.split_first(all_bytes, Num.to_u8(',')) is
                        Ok({ before, after }) ->
                            { to_parse: before, remainder: Some(after) }

                        Err(NotFound) ->
                            { to_parse: all_bytes, remainder: None }

                when Decode.decode_with(to_parse, decode_elem, @EnvFormat({})) is
                    { result, rest } ->
                        when result is
                            Ok(val) ->
                                when remainder is
                                    Some(rest_bytes) -> decode_elems(rest_bytes, List.append(accum, val))
                                    None -> Done(List.append(accum, val))

                            Err(e) -> Errored(e, rest)

            when decode_elems(bytes, []) is
                Errored(e, rest) -> { result: Err(e), rest }
                Done(vals) ->
                    { result: Ok(vals), rest: [] },
    )

# TODO: we must currently annotate the arrows here so that the lambda sets are
# exercised, and the solver can find an ambient lambda set for the
# specialization.
env_record : _, (_, _ -> [Keep (Decoder _ _), Skip]), (_, _ -> _) -> Decoder _ _
env_record = |_initial_state, _step_field, _finalizer|
    Decode.custom(
        |bytes, @EnvFormat({})|
            { result: Err(TooShort), rest: bytes },
    )

# TODO: we must currently annotate the arrows here so that the lambda sets are
# exercised, and the solver can find an ambient lambda set for the
# specialization.
env_tuple : _, (_, _ -> [Next (Decoder _ _), TooLong]), (_ -> _) -> Decoder _ _
env_tuple = |_initial_state, _step_elem, _finalizer|
    Decode.custom(
        |bytes, @EnvFormat({})|
            { result: Err(TooShort), rest: bytes },
    )

Web Proxy Viewer  |  New URL  |  Original Page