feat(activity): computation and range syntax in the core #305
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "279_activity-computation-and-range"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #279 (part of #277).
The core now computes everything a host shows of an activity command for a range of days. Nothing prints it or draws it yet (#280–#282).
Range (
commands/activity/range.rs, pure)RangeSpec::parse:all,2026,2026-10,2026-10-16,2026-10-03..2026-10-17(a reversed range is an error),last N days/last 1 day. Case and surrounding spaces don't matter. Any other text gives an error that lists the accepted forms.Displaywrites it back in the same form.resolve(today, start) -> DayRange { from, to, unit }. A year, a month or a range of days keeps all of its days, so a calendar shows the whole month. Onlyallis cut, to run from the first tracked day to today.label(All time,Oct 2026,3–17 Oct,28 Sep–4 Oct,28 Dec 2025–3 Jan 2026),step(±n),can_step,spec,quick_picks(today), andShape::of(Day/Calendarup to 42 days /Grid).Computation (
commands/activity/compute.rs)Matchholding both series.Tracked,FutureorUntracked(beforestart, or before the first match).DayCellhas, per series, the count and the first and last time; also the number of distinct shards, theClassification, the series it isdrawnin (split/first/most, a tie goes to the first) and itslevel(count: 1–4+;fixed: 4).Statsholds the inclusive and the exclusive day counts together, plusper_weekandpercent. With 0 tracked days everything is 0, never a division by zero.PageRequest/Pagehandle paging.Facade
api::activity(store, project, stream, key, range, now, page) -> ActivityReport: range, label, shape, start, whether it can step back and forward, the series (name and colour),exclude_mixed, the days, the stats, a page ofActivityShards with theirshard_summary, and thesharedshards.api::activity_range(text).ConfigErrorfor an unknown key or a command of another type (…is not an activity command). A newCoreError::InvalidRangecovers a text that is no range.Deviations from the plan
api::activitytakes aStreamStore.shard_summaryneeds the text of the file, so only the files of the requested page are read. The timezone comes from the project, not from a separate argument.UnknownCommand/NotAnActivityCommandvariants: the facade's existingConfigErrorwording is used, as for every other command type.InvalidRangecrosses the bindings asStreamdException.InvalidRange, with its arm in the app'sreason(). The records of the report come with #283.Tests
These cover the sample of the screenshots (15 shards, 11 of 17 days active, 6.2 a week, Run 7 including 2 mixed, Climbing 6, Mixed 2, None 6), the exclusive mode,
startcutting days, a shard in two series, a sub-heading counted once, themosttie,fixed, a day at midnight across Berlin's DST change, and every range form, label, step, clamp and quick pick, plus paging. Facade tests on aMemoryStorecover the summaries, paging and errors.nix flake checkpasses.nix build .#streamd-appbuilds with its tests.Docs: R36 (range and computation), README (Activity), AGENTS.md (the module and the facade).