Current section

Files

Jump to
birl src birl@interval.erl
Raw

src/birl@interval.erl

-module(birl@interval).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([from_start_and_end/2, from_start_and_duration/2, shift/2, scale_up/2, scale_down/2, includes/2, contains/2, intersection/2, get_bounds/1]).
-export_type([interval/0]).
-opaque interval() :: {interval, birl:time(), birl:time()}.
-spec from_start_and_end(birl:time(), birl:time()) -> {ok, interval()} |
{error, nil}.
from_start_and_end(Start, End) ->
case birl:compare(Start, End) of
eq ->
{error, nil};
lt ->
{ok, {interval, Start, End}};
gt ->
{ok, {interval, End, Start}}
end.
-spec from_start_and_duration(birl:time(), birl@duration:duration()) -> {ok,
interval()} |
{error, nil}.
from_start_and_duration(Start, Duration) ->
from_start_and_end(Start, birl:add(Start, Duration)).
-spec shift(interval(), birl@duration:duration()) -> interval().
shift(Interval, Duration) ->
case Interval of
{interval, Start, End} ->
{interval, birl:add(Start, Duration), birl:add(End, Duration)}
end.
-spec scale_up(interval(), integer()) -> interval().
scale_up(Interval, Factor) ->
case Interval of
{interval, Start, End} ->
_assert_subject = begin
_pipe = birl:difference(End, Start),
_pipe@1 = birl@duration:scale_up(_pipe, Factor),
from_start_and_duration(Start, _pipe@1)
end,
{ok, Interval@1} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/interval"/utf8>>,
function => <<"scale_up"/utf8>>,
line => 33})
end,
Interval@1
end.
-spec scale_down(interval(), integer()) -> interval().
scale_down(Interval, Factor) ->
case Interval of
{interval, Start, End} ->
_assert_subject = begin
_pipe = birl:difference(End, Start),
_pipe@1 = birl@duration:scale_down(_pipe, Factor),
from_start_and_duration(Start, _pipe@1)
end,
{ok, Interval@1} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/interval"/utf8>>,
function => <<"scale_down"/utf8>>,
line => 45})
end,
Interval@1
end.
-spec includes(interval(), birl:time()) -> boolean().
includes(Interval, Time) ->
case Interval of
{interval, Start, End} ->
gleam@list:contains([eq, lt], birl:compare(Start, Time)) andalso gleam@list:contains(
[eq, gt],
birl:compare(End, Time)
)
end.
-spec contains(interval(), interval()) -> boolean().
contains(A, B) ->
case B of
{interval, Start, End} ->
includes(A, Start) andalso includes(A, End)
end.
-spec intersection(interval(), interval()) -> gleam@option:option(interval()).
intersection(A, B) ->
case {contains(A, B), contains(B, A)} of
{true, false} ->
{some, B};
{false, true} ->
{some, A};
{_, _} ->
{interval, A_start, A_end} = A,
{interval, B_start, B_end} = B,
case {includes(A, B_start), includes(B, A_start)} of
{true, false} ->
{some, {interval, B_start, A_end}};
{false, true} ->
{some, {interval, A_start, B_end}};
{_, _} ->
none
end
end.
-spec get_bounds(interval()) -> {birl:time(), birl:time()}.
get_bounds(Interval) ->
case Interval of
{interval, Start, End} ->
{Start, End}
end.