src/glipt@parser.erl

-module(glipt@parser).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/glipt/parser.gleam").
-export([strip_directives/1, format_directives/1, update_dep/3, expand_shorthand_version/1, parse/1]).
-export_type([dependency/0, script_meta/0]).

-type dependency() :: {dependency, binary(), binary()}.

-type script_meta() :: {script_meta,
        {ok, binary()} | {error, nil},
        list(binary()),
        list(dependency())}.

-file("src/glipt/parser.gleam", 75).
-spec parse_dep_body(binary()) -> {ok, dependency()} | {error, nil}.
parse_dep_body(Body) ->
    case gleam@string:trim(Body) of
        <<""/utf8>> ->
            {error, nil};

        Trimmed ->
            case gleam@string:split_once(Trimmed, <<" "/utf8>>) of
                {ok, {Name, Constraint}} ->
                    {ok,
                        {dependency,
                            gleam@string:trim(Name),
                            gleam@string:trim(Constraint)}};

                {error, nil} ->
                    {ok, {dependency, Trimmed, <<""/utf8>>}}
            end
    end.

-file("src/glipt/parser.gleam", 91).
-spec strip_directives(binary()) -> binary().
strip_directives(Source) ->
    Lines = gleam@string:split(Source, <<"\n"/utf8>>),
    Filtered = gleam@list:filter(
        Lines,
        fun(Line) ->
            not gleam_stdlib:string_starts_with(
                gleam@string:trim(Line),
                <<"//!"/utf8>>
            )
        end
    ),
    Result = gleam@string:join(Filtered, <<"\n"/utf8>>),
    Trimmed = gleam@string:trim(Result),
    case Trimmed of
        <<""/utf8>> ->
            <<""/utf8>>;

        S ->
            <<S/binary, "\n"/utf8>>
    end.

-file("src/glipt/parser.gleam", 105).
-spec format_directives(script_meta()) -> binary().
format_directives(Meta) ->
    Gleam_line = case erlang:element(2, Meta) of
        {ok, Constraint} ->
            [<<"//! gleam: "/utf8, Constraint/binary>>];

        {error, nil} ->
            []
    end,
    Project_lines = gleam@list:map(
        erlang:element(3, Meta),
        fun(P) -> <<"//! project: "/utf8, P/binary>> end
    ),
    Dep_lines = gleam@list:map(
        erlang:element(4, Meta),
        fun(Dep) -> case erlang:element(3, Dep) of
                <<""/utf8>> ->
                    <<"//! dep: "/utf8, (erlang:element(2, Dep))/binary>>;

                C ->
                    <<<<<<"//! dep: "/utf8, (erlang:element(2, Dep))/binary>>/binary,
                            " "/utf8>>/binary,
                        C/binary>>
            end end
    ),
    All_lines = begin
        _pipe = Gleam_line,
        _pipe@1 = lists:append(_pipe, Project_lines),
        lists:append(_pipe@1, Dep_lines)
    end,
    gleam@string:join(All_lines, <<"\n"/utf8>>).

-file("src/glipt/parser.gleam", 126).
-spec update_dep(script_meta(), binary(), binary()) -> script_meta().
update_dep(Meta, Name, Constraint) ->
    Existing = gleam@list:filter(
        erlang:element(4, Meta),
        fun(D) -> erlang:element(2, D) /= Name end
    ),
    New_deps = lists:append(Existing, [{dependency, Name, Constraint}]),
    {script_meta, erlang:element(2, Meta), erlang:element(3, Meta), New_deps}.

-file("src/glipt/parser.gleam", 137).
-spec expand_shorthand_version(binary()) -> binary().
expand_shorthand_version(Version) ->
    case gleam@string:split(Version, <<"."/utf8>>) of
        [Major, _, _] ->
            Next_major = case gleam_stdlib:parse_int(Major) of
                {ok, N} ->
                    erlang:integer_to_binary(N + 1);

                {error, nil} ->
                    <<"1"/utf8>>
            end,
            <<<<<<<<">= "/utf8, Version/binary>>/binary, " and < "/utf8>>/binary,
                    Next_major/binary>>/binary,
                ".0.0"/utf8>>;

        _ ->
            <<">= "/utf8, Version/binary>>
    end.

-file("src/glipt/parser.gleam", 150).
-spec drop_prefix(binary(), binary()) -> binary().
drop_prefix(S, Prefix) ->
    Prefix_len = string:length(Prefix),
    gleam@string:drop_start(S, Prefix_len).

-file("src/glipt/parser.gleam", 33).
-spec parse_gleam_directive(list(binary())) -> {ok, binary()} | {error, nil}.
parse_gleam_directive(Lines) ->
    gleam@list:find_map(
        Lines,
        fun(Line) ->
            Trimmed = gleam@string:trim(Line),
            Rest = gleam@string:trim(drop_prefix(Trimmed, <<"//!"/utf8>>)),
            case gleam_stdlib:string_starts_with(Rest, <<"gleam:"/utf8>>) of
                true ->
                    {ok,
                        gleam@string:trim(drop_prefix(Rest, <<"gleam:"/utf8>>))};

                false ->
                    {error, nil}
            end
        end
    ).

-file("src/glipt/parser.gleam", 44).
-spec parse_project_directives(list(binary())) -> list(binary()).
parse_project_directives(Lines) ->
    gleam@list:filter_map(
        Lines,
        fun(Line) ->
            Trimmed = gleam@string:trim(Line),
            Rest = gleam@string:trim(drop_prefix(Trimmed, <<"//!"/utf8>>)),
            case gleam_stdlib:string_starts_with(Rest, <<"project:"/utf8>>) of
                true ->
                    Path = gleam@string:trim(
                        drop_prefix(Rest, <<"project:"/utf8>>)
                    ),
                    case Path of
                        <<""/utf8>> ->
                            {error, nil};

                        P ->
                            {ok, P}
                    end;

                false ->
                    {error, nil}
            end
        end
    ).

-file("src/glipt/parser.gleam", 61).
-spec parse_dep_directives(list(binary())) -> list(dependency()).
parse_dep_directives(Lines) ->
    gleam@list:filter_map(
        Lines,
        fun(Line) ->
            Trimmed = gleam@string:trim(Line),
            Rest = gleam@string:trim(drop_prefix(Trimmed, <<"//!"/utf8>>)),
            case gleam_stdlib:string_starts_with(Rest, <<"dep:"/utf8>>) of
                true ->
                    Body = gleam@string:trim(drop_prefix(Rest, <<"dep:"/utf8>>)),
                    parse_dep_body(Body);

                false ->
                    {error, nil}
            end
        end
    ).

-file("src/glipt/parser.gleam", 17).
-spec parse(binary()) -> script_meta().
parse(Source) ->
    Lines = gleam@string:split(Source, <<"\n"/utf8>>),
    Directive_lines = gleam@list:filter(
        Lines,
        fun(Line) ->
            gleam_stdlib:string_starts_with(
                gleam@string:trim(Line),
                <<"//!"/utf8>>
            )
        end
    ),
    Gleam_constraint = parse_gleam_directive(Directive_lines),
    Project_paths = parse_project_directives(Directive_lines),
    Deps = parse_dep_directives(Directive_lines),
    {script_meta, Gleam_constraint, Project_paths, Deps}.