diff --git a/activitystreams-types/src/object/properties.rs b/activitystreams-types/src/object/properties.rs index 9154bd6..8ba8465 100644 --- a/activitystreams-types/src/object/properties.rs +++ b/activitystreams-types/src/object/properties.rs @@ -578,13 +578,12 @@ properties! { "", "If not specified, the default is assumed to be \"m\" for meters.", "", - "TODO: encode rage as any of `\"cm\"` | `\"feet\"` | `\"inches\"` | `\"km\"` | `\"m\"` | `xsd:anyUri`", - "- Range: `xsd:anyUri` | `xsd:string`", + "- Range: `\"cm\"` | `\"feet\"` | `\"inches\"` | `\"km\"` | `\"m\"` | `xsd:anyUri` | `xsd:anyUri`", "- Functional: true", ], types [ + Length, XsdAnyUri, - XsdString, ], functional, }, diff --git a/activitystreams-types/src/primitives/length.rs b/activitystreams-types/src/primitives/length.rs new file mode 100644 index 0000000..8530792 --- /dev/null +++ b/activitystreams-types/src/primitives/length.rs @@ -0,0 +1,118 @@ +#[derive( + Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, serde::Deserialize, serde::Serialize, +)] +#[serde(untagged)] +pub enum Length { + #[serde(rename = "cm")] + Centimeters, + + #[serde(rename = "feet")] + Feet, + + #[serde(rename = "inches")] + Inches, + + #[serde(rename = "km")] + Kilometers, + + #[serde(rename = "m")] + Meters, +} + +#[derive(Clone, Debug, thiserror::Error)] +#[error("Could not parse units")] +pub struct LengthError; + +impl Length { + pub fn is_centimeters(&self) -> bool { + match self { + Length::Centimeters => true, + _ => false, + } + } + + pub fn is_feet(&self) -> bool { + match self { + Length::Feet => true, + _ => false, + } + } + + pub fn is_inches(&self) -> bool { + match self { + Length::Inches => true, + _ => false, + } + } + + pub fn is_kilometers(&self) -> bool { + match self { + Length::Kilometers => true, + _ => false, + } + } + + pub fn is_meters(&self) -> bool { + match self { + Length::Meters => true, + _ => false, + } + } +} + +impl Default for Length { + fn default() -> Self { + Length::Meters + } +} + +impl std::str::FromStr for Length { + type Err = LengthError; + + fn from_str(s: &str) -> Result { + match s { + "cm" => Ok(Length::Centimeters), + "feet" => Ok(Length::Feet), + "inches" => Ok(Length::Inches), + "km" => Ok(Length::Kilometers), + "m" => Ok(Length::Meters), + _ => Err(LengthError), + } + } +} + +impl std::convert::TryFrom<&str> for Length { + type Error = LengthError; + + fn try_from(s: &str) -> Result { + s.parse() + } +} + +impl std::convert::TryFrom<&mut str> for Length { + type Error = LengthError; + + fn try_from(s: &mut str) -> Result { + s.parse() + } +} + +impl std::convert::TryFrom for Length { + type Error = LengthError; + + fn try_from(s: String) -> Result { + s.parse() + } +} + +impl std::fmt::Display for Length { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Length::Centimeters => write!(f, "cm"), + Length::Feet => write!(f, "feet"), + Length::Inches => write!(f, "inches"), + Length::Kilometers => write!(f, "km"), + Length::Meters => write!(f, "meters"), + } + } +} diff --git a/activitystreams-types/src/primitives/mod.rs b/activitystreams-types/src/primitives/mod.rs index 996e913..f504281 100644 --- a/activitystreams-types/src/primitives/mod.rs +++ b/activitystreams-types/src/primitives/mod.rs @@ -1,3 +1,4 @@ +mod length; mod mime_media_type; mod rdf_lang_string; mod xsd_any_uri; @@ -9,6 +10,7 @@ mod xsd_non_negative_integer; mod xsd_string; pub use self::{ + length::Length, mime_media_type::{MimeMediaType, MimeMediaTypeError}, rdf_lang_string::RdfLangString, xsd_any_uri::{XsdAnyUri, XsdAnyUriError}, diff --git a/activitystreams-types/src/primitives/xsd_string.rs b/activitystreams-types/src/primitives/xsd_string.rs index 5db7d6b..16cc16a 100644 --- a/activitystreams-types/src/primitives/xsd_string.rs +++ b/activitystreams-types/src/primitives/xsd_string.rs @@ -26,6 +26,30 @@ impl From for String { } } +impl AsRef for XsdString { + fn as_ref(&self) -> &str { + &self.0 + } +} + +impl AsRef for XsdString { + fn as_ref(&self) -> &String { + &self.0 + } +} + +impl AsMut for XsdString { + fn as_mut(&mut self) -> &mut str { + &mut self.0 + } +} + +impl AsMut for XsdString { + fn as_mut(&mut self) -> &mut String { + &mut self.0 + } +} + impl std::fmt::Display for XsdString { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { std::fmt::Display::fmt(&self.0, f)