Packages

Reference Elixir validator for WPL (Wellness Plan Language) — JSON Schema + semantic invariants

Current section

Files

Jump to
wpl_validator lib wpl validator rules phase_duration_mismatch.ex
Raw

lib/wpl/validator/rules/phase_duration_mismatch.ex

defmodule WPL.Validator.Rules.PhaseDurationMismatch do
@moduledoc false
use WPL.Validator.Rule
alias WPL.Validator.{Error, WalkContext}
@impl true
def enter_phase(ctx, phase, path) do
dur = Map.get(phase, "duration")
weeks = phase |> Map.get("weeks", []) |> List.wrap()
with true <- is_map(dur),
true <- weeks != [],
value when is_number(value) <- Map.get(dur, "value"),
unit when is_binary(unit) <- Map.get(dur, "unit"),
true <- mismatch?(value, unit, length(weeks)) do
WalkContext.emit(ctx, %Error{
path: path,
code: :phase_duration_mismatch,
message:
"Phase duration (#{value} #{unit}) does not match weeks array (#{length(weeks)} items)",
severity: :warning,
meta: %{
declared_value: value,
declared_unit: unit,
weeks_count: length(weeks)
}
})
else
_ -> ctx
end
end
defp mismatch?(value, "weeks", weeks_count) do
value != weeks_count
end
defp mismatch?(value, "days", weeks_count) do
expected_weeks = trunc(value / 7)
expected_weeks > 0 and abs(expected_weeks - weeks_count) > 1
end
defp mismatch?(_value, _unit, _weeks_count), do: false
end