Implement shared RFC 5545 VEvent library with workspace restructuring
- Created calendar-models/ shared library with RFC 5545-compliant VEvent structures - Migrated backend to use shared VEvent with proper field mappings (dtstart/dtend, rrule, exdate, etc.) - Converted CalDAV client to parse into VEvent structures with structured types - Updated all CRUD handlers to use VEvent with CalendarUser, Attendee, VAlarm types - Restructured project as Cargo workspace with frontend/, backend/, calendar-models/ - Updated Trunk configuration for new directory structure - Fixed all compilation errors and field references throughout codebase - Updated documentation and build instructions for workspace structure 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
		
							
								
								
									
										220
									
								
								calendar-models/src/common.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								calendar-models/src/common.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,220 @@ | ||||
| //! Common types and enums used across calendar components | ||||
|  | ||||
| use chrono::{DateTime, Utc, Duration}; | ||||
| use serde::{Deserialize, Serialize}; | ||||
|  | ||||
| // ==================== ENUMS AND COMMON TYPES ==================== | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] | ||||
| pub enum EventStatus { | ||||
|     Tentative, | ||||
|     Confirmed, | ||||
|     Cancelled, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] | ||||
| pub enum EventClass { | ||||
|     Public, | ||||
|     Private, | ||||
|     Confidential, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] | ||||
| pub enum TimeTransparency { | ||||
|     Opaque,      // OPAQUE - time is not available | ||||
|     Transparent, // TRANSPARENT - time is available   | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] | ||||
| pub enum TodoStatus { | ||||
|     NeedsAction, | ||||
|     Completed, | ||||
|     InProcess, | ||||
|     Cancelled, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] | ||||
| pub enum AttendeeRole { | ||||
|     Chair, | ||||
|     ReqParticipant, | ||||
|     OptParticipant, | ||||
|     NonParticipant, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] | ||||
| pub enum ParticipationStatus { | ||||
|     NeedsAction, | ||||
|     Accepted, | ||||
|     Declined, | ||||
|     Tentative, | ||||
|     Delegated, | ||||
|     Completed, | ||||
|     InProcess, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] | ||||
| pub enum AlarmAction { | ||||
|     Audio, | ||||
|     Display, | ||||
|     Email, | ||||
|     Procedure, | ||||
| } | ||||
|  | ||||
| // ==================== STRUCTURED TYPES ==================== | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||||
| pub struct CalendarUser { | ||||
|     pub cal_address: String,                    // Calendar user address (usually email) | ||||
|     pub common_name: Option<String>,            // CN parameter - display name | ||||
|     pub dir_entry_ref: Option<String>,          // DIR parameter - directory entry | ||||
|     pub sent_by: Option<String>,                // SENT-BY parameter | ||||
|     pub language: Option<String>,               // LANGUAGE parameter | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||||
| pub struct Attendee { | ||||
|     pub cal_address: String,                    // Calendar user address | ||||
|     pub common_name: Option<String>,            // CN parameter | ||||
|     pub role: Option<AttendeeRole>,             // ROLE parameter | ||||
|     pub part_stat: Option<ParticipationStatus>, // PARTSTAT parameter | ||||
|     pub rsvp: Option<bool>,                     // RSVP parameter | ||||
|     pub cu_type: Option<String>,                // CUTYPE parameter (INDIVIDUAL, GROUP, RESOURCE, ROOM, UNKNOWN) | ||||
|     pub member: Vec<String>,                    // MEMBER parameter | ||||
|     pub delegated_to: Vec<String>,              // DELEGATED-TO parameter   | ||||
|     pub delegated_from: Vec<String>,            // DELEGATED-FROM parameter | ||||
|     pub sent_by: Option<String>,                // SENT-BY parameter | ||||
|     pub dir_entry_ref: Option<String>,          // DIR parameter | ||||
|     pub language: Option<String>,               // LANGUAGE parameter | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||||
| pub struct VAlarm { | ||||
|     pub action: AlarmAction,                    // Action (ACTION) - REQUIRED | ||||
|     pub trigger: AlarmTrigger,                  // Trigger (TRIGGER) - REQUIRED | ||||
|     pub duration: Option<Duration>,             // Duration (DURATION) | ||||
|     pub repeat: Option<u32>,                    // Repeat count (REPEAT) | ||||
|     pub description: Option<String>,            // Description for DISPLAY/EMAIL | ||||
|     pub summary: Option<String>,                // Summary for EMAIL | ||||
|     pub attendees: Vec<Attendee>,               // Attendees for EMAIL | ||||
|     pub attach: Vec<Attachment>,                // Attachments for AUDIO/EMAIL | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||||
| pub enum AlarmTrigger { | ||||
|     DateTime(DateTime<Utc>),                    // Absolute trigger time | ||||
|     Duration(Duration),                         // Duration relative to start/end | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||||
| pub struct Attachment { | ||||
|     pub format_type: Option<String>,            // FMTTYPE parameter (MIME type) | ||||
|     pub encoding: Option<String>,               // ENCODING parameter | ||||
|     pub value: Option<String>,                  // VALUE parameter (BINARY or URI) | ||||
|     pub uri: Option<String>,                    // URI reference | ||||
|     pub binary_data: Option<Vec<u8>>,           // Binary data (when ENCODING=BASE64) | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||||
| pub struct GeographicPosition { | ||||
|     pub latitude: f64,                          // Latitude in decimal degrees | ||||
|     pub longitude: f64,                         // Longitude in decimal degrees | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||||
| pub struct VTimeZone { | ||||
|     pub tzid: String,                           // Time zone ID (TZID) - REQUIRED | ||||
|     pub last_modified: Option<DateTime<Utc>>,   // Last modified (LAST-MODIFIED) | ||||
|     pub tzurl: Option<String>,                  // Time zone URL (TZURL) | ||||
|     pub standard_components: Vec<TimeZoneComponent>, // STANDARD components | ||||
|     pub daylight_components: Vec<TimeZoneComponent>, // DAYLIGHT components | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||||
| pub struct TimeZoneComponent { | ||||
|     pub dtstart: DateTime<Utc>,                 // Start of this time zone definition | ||||
|     pub tzoffset_to: String,                    // UTC offset for this component | ||||
|     pub tzoffset_from: String,                  // UTC offset before this component   | ||||
|     pub rrule: Option<String>,                  // Recurrence rule | ||||
|     pub rdate: Vec<DateTime<Utc>>,              // Recurrence dates | ||||
|     pub tzname: Vec<String>,                    // Time zone names | ||||
|     pub comment: Vec<String>,                   // Comments | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||||
| pub struct VJournal { | ||||
|     // Required properties | ||||
|     pub dtstamp: DateTime<Utc>,                 // Date-time stamp (DTSTAMP) - REQUIRED | ||||
|     pub uid: String,                            // Unique identifier (UID) - REQUIRED | ||||
|      | ||||
|     // Optional properties | ||||
|     pub dtstart: Option<DateTime<Utc>>,         // Start date-time (DTSTART) | ||||
|     pub summary: Option<String>,                // Summary/title (SUMMARY)  | ||||
|     pub description: Option<String>,            // Description (DESCRIPTION) | ||||
|      | ||||
|     // Classification and status | ||||
|     pub class: Option<EventClass>,              // Classification (CLASS) | ||||
|     pub status: Option<String>,                 // Status (STATUS) | ||||
|      | ||||
|     // People and organization | ||||
|     pub organizer: Option<CalendarUser>,        // Organizer (ORGANIZER) | ||||
|     pub attendees: Vec<Attendee>,               // Attendees (ATTENDEE) | ||||
|      | ||||
|     // Categorization | ||||
|     pub categories: Vec<String>,                // Categories (CATEGORIES) | ||||
|      | ||||
|     // Versioning and modification | ||||
|     pub sequence: Option<u32>,                  // Sequence number (SEQUENCE) | ||||
|     pub created: Option<DateTime<Utc>>,         // Creation time (CREATED) | ||||
|     pub last_modified: Option<DateTime<Utc>>,   // Last modified (LAST-MODIFIED) | ||||
|      | ||||
|     // Recurrence | ||||
|     pub rrule: Option<String>,                  // Recurrence rule (RRULE) | ||||
|     pub rdate: Vec<DateTime<Utc>>,              // Recurrence dates (RDATE) | ||||
|     pub exdate: Vec<DateTime<Utc>>,             // Exception dates (EXDATE) | ||||
|     pub recurrence_id: Option<DateTime<Utc>>,   // Recurrence ID (RECURRENCE-ID) | ||||
|      | ||||
|     // Attachments | ||||
|     pub attachments: Vec<Attachment>,           // Attachments (ATTACH) | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||||
| pub struct VFreeBusy { | ||||
|     // Required properties | ||||
|     pub dtstamp: DateTime<Utc>,                 // Date-time stamp (DTSTAMP) - REQUIRED | ||||
|     pub uid: String,                            // Unique identifier (UID) - REQUIRED | ||||
|      | ||||
|     // Optional date-time properties | ||||
|     pub dtstart: Option<DateTime<Utc>>,         // Start date-time (DTSTART) | ||||
|     pub dtend: Option<DateTime<Utc>>,           // End date-time (DTEND) | ||||
|      | ||||
|     // People | ||||
|     pub organizer: Option<CalendarUser>,        // Organizer (ORGANIZER) | ||||
|     pub attendees: Vec<Attendee>,               // Attendees (ATTENDEE) | ||||
|      | ||||
|     // Free/busy time | ||||
|     pub freebusy: Vec<FreeBusyTime>,            // Free/busy time periods | ||||
|     pub url: Option<String>,                    // URL (URL) | ||||
|     pub comment: Vec<String>,                   // Comments (COMMENT) | ||||
|     pub contact: Option<String>,                // Contact information (CONTACT) | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||||
| pub struct FreeBusyTime { | ||||
|     pub fb_type: FreeBusyType,                  // Free/busy type | ||||
|     pub periods: Vec<Period>,                   // Time periods | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] | ||||
| pub enum FreeBusyType { | ||||
|     Free, | ||||
|     Busy, | ||||
|     BusyUnavailable, | ||||
|     BusyTentative, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] | ||||
| pub struct Period { | ||||
|     pub start: DateTime<Utc>,                   // Period start | ||||
|     pub end: Option<DateTime<Utc>>,             // Period end | ||||
|     pub duration: Option<Duration>,             // Period duration (alternative to end) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Connor Johnstone
					Connor Johnstone