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