1use 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()"))] 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 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#[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}