Skip to main content

src/spruce@line.erl

-module(spruce@line).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/spruce/line.gleam").
-export([new/1, timestamp/2, scope/2, severity/2, severity_formatter/2, details/2, render/2]).
-export_type([line/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.

?MODULEDOC(
    " Compact single-line message composition.\n"
    "\n"
    " A `Line` wraps a main message with an optional timestamp, severity, scope,\n"
    " and key-value details, rendered to one styled line via `render`. Build one\n"
    " with `new` and the combinators in this module.\n"
).

-opaque line() :: {line,
        binary(),
        gleam@option:option(binary()),
        gleam@option:option(binary()),
        gleam@option:option(spruce@severity:severity()),
        spruce@severity:formatter(),
        gleam@option:option(spruce@details:details())}.

-file("src/spruce/line.gleam", 29).
?DOC(" Start a compact line with the main message text.\n").
-spec new(binary()) -> line().
new(Text) ->
    {line, Text, none, none, none, spruce@severity:label(), none}.

-file("src/spruce/line.gleam", 41).
?DOC(" Add a timestamp prefix.\n").
-spec timestamp(line(), binary()) -> line().
timestamp(Line, Timestamp) ->
    {line,
        erlang:element(2, Line),
        {some, Timestamp},
        erlang:element(4, Line),
        erlang:element(5, Line),
        erlang:element(6, Line),
        erlang:element(7, Line)}.

-file("src/spruce/line.gleam", 46).
?DOC(" Add a dim `[scope]` prefix.\n").
-spec scope(line(), binary()) -> line().
scope(Line, Scope) ->
    {line,
        erlang:element(2, Line),
        erlang:element(3, Line),
        {some, Scope},
        erlang:element(5, Line),
        erlang:element(6, Line),
        erlang:element(7, Line)}.

-file("src/spruce/line.gleam", 51).
?DOC(" Add a generic severity/status prefix.\n").
-spec severity(line(), spruce@severity:severity()) -> line().
severity(Line, Severity) ->
    {line,
        erlang:element(2, Line),
        erlang:element(3, Line),
        erlang:element(4, Line),
        {some, Severity},
        erlang:element(6, Line),
        erlang:element(7, Line)}.

-file("src/spruce/line.gleam", 56).
?DOC(" Override the severity formatter.\n").
-spec severity_formatter(line(), spruce@severity:formatter()) -> line().
severity_formatter(Line, Formatter) ->
    {line,
        erlang:element(2, Line),
        erlang:element(3, Line),
        erlang:element(4, Line),
        erlang:element(5, Line),
        Formatter,
        erlang:element(7, Line)}.

-file("src/spruce/line.gleam", 64).
?DOC(" Add key-value details after the main text.\n").
-spec details(line(), spruce@details:details()) -> line().
details(Line, Details) ->
    {line,
        erlang:element(2, Line),
        erlang:element(3, Line),
        erlang:element(4, Line),
        erlang:element(5, Line),
        erlang:element(6, Line),
        {some, Details}}.

-file("src/spruce/line.gleam", 122).
-spec render_details_part(
    spruce:spruce(),
    gleam@option:option(spruce@details:details())
) -> binary().
render_details_part(Sp, Details_option) ->
    case Details_option of
        none ->
            <<""/utf8>>;

        {some, Details} ->
            case spruce@details:render(Sp, Details) of
                <<""/utf8>> ->
                    <<""/utf8>>;

                Rendered ->
                    <<" "/utf8,
                        (spruce@style:render(
                            Sp,
                            begin
                                _pipe = spruce@style:new(),
                                spruce@style:dim(_pipe)
                            end,
                            Rendered
                        ))/binary>>
            end
    end.

-file("src/spruce/line.gleam", 102).
-spec render_scope(spruce:spruce(), gleam@option:option(binary())) -> gleam@option:option(binary()).
render_scope(Sp, Scope) ->
    case Scope of
        none ->
            none;

        {some, Scope@1} ->
            {some,
                spruce@style:render(
                    Sp,
                    begin
                        _pipe = spruce@style:new(),
                        spruce@style:dim(_pipe)
                    end,
                    <<<<"["/utf8, Scope@1/binary>>/binary, "]"/utf8>>
                )}
    end.

-file("src/spruce/line.gleam", 86).
-spec maybe_append(list(binary()), gleam@option:option(binary())) -> list(binary()).
maybe_append(Items, Item) ->
    case Item of
        none ->
            Items;

        {some, <<""/utf8>>} ->
            Items;

        {some, Item@1} ->
            [Item@1 | Items]
    end.

-file("src/spruce/line.gleam", 110).
-spec render_severity(
    spruce:spruce(),
    gleam@option:option(spruce@severity:severity()),
    spruce@severity:formatter()
) -> gleam@option:option(binary()).
render_severity(Sp, Severity_value, Formatter) ->
    case Severity_value of
        none ->
            none;

        {some, Severity_value@1} ->
            {some,
                spruce@severity:render_padded(Sp, Formatter, Severity_value@1)}
    end.

-file("src/spruce/line.gleam", 94).
-spec render_timestamp(spruce:spruce(), gleam@option:option(binary())) -> gleam@option:option(binary()).
render_timestamp(Sp, Timestamp) ->
    case Timestamp of
        none ->
            none;

        {some, Timestamp@1} ->
            {some,
                spruce@style:render(
                    Sp,
                    begin
                        _pipe = spruce@style:new(),
                        spruce@style:dim(_pipe)
                    end,
                    Timestamp@1
                )}
    end.

-file("src/spruce/line.gleam", 69).
?DOC(" Render the compact line.\n").
-spec render(spruce:spruce(), line()) -> binary().
render(Sp, Line) ->
    Prefix = spruce@internal@layout:indent_prefix(Sp),
    Prefix_parts = begin
        _pipe = [],
        _pipe@1 = maybe_append(
            _pipe,
            render_timestamp(Sp, erlang:element(3, Line))
        ),
        _pipe@2 = maybe_append(
            _pipe@1,
            render_severity(
                Sp,
                erlang:element(5, Line),
                erlang:element(6, Line)
            )
        ),
        _pipe@3 = maybe_append(
            _pipe@2,
            render_scope(Sp, erlang:element(4, Line))
        ),
        lists:reverse(_pipe@3)
    end,
    Head = case Prefix_parts of
        [] ->
            erlang:element(2, Line);

        _ ->
            <<<<(gleam@string:join(Prefix_parts, <<" "/utf8>>))/binary,
                    " "/utf8>>/binary,
                (erlang:element(2, Line))/binary>>
    end,
    <<<<Prefix/binary, Head/binary>>/binary,
        (render_details_part(Sp, erlang:element(7, Line)))/binary>>.