Add lazy day/week iterators to Calendar that yield pre-bucketed event views, making it easy to plug eventix into UI frameworks (Yew, Leptos, Dioxus, etc.) for calendar rendering.
Motivation
eventix already has lazy iteration at the recurrence level (Recurrence::occurrences(start).take(5)), but calendar-level queries like events_between() and events_on_date() return eager Vec<EventOccurrence>. Building a calendar UI currently requires:
- Picking an arbitrary end date
- Collecting all occurrences into a Vec
- Manually grouping by date
There's no way to lazily walk forward through days/weeks and get events pre-grouped per time slice — which is exactly what UI rendering needs.
Proposed API
// Lazy day iteration — only computes events for days you consume
for day in cal.days(start).take(30) {
println!("{}: {} events", day.date(), day.event_count());
for event in day.events() {
println!(" {} at {}", event.title(), event.occurrence_time);
}
}
// Lazy week iteration — each WeekView contains 7 DayViews
for week in cal.weeks(start).take(4) {
println!("Week of {}: {} events", week.start_date(), week.event_count());
}
// Backward iteration for scrolling into the past
let previous_30_days = cal.days_back(today).take(30);
New types
| Type |
Purpose |
DayView |
A single calendar day with its events pre-bucketed and sorted |
WeekView |
7 DayViews (Monday–Sunday) |
OwnedEventOccurrence |
Owned event snapshot (no lifetime ties to Calendar) |
DayIterator |
Lazy iterator yielding DayViews |
WeekIterator |
Lazy iterator yielding WeekViews |
Use Cases
- Calendar UIs: Each
DayView maps directly to a day cell/card component
- Agenda views:
.days(today).take(7).filter(|d| !d.is_empty())
- Infinite scroll: Keep calling
.next() as the user scrolls — no end date needed
- Week/month grids:
.weeks(start).take(4) for a month view
Design Decisions
- Owned data:
DayView owns its event data (OwnedEventOccurrence) instead of borrowing from Calendar, so views can be freely moved into UI component props
- Infinite iterator:
DayIterator never returns None — callers use .take(N) to bound it (matches OccurrenceIterator pattern)
- Timezone-aware: Day boundaries respect the timezone passed to
days(start), including DST transitions
- Additive only: No breaking changes to existing APIs
Target
v0.5.0
Add lazy day/week iterators to
Calendarthat yield pre-bucketed event views, making it easy to plug eventix into UI frameworks (Yew, Leptos, Dioxus, etc.) for calendar rendering.Motivation
eventix already has lazy iteration at the recurrence level (
Recurrence::occurrences(start).take(5)), but calendar-level queries likeevents_between()andevents_on_date()return eagerVec<EventOccurrence>. Building a calendar UI currently requires:There's no way to lazily walk forward through days/weeks and get events pre-grouped per time slice — which is exactly what UI rendering needs.
Proposed API
New types
DayViewWeekViewDayViews (Monday–Sunday)OwnedEventOccurrenceDayIteratorDayViewsWeekIteratorWeekViewsUse Cases
DayViewmaps directly to a day cell/card component.days(today).take(7).filter(|d| !d.is_empty()).next()as the user scrolls — no end date needed.weeks(start).take(4)for a month viewDesign Decisions
DayViewowns its event data (OwnedEventOccurrence) instead of borrowing from Calendar, so views can be freely moved into UI component propsDayIteratornever returnsNone— callers use.take(N)to bound it (matchesOccurrenceIteratorpattern)days(start), including DST transitionsTarget
v0.5.0