-module(calendar@date_range). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/calendar/date_range.gleam"). -export([new_with_step/3, new/2, size/1, member/2, to_list/1]). -export_type([date_range/0, date_range_error/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 date_range() :: {date_range, calendar@date:date(), calendar@date:date(), integer()}. -type date_range_error() :: invalid_range. -file("src/calendar/date_range.gleam", 19). ?DOC(" Creates a date range with a custom step.\n"). -spec new_with_step(calendar@date:date(), calendar@date:date(), integer()) -> {ok, date_range()} | {error, date_range_error()}. new_with_step(First, Last, Step) -> case Step =:= 0 of true -> {error, invalid_range}; false -> case erlang:element(5, First) =:= erlang:element(5, Last) of false -> {error, invalid_range}; true -> {ok, {date_range, First, Last, Step}} end end. -file("src/calendar/date_range.gleam", 14). ?DOC(" Creates a date range with step 1.\n"). -spec new(calendar@date:date(), calendar@date:date()) -> {ok, date_range()} | {error, date_range_error()}. new(First, Last) -> new_with_step(First, Last, 1). -file("src/calendar/date_range.gleam", 44). ?DOC(" Returns the number of dates in the range.\n"). -spec size(date_range()) -> integer(). size(Range) -> First_days = calendar@date:to_gregorian_days(erlang:element(2, Range)), Last_days = calendar@date:to_gregorian_days(erlang:element(3, Range)), Diff = Last_days - First_days, case (erlang:element(4, Range) > 0) andalso (Diff >= 0) of true -> (case erlang:element(4, Range) of 0 -> 0; Gleam@denominator -> Diff div Gleam@denominator end) + 1; false -> case (erlang:element(4, Range) < 0) andalso (Diff =< 0) of true -> (case (- erlang:element(4, Range)) of 0 -> 0; Gleam@denominator@1 -> (- Diff) div Gleam@denominator@1 end) + 1; false -> 0 end end. -file("src/calendar/date_range.gleam", 59). ?DOC(" Checks if a date is in the range.\n"). -spec member(date_range(), calendar@date:date()) -> boolean(). member(Range, D) -> D_days = calendar@date:to_gregorian_days(D), First_days = calendar@date:to_gregorian_days(erlang:element(2, Range)), Last_days = calendar@date:to_gregorian_days(erlang:element(3, Range)), Diff = D_days - First_days, case erlang:element(4, Range) > 0 of true -> ((D_days >= First_days) andalso (D_days =< Last_days)) andalso ((case erlang:element( 4, Range ) of 0 -> 0; Gleam@denominator -> Diff rem Gleam@denominator end) =:= 0); false -> ((D_days =< First_days) andalso (D_days >= Last_days)) andalso ((case erlang:element( 4, Range ) of 0 -> 0; Gleam@denominator@1 -> Diff rem Gleam@denominator@1 end) =:= 0) end. -file("src/calendar/date_range.gleam", 72). -spec date_range_to_list( calendar@date:date(), integer(), integer(), integer(), list(calendar@date:date()) ) -> list(calendar@date:date()). date_range_to_list(Current, Current_days, Target_days, Step, Acc) -> case ((Step > 0) andalso (Current_days > Target_days)) orelse ((Step < 0) andalso (Current_days < Target_days)) of true -> Acc; false -> Next = calendar@date:add(Current, Step), date_range_to_list( Next, Current_days + Step, Target_days, Step, [Current | Acc] ) end. -file("src/calendar/date_range.gleam", 36). ?DOC(" Converts a date range to a list of dates.\n"). -spec to_list(date_range()) -> list(calendar@date:date()). to_list(Range) -> First_days = calendar@date:to_gregorian_days(erlang:element(2, Range)), Last_days = calendar@date:to_gregorian_days(erlang:element(3, Range)), _pipe = date_range_to_list( erlang:element(2, Range), First_days, Last_days, erlang:element(4, Range), [] ), lists:reverse(_pipe).