diff --git a/lib/cocktail/builder/i_calendar.ex b/lib/cocktail/builder/i_calendar.ex index 90f309d..91a3488 100644 --- a/lib/cocktail/builder/i_calendar.ex +++ b/lib/cocktail/builder/i_calendar.ex @@ -38,7 +38,7 @@ defmodule Cocktail.Builder.ICalendar do def build(schedule) do rules = schedule.recurrence_rules - |> Enum.map(&build_rule/1) + |> Enum.map(&do_build_rule/1) times = schedule.recurrence_times @@ -56,6 +56,35 @@ defmodule Cocktail.Builder.ICalendar do |> Enum.join("\n") end + @doc ~S""" + Builds an iCalendar RRULE format string representation of a `t:Cocktail.Schedule.t/0` + + ## Examples + + iex> alias Cocktail.Schedule + ...> start_time = Timex.to_datetime(~N[2017-01-01 06:00:00], "America/Los_Angeles") + ...> schedule = Schedule.new(start_time) + ...> schedule = Schedule.add_recurrence_rule(schedule, :daily, interval: 2, hours: [10, 12]) + ...> build_rule(schedule) + "RRULE:FREQ=DAILY;INTERVAL=2;BYHOUR=10,12" + + iex> alias Cocktail.Schedule + ...> schedule = Schedule.new(~N[2017-01-01 06:00:00]) + ...> schedule = Schedule.add_recurrence_rule(schedule, :daily, until: ~N[2017-01-31 11:59:59]) + ...> build_rule(schedule) + "RRULE:FREQ=DAILY;UNTIL=20170131T115959" + + iex> alias Cocktail.Schedule + ...> schedule = Schedule.new(~N[2017-01-01 06:00:00]) + ...> schedule = Schedule.add_recurrence_rule(schedule, :daily, count: 3) + ...> build_rule(schedule) + "RRULE:FREQ=DAILY;COUNT=3" + """ + @spec build_rule(Schedule.t()) :: String.t() + def build_rule(schedule) do + Enum.map(schedule.recurrence_rules, &do_build_rule/1) |> Enum.join() + end + @spec build_time(Cocktail.time(), String.t()) :: String.t() defp build_time(%DateTime{} = time, prefix) do timezone = time.time_zone @@ -89,8 +118,8 @@ defmodule Cocktail.Builder.ICalendar do |> Timex.format!(@time_format_string <> "Z") end - @spec build_rule(Rule.t()) :: String.t() - defp build_rule(%Rule{validations: validations_map, until: until, count: count}) do + @spec do_build_rule(Rule.t()) :: String.t() + defp do_build_rule(%Rule{validations: validations_map, until: until, count: count}) do parts = for key <- [ :interval, diff --git a/lib/cocktail/schedule.ex b/lib/cocktail/schedule.ex index e94d849..8bcb0ab 100644 --- a/lib/cocktail/schedule.ex +++ b/lib/cocktail/schedule.ex @@ -228,6 +228,14 @@ defmodule Cocktail.Schedule do @spec to_i_calendar(t) :: String.t() def to_i_calendar(%__MODULE__{} = schedule), do: Builder.ICalendar.build(schedule) + @doc """ + Builds an iCalendar RRULE format string representation of a `t:Cocktail.Schedule.t/0`. + + see `Cocktail.Builder.ICalendar.build_rule/1` for details. + """ + @spec to_i_calendar_rrule(t) :: String.t() + def to_i_calendar_rrule(%__MODULE__{} = schedule), do: Builder.ICalendar.build_rule(schedule) + @doc """ Builds a human readable string representation of a `t:Cocktail.Schedule.t/0`. diff --git a/test/cocktail/builder/i_calendar_test.exs b/test/cocktail/builder/i_calendar_test.exs index c270d4e..26930f5 100644 --- a/test/cocktail/builder/i_calendar_test.exs +++ b/test/cocktail/builder/i_calendar_test.exs @@ -17,6 +17,17 @@ defmodule Cocktail.Builder.ICalendarTest do """ end + test "build rrule from schedule" do + schedule = + ~Y[2017-01-01 09:00:00 America/Los_Angeles] + |> Cocktail.schedule() + |> Schedule.add_recurrence_rule(:daily, until: ~Y[2017-01-31 09:00:00 America/Los_Angeles]) + + i_calendar_string = Schedule.to_i_calendar_rrule(schedule) + + assert i_calendar_string == "RRULE:FREQ=DAILY;UNTIL=20170131T170000Z" + end + test "build a schedule with timezone with until option" do schedule = ~Y[2017-01-01 09:00:00 America/Los_Angeles]