Skip to main content

cdevents_sdk/
uri.rs

1// wrapper for fluent_uri::UriRef to allow for restristed set of operations
2// and to complete currently missing features.
3// Why fluent_uri?
4// - support uri & uri-reference, preserve the original string, but young, doesn't impl PartialEq,...
5// - http::Uri, more mature, but doesn't support uri-reference, and normalize url when generate string
6//TODO impl the check difference for Uri and Uri-reference
7
8use std::str::FromStr;
9
10use serde::{Serialize, Deserialize};
11#[cfg(feature = "testkit")] use proptest_derive::Arbitrary;
12use crate::UriReference;
13
14#[derive(Debug, Clone, Default, Serialize, Deserialize)]
15#[cfg_attr(feature = "testkit", derive(Arbitrary))]
16pub struct Uri(
17    #[cfg_attr(feature = "testkit", proptest(value = "fluent_uri::UriRef::parse(\"https://example.com/\".to_owned()).unwrap()"))] //TODO generate random value
18    //#[serde(with = "crate::serde::fluent_uri")]
19    pub(crate) fluent_uri::UriRef<String>
20);
21
22impl PartialEq for Uri {
23    fn eq(&self, other: &Self) -> bool {
24        self.0.as_str() == other.0.as_str()
25    }
26}
27
28impl Eq for Uri {}
29
30impl FromStr for Uri {
31    type Err = crate::Error;
32
33    fn from_str(s: &str) -> Result<Self, Self::Err> {
34        //TODO check it's not a reference URI
35        fluent_uri::UriRef::parse(s.to_owned()).map_err(|(e,_)| Self::Err::from(e)).map(Uri)
36    }
37}
38
39impl TryFrom<UriReference> for Uri {
40    type Error = crate::Error;
41
42    fn try_from(s: UriReference) -> Result<Self, Self::Error> {
43        Uri::from_str(s.as_str())
44    }
45}
46
47impl TryFrom<&str> for Uri {
48    type Error = crate::Error;
49
50    fn try_from(s: &str) -> Result<Self, Self::Error> {
51        fluent_uri::UriRef::parse(s.to_owned()).map_err(|(e, _)| Self::Error::from(e)).map(Uri)
52    }
53}
54
55impl TryFrom<String> for Uri {
56    type Error = crate::Error;
57
58    fn try_from(s: String) -> Result<Self, Self::Error> {
59        fluent_uri::UriRef::parse(s).map_err(|(e, _)| Self::Error::from(e)).map(Uri)
60    }
61}
62
63impl std::fmt::Display for Uri {
64    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65        self.0.as_str().fmt(f)
66    }
67}
68
69impl Uri {
70    pub fn as_str(&self) -> &str {
71        self.0.as_str()
72    }
73}
74
75// impl From<Uri> for fluent_uri::UriRef<String> {
76//     fn from(uri: Uri) -> Self {
77//         uri.0
78//     }
79// }
80
81#[cfg(test)]
82mod tests {
83    use proptest::prelude::*;
84    use super::*;
85
86    proptest! {
87        #[test]
88        #[cfg(feature = "testkit")]
89        fn arbitraries_are_json_valid(s in any::<Uri>()) {
90            let json_str = serde_json::to_string(&s).unwrap();
91            let actual = serde_json::from_str::<Uri>(&json_str).unwrap();
92            assert_eq!(s, actual);
93        }
94    }
95}