1use calendar_types::string::Uri;
4
5#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
10pub struct Geo {
11 pub lat: f64,
12 pub lon: f64,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq)]
19pub enum Attachment {
20 Uri(Box<Uri>),
21 Binary(Vec<u8>),
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
26pub enum InvalidFormatTypeError {
27 #[error("expected at least one character")]
28 EmptyString,
29 #[error("missing '/' separator between type and subtype")]
30 MissingSlash,
31 #[error("empty type part before '/'")]
32 EmptyType,
33 #[error("empty subtype part after '/'")]
34 EmptySubtype,
35}
36
37#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, dizzy::DstNewtype)]
41#[dizzy(invariant = FormatType::str_is_format_type, error = InvalidFormatTypeError)]
42#[dizzy(constructor = pub new)]
43#[dizzy(getter = pub const as_str)]
44#[dizzy(derive(Debug, CloneBoxed, IntoBoxed))]
45#[dizzy(owned = pub FormatTypeBuf(String))]
46#[dizzy(derive_owned(Debug, IntoBoxed))]
47#[repr(transparent)]
48pub struct FormatType(str);
49
50impl FormatType {
51 fn str_is_format_type(s: &str) -> Result<(), InvalidFormatTypeError> {
52 if s.is_empty() {
53 return Err(InvalidFormatTypeError::EmptyString);
54 }
55
56 let (type_part, subtype) = s
57 .split_once('/')
58 .ok_or(InvalidFormatTypeError::MissingSlash)?;
59
60 if type_part.is_empty() {
61 return Err(InvalidFormatTypeError::EmptyType);
62 }
63 if subtype.is_empty() {
64 return Err(InvalidFormatTypeError::EmptySubtype);
65 }
66
67 Ok(())
68 }
69
70 #[inline(always)]
72 pub fn type_part(&self) -> &str {
73 self.as_str()
74 .split_once('/')
75 .expect("FormatType must contain /")
76 .0
77 }
78
79 #[inline(always)]
81 pub fn subtype(&self) -> &str {
82 self.as_str()
83 .split_once('/')
84 .expect("FormatType must contain /")
85 .1
86 }
87}
88
89impl std::fmt::Display for FormatType {
90 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91 f.write_str(self.as_str())
92 }
93}
94
95impl PartialEq for FormatTypeBuf {
96 fn eq(&self, other: &Self) -> bool {
97 **self == **other
98 }
99}
100
101impl Eq for FormatTypeBuf {}
102
103impl std::fmt::Display for FormatTypeBuf {
104 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105 f.write_str(self.as_str())
106 }
107}
108
109#[derive(Debug, Clone, PartialEq, Eq)]
111pub enum StructuredDataValue {
112 Text(String),
113 Binary(Vec<u8>),
114 Uri(Box<Uri>),
115}
116
117#[derive(Debug, Clone, PartialEq, Eq)]
119pub enum StyledDescriptionValue {
120 Text(String),
121 Uri(Box<Uri>),
122 Iana { value_type: String, value: String },
123}