1use strum::{Display, EnumString};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, EnumString, Display)]
11#[non_exhaustive]
12#[strum(ascii_case_insensitive)]
13pub enum Method {
14 #[strum(serialize = "PUBLISH")]
15 Publish,
16 #[strum(serialize = "REQUEST")]
17 Request,
18 #[strum(serialize = "REPLY")]
19 Reply,
20 #[strum(serialize = "ADD")]
21 Add,
22 #[strum(serialize = "CANCEL")]
23 Cancel,
24 #[strum(serialize = "REFRESH")]
25 Refresh,
26 #[strum(serialize = "COUNTER")]
27 Counter,
28 #[strum(serialize = "DECLINECOUNTER")]
29 DeclineCounter,
30}
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
34pub struct Percent(u8);
35
36impl Percent {
37 pub const MIN: Self = Percent(0);
39 pub const MAX: Self = Percent(100);
41
42 #[inline(always)]
44 pub const fn get(self) -> u8 {
45 self.0
46 }
47
48 #[inline(always)]
50 pub const fn new(value: u8) -> Option<Self> {
51 match value {
52 0..=100 => Some(Self(value)),
53 _ => None,
54 }
55 }
56}
57
58#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
60pub enum Priority {
61 #[default]
62 Zero,
63 A1,
64 A2,
65 A3,
66 B1,
67 B2,
68 B3,
69 C1,
70 C2,
71 C3,
72}
73
74#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
76pub enum PriorityClass {
77 Low,
79 Medium,
81 High,
83}
84
85impl PartialOrd for Priority {
86 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
87 if matches!(self, Self::Zero) || matches!(other, Self::Zero) {
88 None
89 } else {
90 let a = (*self) as u8;
91 let b = (*other) as u8;
92
93 match a.cmp(&b) {
94 std::cmp::Ordering::Less => Some(std::cmp::Ordering::Greater),
95 std::cmp::Ordering::Equal => Some(std::cmp::Ordering::Equal),
96 std::cmp::Ordering::Greater => Some(std::cmp::Ordering::Less),
97 }
98 }
99 }
100}
101
102impl Priority {
103 pub const fn is_low(self) -> bool {
105 matches!(self.into_class(), Some(PriorityClass::Low))
106 }
107
108 pub const fn is_medium(self) -> bool {
110 matches!(self.into_class(), Some(PriorityClass::Medium))
111 }
112
113 pub const fn is_high(self) -> bool {
115 matches!(self.into_class(), Some(PriorityClass::High))
116 }
117
118 pub const fn into_class(self) -> Option<PriorityClass> {
120 match self {
121 Self::Zero => None,
122 Self::A1 | Self::A2 | Self::A3 | Self::B1 => Some(PriorityClass::High),
123 Self::B2 => Some(PriorityClass::Medium),
124 Self::B3 | Self::C1 | Self::C2 | Self::C3 => Some(PriorityClass::Low),
125 }
126 }
127}
128
129#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
135pub enum Version {
136 V2_0,
138}
139
140#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
142pub struct Gregorian;
143
144#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
150#[non_exhaustive]
151#[strum(ascii_case_insensitive)]
152pub enum Encoding {
153 #[strum(serialize = "8BIT")]
155 Bit8,
156 #[strum(serialize = "BASE64")]
158 Base64,
159}
160
161#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
167#[non_exhaustive]
168#[strum(ascii_case_insensitive)]
169pub enum TimeTransparency {
170 #[default]
172 #[strum(serialize = "OPAQUE")]
173 Opaque,
174 #[strum(serialize = "TRANSPARENT")]
176 Transparent,
177}
178
179#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
185#[non_exhaustive]
186#[strum(ascii_case_insensitive)]
187pub enum EventStatus {
188 #[strum(serialize = "TENTATIVE")]
189 Tentative,
190 #[strum(serialize = "CONFIRMED")]
191 Confirmed,
192 #[strum(serialize = "CANCELLED")]
193 Cancelled,
194}
195
196#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
198#[non_exhaustive]
199#[strum(ascii_case_insensitive)]
200pub enum TodoStatus {
201 #[strum(serialize = "NEEDS-ACTION")]
202 NeedsAction,
203 #[strum(serialize = "COMPLETED")]
204 Completed,
205 #[strum(serialize = "IN-PROCESS")]
206 InProcess,
207 #[strum(serialize = "CANCELLED")]
208 Cancelled,
209}
210
211#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
213#[non_exhaustive]
214#[strum(ascii_case_insensitive)]
215pub enum JournalStatus {
216 #[strum(serialize = "DRAFT")]
217 Draft,
218 #[strum(serialize = "FINAL")]
219 Final,
220 #[strum(serialize = "CANCELLED")]
221 Cancelled,
222}
223
224#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
230#[non_exhaustive]
231#[strum(ascii_case_insensitive)]
232pub enum ClassValue {
233 #[default]
234 #[strum(serialize = "PUBLIC")]
235 Public,
236 #[strum(serialize = "PRIVATE")]
237 Private,
238 #[strum(serialize = "CONFIDENTIAL")]
239 Confidential,
240}
241
242#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
248#[non_exhaustive]
249#[strum(ascii_case_insensitive)]
250pub enum CalendarUserType {
251 #[default]
252 #[strum(serialize = "INDIVIDUAL")]
253 Individual,
254 #[strum(serialize = "GROUP")]
255 Group,
256 #[strum(serialize = "RESOURCE")]
257 Resource,
258 #[strum(serialize = "ROOM")]
259 Room,
260 #[strum(serialize = "UNKNOWN")]
261 Unknown,
262}
263
264#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
266#[non_exhaustive]
267#[strum(ascii_case_insensitive)]
268pub enum ParticipationRole {
269 #[strum(serialize = "CHAIR")]
270 Chair,
271 #[default]
272 #[strum(serialize = "REQ-PARTICIPANT")]
273 ReqParticipant,
274 #[strum(serialize = "OPT-PARTICIPANT")]
275 OptParticipant,
276 #[strum(serialize = "NON-PARTICIPANT")]
277 NonParticipant,
278}
279
280#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
282#[non_exhaustive]
283#[strum(ascii_case_insensitive)]
284pub enum ParticipationStatus {
285 #[default]
286 #[strum(serialize = "NEEDS-ACTION")]
287 NeedsAction,
288 #[strum(serialize = "ACCEPTED")]
289 Accepted,
290 #[strum(serialize = "DECLINED")]
291 Declined,
292 #[strum(serialize = "TENTATIVE")]
293 Tentative,
294 #[strum(serialize = "DELEGATED")]
295 Delegated,
296 #[strum(serialize = "COMPLETED")]
297 Completed,
298 #[strum(serialize = "IN-PROCESS")]
299 InProcess,
300}
301
302#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
304#[non_exhaustive]
305#[strum(ascii_case_insensitive)]
306pub enum FreeBusyType {
307 #[strum(serialize = "FREE")]
308 Free,
309 #[strum(serialize = "BUSY")]
310 Busy,
311 #[strum(serialize = "BUSY-UNAVAILABLE")]
312 BusyUnavailable,
313 #[strum(serialize = "BUSY-TENTATIVE")]
314 BusyTentative,
315}
316
317#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
319#[non_exhaustive]
320#[strum(ascii_case_insensitive)]
321pub enum RelationshipType {
322 #[strum(serialize = "PARENT")]
323 Parent,
324 #[strum(serialize = "CHILD")]
325 Child,
326 #[strum(serialize = "SIBLING")]
327 Sibling,
328 #[strum(serialize = "SNOOZE")]
330 Snooze,
331}
332
333#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
335#[non_exhaustive]
336#[strum(ascii_case_insensitive)]
337pub enum AlarmAction {
338 #[strum(serialize = "AUDIO")]
339 Audio,
340 #[strum(serialize = "DISPLAY")]
341 Display,
342 #[strum(serialize = "EMAIL")]
343 Email,
344}
345
346#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
348#[non_exhaustive]
349#[strum(ascii_case_insensitive)]
350pub enum TriggerRelation {
351 #[strum(serialize = "START")]
352 Start,
353 #[strum(serialize = "END")]
354 End,
355}
356
357#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
359#[non_exhaustive]
360#[strum(ascii_case_insensitive)]
361pub enum ValueType {
362 #[strum(serialize = "BINARY")]
363 Binary,
364 #[strum(serialize = "BOOLEAN")]
365 Boolean,
366 #[strum(serialize = "CAL-ADDRESS")]
367 CalAddress,
368 #[strum(serialize = "DATE")]
369 Date,
370 #[strum(serialize = "DATE-TIME")]
371 DateTime,
372 #[strum(serialize = "DURATION")]
373 Duration,
374 #[strum(serialize = "FLOAT")]
375 Float,
376 #[strum(serialize = "INTEGER")]
377 Integer,
378 #[strum(serialize = "PERIOD")]
379 Period,
380 #[strum(serialize = "RECUR")]
381 Recur,
382 #[strum(serialize = "TEXT")]
383 Text,
384 #[strum(serialize = "TIME")]
385 Time,
386 #[strum(serialize = "URI")]
387 Uri,
388 #[strum(serialize = "UTC-OFFSET")]
389 UtcOffset,
390}
391
392#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
394pub struct ThisAndFuture;
395
396#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
402#[non_exhaustive]
403#[strum(ascii_case_insensitive)]
404pub enum DisplayType {
405 #[strum(serialize = "BADGE")]
406 Badge,
407 #[strum(serialize = "GRAPHIC")]
408 Graphic,
409 #[strum(serialize = "FULLSIZE")]
410 Fullsize,
411 #[strum(serialize = "THUMBNAIL")]
412 Thumbnail,
413}
414
415#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
417#[non_exhaustive]
418#[strum(ascii_case_insensitive)]
419pub enum FeatureType {
420 #[strum(serialize = "AUDIO")]
421 Audio,
422 #[strum(serialize = "CHAT")]
423 Chat,
424 #[strum(serialize = "FEED")]
425 Feed,
426 #[strum(serialize = "MODERATOR")]
427 Moderator,
428 #[strum(serialize = "PHONE")]
429 Phone,
430 #[strum(serialize = "SCREEN")]
431 Screen,
432 #[strum(serialize = "VIDEO")]
433 Video,
434}
435
436#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
442#[non_exhaustive]
443#[strum(ascii_case_insensitive)]
444pub enum ResourceType {
445 #[strum(serialize = "ROOM")]
446 Room,
447 #[strum(serialize = "PROJECTOR")]
448 Projector,
449 #[strum(serialize = "REMOTE-CONFERENCE-AUDIO")]
450 RemoteConferenceAudio,
451 #[strum(serialize = "REMOTE-CONFERENCE-VIDEO")]
452 RemoteConferenceVideo,
453}
454
455#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
457#[non_exhaustive]
458#[strum(ascii_case_insensitive)]
459pub enum ParticipantType {
460 #[strum(serialize = "ACTIVE")]
461 Active,
462 #[strum(serialize = "INACTIVE")]
463 Inactive,
464 #[strum(serialize = "SPONSOR")]
465 Sponsor,
466 #[strum(serialize = "CONTACT")]
467 Contact,
468 #[strum(serialize = "BOOKING-CONTACT")]
469 BookingContact,
470 #[strum(serialize = "EMERGENCY-CONTACT")]
471 EmergencyContact,
472 #[strum(serialize = "PUBLICITY-CONTACT")]
473 PublicityContact,
474 #[strum(serialize = "PLANNER-CONTACT")]
475 PlannerContact,
476 #[strum(serialize = "PERFORMER")]
477 Performer,
478 #[strum(serialize = "SPEAKER")]
479 Speaker,
480}
481
482#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
488#[non_exhaustive]
489#[strum(ascii_case_insensitive)]
490pub enum ProximityValue {
491 #[strum(serialize = "ARRIVE")]
492 Arrive,
493 #[strum(serialize = "DEPART")]
494 Depart,
495 #[strum(serialize = "CONNECT")]
496 Connect,
497 #[strum(serialize = "DISCONNECT")]
498 Disconnect,
499}
500
501#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, Display)]
507#[non_exhaustive]
508#[strum(ascii_case_insensitive)]
509pub enum Status {
510 #[strum(serialize = "TENTATIVE")]
511 Tentative,
512 #[strum(serialize = "CONFIRMED")]
513 Confirmed,
514 #[strum(serialize = "CANCELLED")]
515 Cancelled,
516 #[strum(serialize = "NEEDS-ACTION")]
517 NeedsAction,
518 #[strum(serialize = "COMPLETED")]
519 Completed,
520 #[strum(serialize = "IN-PROCESS")]
521 InProcess,
522 #[strum(serialize = "DRAFT")]
523 Draft,
524 #[strum(serialize = "FINAL")]
525 Final,
526}
527
528#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
534pub struct AudioAction;
535
536#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
538pub struct DisplayAction;
539
540#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
542pub struct EmailAction;
543
544#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
546pub enum UnknownAction<S> {
547 Iana(S),
549 X(S),
551}
552
553impl<S> UnknownAction<S> {
554 pub const fn as_ref(&self) -> UnknownAction<&S> {
556 match self {
557 UnknownAction::Iana(action) => UnknownAction::Iana(action),
558 UnknownAction::X(action) => UnknownAction::X(action),
559 }
560 }
561
562 pub const fn kind(&self) -> crate::string::NameKind {
564 match self {
565 UnknownAction::Iana(_) => crate::string::NameKind::Iana,
566 UnknownAction::X(_) => crate::string::NameKind::X,
567 }
568 }
569
570 pub fn into_inner(self) -> S {
572 match self {
573 UnknownAction::Iana(action) | UnknownAction::X(action) => action,
574 }
575 }
576}
577
578#[cfg(test)]
579mod tests {
580 use super::*;
581
582 #[test]
583 #[allow(clippy::neg_cmp_op_on_partial_ord)]
584 fn priority_partial_ord() {
585 assert_eq!(Priority::Zero.partial_cmp(&Priority::Zero), None);
586 assert_eq!(Priority::Zero.partial_cmp(&Priority::A1), None);
587 assert_eq!(Priority::A1.partial_cmp(&Priority::Zero), None);
588
589 assert!(Priority::A1 > Priority::A2);
590 assert!(Priority::A2 > Priority::A3);
591 assert!(Priority::A1 > Priority::A3);
592
593 assert!(Priority::A1 > Priority::B1);
594 assert!(Priority::B1 > Priority::C1);
595 assert!(Priority::A1 > Priority::C1);
596
597 assert!(!(Priority::Zero > Priority::C2));
598 assert!(!(Priority::Zero < Priority::C2));
599 assert!(Priority::Zero != Priority::C2);
600 }
601
602 #[test]
603 fn priority_class_predicates() {
604 assert!(!Priority::Zero.is_low());
605 assert!(!Priority::Zero.is_medium());
606 assert!(!Priority::Zero.is_high());
607
608 assert!(Priority::A1.is_high());
609 assert!(Priority::A2.is_high());
610 assert!(Priority::A3.is_high());
611 assert!(Priority::B1.is_high());
612
613 assert!(!Priority::B2.is_high());
614 assert!(Priority::B2.is_medium());
615 assert!(!Priority::B2.is_low());
616
617 assert!(Priority::B3.is_low());
618 assert!(Priority::C1.is_low());
619 assert!(Priority::C2.is_low());
620 assert!(Priority::C3.is_low());
621 }
622
623 #[test]
624 fn priority_class_projection() {
625 assert_eq!(Priority::Zero.into_class(), None);
626
627 assert_eq!(Priority::A1.into_class(), Some(PriorityClass::High));
628 assert_eq!(Priority::A2.into_class(), Some(PriorityClass::High));
629 assert_eq!(Priority::A3.into_class(), Some(PriorityClass::High));
630 assert_eq!(Priority::B1.into_class(), Some(PriorityClass::High));
631
632 assert_eq!(Priority::B2.into_class(), Some(PriorityClass::Medium));
633
634 assert_eq!(Priority::B3.into_class(), Some(PriorityClass::Low));
635 assert_eq!(Priority::C1.into_class(), Some(PriorityClass::Low));
636 assert_eq!(Priority::C2.into_class(), Some(PriorityClass::Low));
637 assert_eq!(Priority::C3.into_class(), Some(PriorityClass::Low));
638 }
639}