Files
herolib/lib/servers/calendar/calbox/event.v
2025-02-17 06:40:06 +03:00

106 lines
2.6 KiB
V

module calbox
// Represents an event
@[heap]
pub struct Event {
CalendarComponent
pub mut:
start_time i64
end_time ?i64 // Either end_time or duration must be set
duration ?string // ISO 8601 duration format
rrule ?RecurrenceRule
rdate []i64 // Additional recurrence dates
exdate []i64 // Dates to exclude
transp EventTransp
attendees []Attendee
organizer ?Attendee
}
// Event transparency (busy time)
pub enum EventTransp {
opaque // Blocks time (shows as busy)
transparent // Does not block time (shows as free)
}
// String representation of event transparency
pub fn (t EventTransp) str() string {
return match t {
.opaque { 'OPAQUE' }
.transparent { 'TRANSPARENT' }
}
}
// Parse event transparency from string
pub fn parse_event_transp(s string) !EventTransp {
return match s {
'OPAQUE' { EventTransp.opaque }
'TRANSPARENT' { EventTransp.transparent }
else { error('Invalid event transparency: ${s}') }
}
}
// Checks if an event overlaps with a time range
fn (event Event) overlaps(tr TimeRange) bool {
// Get end time from either end_time or duration
mut end_ts := event.end_time or {
// TODO: Add duration parsing to get actual end time
event.start_time + 3600 // Default 1 hour if no end/duration
}
// Check basic overlap
if is_in_range(event.start_time, tr) || is_in_range(end_ts, tr) {
return true
}
// Check recurrences if any
if rule := event.rrule {
// TODO: Implement recurrence expansion
// For now just check if the rule's until date (if any) is after range start
if until := rule.until {
return until >= tr.start
}
return true // Infinite recurrence overlaps everything
}
return false
}
// Gets the effective end time of an event
pub fn (event Event) get_effective_end_time() !i64 {
if end := event.end_time {
return end
}
if dur_str := event.duration {
duration := parse_duration(dur_str)!
return duration.add_to(event.start_time)
}
// Default 1 hour duration
return event.start_time + 3600
}
// Gets all instances of an event that overlap with a time range
pub fn (event Event) get_instances(tr TimeRange) ![]EventInstance {
// For non-recurring events, just check if it overlaps
if event.rrule == none && event.rdate.len == 0 {
end_time := event.get_effective_end_time()!
if event.start_time < tr.end && end_time > tr.start {
return [
EventInstance{
original_event: event
start_time: event.start_time
end_time: end_time
recurrence_id: event.start_time
is_override: false
},
]
}
return []
}
// Expand recurring event
if instances := expand_recurring_event(event, tr) {
return instances
}
return []
}