06cfbb6d

By: Tom Sydney Kerckhove <syd@cs-syd.eu>

ical: refuse an out-of-range rule part value

GREEN for the tests in the previous commit.  Nine rule part parsers now
ask whether the value they just read is in range, and refuse it if not.

The range itself is not restated anywhere.  Each of these types already
declares it in its 'Validity' instance, so 'requireInRange' asks that,
which keeps the parser and the invariant from drifting apart: tighten one
and the other follows.  That is also why the two preceding fixes had to
land first.  The check inherits whatever 'Validity' says, so a wrong bound
becomes a wrong refusal, and before those fixes this would have started
refusing COUNT=100 and BYDAY=6MO, both of them ordinary.

Refused rather than repaired.  The spec says which values are valid but
not what to do with one that is not, and dropping the value would empty
the rule part.  For a part that limits rather than expands, an empty part
means no restriction at all, so a forbidden value would widen the
recurrence set rather than narrow it -- the same shape as the BYDAY
widening fixed earlier.  BYMONTH already refused an out-of-range value, so
refusing is what the rest of the module did anyway.

The check is per rule part and deliberately not on the whole
'RecurrenceRule'.  'Validity RecurrenceRule' also rules on combinations,
such as a numeric BYDAY at a frequency that forbids one, and those are
fixable errors raised while recurring.  Refusing the rule outright for one
would undo that.

It lives in the parsers rather than in 'parseRecurrenceRule', so that
'recurrenceRulePartP' cannot hand back an invalid value either.  It is the
primitive, so the invariant belongs there.

Suite timing

Time to Start Worker time Duration Time to finish Idle
Config 51s 0s 0s 51s 51s
Eval 53s 12s 12s 1m06s 1s
Build 1m05s 0s 1h14m14s 1h15m20s 1h14m13s
Suite 51s 13s 1h14m29s 1h15m20s 1h15m06s

Timeline

0s1m