1use core::{error, fmt, ops, str};
14
15use alloc::string::{String, ToString};
16
17#[derive(Debug)]
19pub struct ParseIcalVersionError(
20 String,
22);
23
24impl fmt::Display for ParseIcalVersionError {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 write!(f, "Cannot parse iCalendar version `{}`", self.0)
27 }
28}
29
30impl error::Error for ParseIcalVersionError {}
31
32#[derive(Clone, Copy, Debug, PartialEq, Eq)]
35pub enum IcalVersion {
36 V1_0,
38 V2_0,
40}
41
42impl str::FromStr for IcalVersion {
43 type Err = ParseIcalVersionError;
44
45 fn from_str(version: &str) -> Result<Self, Self::Err> {
47 match version {
48 "1.0" => Ok(Self::V1_0),
49 "2.0" => Ok(Self::V2_0),
50 _ => Err(ParseIcalVersionError(version.to_string())),
51 }
52 }
53}
54
55impl ops::Deref for IcalVersion {
56 type Target = str;
57
58 fn deref(&self) -> &Self::Target {
59 match self {
60 Self::V1_0 => "1.0",
61 Self::V2_0 => "2.0",
62 }
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use alloc::string::ToString;
69
70 use crate::version::IcalVersion;
71
72 #[test]
73 fn maps_known_wire_strings_both_ways() {
74 assert_eq!("1.0".parse().ok(), Some(IcalVersion::V1_0));
75 assert_eq!(IcalVersion::V2_0.to_string(), "2.0");
76 assert_eq!(&*IcalVersion::V2_0, "2.0");
77 }
78
79 #[test]
80 fn rejects_unknown_versions() {
81 let error = "5.0".parse::<IcalVersion>().unwrap_err();
82 assert!(error.to_string().contains("5.0"));
83 }
84}