src/automata@rrule@parser.erl

-module(automata@rrule@parser).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/automata/rrule/parser.gleam").
-export([parse/1]).
-export_type([parse_error/0]).

-type parse_error() :: {invalid_rule, binary()} |
    {invalid_part_syntax, binary()} |
    {empty_part, binary()}.

-file("src/automata/rrule/parser.gleam", 22).
-spec strip_prefix(binary()) -> binary().
strip_prefix(Input) ->
    case gleam_stdlib:string_starts_with(
        string:uppercase(Input),
        <<"RRULE:"/utf8>>
    ) of
        true ->
            gleam@string:drop_start(Input, 6);

        false ->
            Input
    end.

-file("src/automata/rrule/parser.gleam", 40).
-spec collect_parts(list(binary()), list(automata@rrule@ast:raw_rule_part())) -> {ok,
        automata@rrule@ast:raw_r_rule()} |
    {error, parse_error()}.
collect_parts(Parts, Acc) ->
    case Parts of
        [] ->
            {ok, {raw_r_rule, lists:reverse(Acc)}};

        [Part | Rest] ->
            case gleam@string:split_once(gleam@string:trim(Part), <<"="/utf8>>) of
                {error, _} ->
                    {error, {invalid_part_syntax, Part}};

                {ok, {Name, Value}} ->
                    case (gleam@string:trim(Name) =:= <<""/utf8>>) orelse (gleam@string:trim(
                        Value
                    )
                    =:= <<""/utf8>>) of
                        true ->
                            {error, {empty_part, Part}};

                        false ->
                            collect_parts(
                                Rest,
                                [{raw_rule_part,
                                        string:uppercase(
                                            gleam@string:trim(Name)
                                        ),
                                        gleam@string:trim(Value)} |
                                    Acc]
                            )
                    end
            end
    end.

-file("src/automata/rrule/parser.gleam", 29).
-spec parse_parts(binary()) -> {ok, automata@rrule@ast:raw_r_rule()} |
    {error, parse_error()}.
parse_parts(Body) ->
    case Body of
        <<""/utf8>> ->
            {error, {invalid_rule, Body}};

        _ ->
            case gleam@list:any(
                gleam@string:split(Body, <<";"/utf8>>),
                fun gleam@string:is_empty/1
            ) of
                true ->
                    {error, {invalid_rule, Body}};

                false ->
                    collect_parts(gleam@string:split(Body, <<";"/utf8>>), [])
            end
    end.

-file("src/automata/rrule/parser.gleam", 13).
-spec parse(binary()) -> {ok, automata@rrule@ast:raw_r_rule()} |
    {error, parse_error()}.
parse(Input) ->
    Trimmed = gleam@string:trim(Input),
    case Trimmed of
        <<""/utf8>> ->
            {error, {invalid_rule, Input}};

        _ ->
            parse_parts(strip_prefix(Trimmed))
    end.