src/gleedoc@extract.erl

-module(gleedoc@extract).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gleedoc/extract.gleam").
-export([doc_blocks_from_file/1]).
-export_type([doc_block/0]).

-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.

-type doc_block() :: {doc_block,
        list(binary()),
        gleam@option:option(binary()),
        binary(),
        integer()}.

-file("src/gleedoc/extract.gleam", 151).
-spec try_extract_const_name(binary()) -> {ok, binary()} | {error, nil}.
try_extract_const_name(Line) ->
    Line@1 = begin
        _pipe = gleam@string:split_once(Line, <<"pub "/utf8>>),
        _pipe@1 = gleam@result:map(
            _pipe,
            fun(Pair) -> erlang:element(2, Pair) end
        ),
        gleam@result:unwrap(_pipe@1, Line)
    end,
    gleam@result:'try'(
        gleam@string:split_once(Line@1, <<"const "/utf8>>),
        fun(Rest) ->
            _pipe@3 = gleam@string:split_once(
                begin
                    _pipe@2 = erlang:element(2, Rest),
                    gleam@string:trim_start(_pipe@2)
                end,
                <<" "/utf8>>
            ),
            _pipe@4 = gleam@result:map(
                _pipe@3,
                fun(Pair@1) -> gleam@string:trim(erlang:element(1, Pair@1)) end
            ),
            _pipe@5 = gleam@result:unwrap(
                _pipe@4,
                gleam@string:trim(erlang:element(2, Rest))
            ),
            {ok, _pipe@5}
        end
    ).

-file("src/gleedoc/extract.gleam", 128).
-spec try_extract_type_name(binary()) -> {ok, binary()} | {error, nil}.
try_extract_type_name(Line) ->
    Line@1 = begin
        _pipe = gleam@string:split_once(Line, <<"pub "/utf8>>),
        _pipe@1 = gleam@result:map(
            _pipe,
            fun(Pair) -> erlang:element(2, Pair) end
        ),
        gleam@result:unwrap(_pipe@1, Line)
    end,
    gleam@result:'try'(
        gleam@string:split_once(Line@1, <<"type "/utf8>>),
        fun(Rest) ->
            Rest@1 = begin
                _pipe@3 = gleam@string:split_once(
                    begin
                        _pipe@2 = erlang:element(2, Rest),
                        gleam@string:trim_start(_pipe@2)
                    end,
                    <<"opaque "/utf8>>
                ),
                _pipe@5 = gleam@result:map(
                    _pipe@3,
                    fun(Pair@1) -> _pipe@4 = erlang:element(2, Pair@1),
                        gleam@string:trim_start(_pipe@4) end
                ),
                gleam@result:unwrap(
                    _pipe@5,
                    begin
                        _pipe@6 = erlang:element(2, Rest),
                        gleam@string:trim_start(_pipe@6)
                    end
                )
            end,
            _pipe@7 = gleam@string:split_once(Rest@1, <<" "/utf8>>),
            _pipe@8 = gleam@result:'or'(
                _pipe@7,
                gleam@string:split_once(Rest@1, <<"{"/utf8>>)
            ),
            _pipe@9 = gleam@result:map(
                _pipe@8,
                fun(Pair@2) -> gleam@string:trim(erlang:element(1, Pair@2)) end
            ),
            _pipe@10 = gleam@result:unwrap(_pipe@9, gleam@string:trim(Rest@1)),
            {ok, _pipe@10}
        end
    ).

-file("src/gleedoc/extract.gleam", 113).
-spec try_extract_function_name(binary()) -> {ok, binary()} | {error, nil}.
try_extract_function_name(Line) ->
    Line@1 = begin
        _pipe = gleam@string:split_once(Line, <<"pub "/utf8>>),
        _pipe@1 = gleam@result:map(
            _pipe,
            fun(Pair) -> erlang:element(2, Pair) end
        ),
        gleam@result:unwrap(_pipe@1, Line)
    end,
    gleam@result:'try'(
        gleam@string:split_once(Line@1, <<"fn "/utf8>>),
        fun(Rest) -> _pipe@2 = erlang:element(2, Rest),
            _pipe@3 = gleam@string:trim_start(_pipe@2),
            _pipe@4 = gleam@string:split_once(_pipe@3, <<"("/utf8>>),
            gleam@result:map(
                _pipe@4,
                fun(Pair@1) -> gleam@string:trim(erlang:element(1, Pair@1)) end
            ) end
    ).

-file("src/gleedoc/extract.gleam", 103).
?DOC(" Try to extract a definition name from a source line.\n").
-spec extract_definition_name(binary()) -> gleam@option:option(binary()).
extract_definition_name(Line) ->
    Trimmed = gleam@string:trim_start(Line),
    _pipe = try_extract_function_name(Trimmed),
    _pipe@1 = gleam@result:'or'(_pipe, try_extract_type_name(Trimmed)),
    _pipe@2 = gleam@result:'or'(_pipe@1, try_extract_const_name(Trimmed)),
    gleam@option:from_result(_pipe@2).

-file("src/gleedoc/extract.gleam", 45).
-spec extract_blocks(list({integer(), binary()}), binary()) -> list(doc_block()).
extract_blocks(Lines, File) ->
    {Processed_doc_blocks, _} = gleam@list:fold(
        Lines,
        {[], []},
        fun(State, Item) ->
            {Processed_docs, Current_doc} = State,
            {Line_no, Line} = Item,
            Trimmed = gleam@string:trim_start(Line),
            case gleam_stdlib:string_starts_with(Trimmed, <<"///"/utf8>>) of
                true ->
                    Doc_line = begin
                        _pipe = Trimmed,
                        _pipe@1 = gleam@string:drop_start(_pipe, 3),
                        gleam@string:trim_start(_pipe@1)
                    end,
                    {Processed_docs, [{Line_no, Doc_line} | Current_doc]};

                false ->
                    case Current_doc of
                        [] ->
                            State;

                        _ ->
                            case gleam@string:trim(Line) =:= <<""/utf8>> of
                                true ->
                                    State;

                                false ->
                                    Target = extract_definition_name(Line),
                                    Start_line = begin
                                        _pipe@2 = Current_doc,
                                        _pipe@3 = gleam@list:last(_pipe@2),
                                        _pipe@4 = gleam@result:map(
                                            _pipe@3,
                                            fun(Pair) ->
                                                erlang:element(1, Pair)
                                            end
                                        ),
                                        gleam@result:unwrap(_pipe@4, Line_no)
                                    end,
                                    Doc_lines = begin
                                        _pipe@5 = Current_doc,
                                        _pipe@6 = lists:reverse(_pipe@5),
                                        gleam@list:map(
                                            _pipe@6,
                                            fun(Pair@1) ->
                                                erlang:element(2, Pair@1)
                                            end
                                        )
                                    end,
                                    New_doc = {doc_block,
                                        Doc_lines,
                                        Target,
                                        File,
                                        Start_line},
                                    {[New_doc | Processed_docs], []}
                            end
                    end
            end
        end
    ),
    lists:reverse(Processed_doc_blocks).

-file("src/gleedoc/extract.gleam", 23).
?DOC(" Extract all doc comment blocks from a Gleam source file.\n").
-spec doc_blocks_from_file(binary()) -> {ok, list(doc_block())} |
    {error, snag:snag()}.
doc_blocks_from_file(File_path) ->
    gleam@result:'try'(
        begin
            _pipe = File_path,
            _pipe@1 = simplifile:read(_pipe),
            gleam@result:map_error(
                _pipe@1,
                fun(Err) ->
                    snag:new(
                        <<<<<<"Failed to read file: "/utf8, File_path/binary>>/binary,
                                " - "/utf8>>/binary,
                            (gleam@string:inspect(Err))/binary>>
                    )
                end
            )
        end,
        fun(Content) ->
            Doc_blocks = begin
                _pipe@2 = Content,
                _pipe@3 = gleam@string:split(_pipe@2, <<"\n"/utf8>>),
                _pipe@4 = gleam@list:index_map(
                    _pipe@3,
                    fun(Line, Index) -> {Index + 1, Line} end
                ),
                extract_blocks(_pipe@4, File_path)
            end,
            {ok, Doc_blocks}
        end
    ).