Flicker.Facet.Preset (Flicker v0.1.0)

Copy Markdown View Source

A semantic date preset — last-30-days, this-quarter, all-time (Spec 018).

A preset is the question a user is asking ("the last 30 days"), not the answer ("Jun 29 to Jul 28"). That distinction is load-bearing: presets serialise back to their :token, so a query saved today still means "the last 30 days" when reopened next week, rather than freezing to this week's dates (ADR-011).

Fields

  • :id — the canonical atom (:last_30_days), carried on Flicker.Facet.Range's :preset.
  • :token — the typed/serialised form ("last-30-days").
  • :label — the fallback display string. With localize present, Flicker.Facet.Format prefers CLDR's own wording (ADR-013).
  • :resolve — fun(reference_date, first_day_of_week) :: {from, to}, or nil for a built-in, which resolve/3 computes from :id instead.

Why built-ins carry no function

A %Flicker.Facet{} holding presets that each closed over an anonymous function could not be a module attribute — @facets [...] fails, because anonymous functions can't be escaped into one. Since a hand-built facet registry as a module attribute is a perfectly reasonable thing to write, the built-in table stores plain data and resolve/3 dispatches on :id. A host defining its own preset may still pass a :resolve function; that preset just can't live in a module attribute.

Resolution is contextual, and takes its context as arguments

:resolve never calls Date.utc_today/0 and never reads a locale: both the reference date and the week's first day arrive as arguments. That keeps every preset a pure function — the whole table is testable at a fixed date — and it is what lets this-week mean different days in en-US (Sunday start) and en-AU (Monday start) without the preset knowing anything about locales.

first_day_of_week is 1 for Monday through 7 for Sunday, matching Date.day_of_week/1. Without localize, callers pass 1 (Monday), which is the ISO 8601 default.

Summary

Types

A day-of-week number, 1 (Monday) through 7 (Sunday).

t()

A semantic date preset.

Functions

The built-in preset table, in display order.

Finds a preset by its canonical id.

Finds a preset by its typed token, case-sensitively.

Resolves preset against a reference date and the locale's first day of week, returning a Flicker.Facet.Range tagged with the preset's id.

Types

day_of_week()

@type day_of_week() :: 1..7

A day-of-week number, 1 (Monday) through 7 (Sunday).

t()

@type t() :: %Flicker.Facet.Preset{
  id: atom(),
  label: String.t(),
  resolve: (Date.t(), day_of_week() -> {Date.t() | nil, Date.t() | nil}) | nil,
  token: String.t()
}

A semantic date preset.

Functions

builtin()

@spec builtin() :: [t()]

The built-in preset table, in display order.

Examples

iex> Flicker.Facet.Preset.builtin() |> Enum.map(& &1.token) |> Enum.take(3)
["today", "yesterday", "last-7-days"]

find_by_id(id, presets \\ builtin())

@spec find_by_id(atom(), [t()]) :: t() | nil

Finds a preset by its canonical id.

Examples

iex> Flicker.Facet.Preset.find_by_id(:all_time).token
"all-time"

iex> Flicker.Facet.Preset.find_by_id(:nope)
nil

find_by_token(token, presets \\ builtin())

@spec find_by_token(String.t(), [t()]) :: t() | nil

Finds a preset by its typed token, case-sensitively.

Examples

iex> Flicker.Facet.Preset.find_by_token("last-30-days").id
:last_30_days

iex> Flicker.Facet.Preset.find_by_token("Last-30-Days")
nil

iex> Flicker.Facet.Preset.find_by_token("nope")
nil

resolve(preset, reference_date, first_day_of_week)

@spec resolve(t(), Date.t(), day_of_week()) :: Flicker.Facet.Range.t()

Resolves preset against a reference date and the locale's first day of week, returning a Flicker.Facet.Range tagged with the preset's id.

Examples

iex> preset = Flicker.Facet.Preset.find_by_id(:last_7_days)
...> Flicker.Facet.Preset.resolve(preset, ~D[2026-07-28], 1)
%Flicker.Facet.Range{from: ~D[2026-07-22], to: ~D[2026-07-28], preset: :last_7_days}

iex> preset = Flicker.Facet.Preset.find_by_id(:this_week)
...> Flicker.Facet.Preset.resolve(preset, ~D[2026-07-29], 1).from
~D[2026-07-27]

iex> preset = Flicker.Facet.Preset.find_by_id(:this_week)
...> Flicker.Facet.Preset.resolve(preset, ~D[2026-07-29], 7).from
~D[2026-07-26]

iex> preset = Flicker.Facet.Preset.find_by_id(:all_time)
...> Flicker.Facet.Preset.resolve(preset, ~D[2026-07-28], 1)
%Flicker.Facet.Range{from: nil, to: nil, preset: :all_time}