idkollen_client/models/
url.rs1use fmt::Display;
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3use std::fmt;
4use thiserror::Error;
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash)]
10pub struct Url(String);
11
12#[derive(Debug, Error)]
13#[error("invalid URL: {0}")]
14pub struct UrlError(#[from] url::ParseError);
15
16impl Url {
17 pub fn parse(s: &str) -> Result<Self, UrlError> {
18 url::Url::parse(s)?;
19
20 Ok(Self(s.to_owned()))
21 }
22
23 #[inline]
24 #[must_use]
25 pub fn as_str(&self) -> &str {
26 &self.0
27 }
28}
29
30impl From<Url> for String {
31 #[inline]
32 fn from(u: Url) -> String {
33 u.0
34 }
35}
36
37impl AsRef<str> for Url {
38 #[inline]
39 fn as_ref(&self) -> &str {
40 &self.0
41 }
42}
43
44impl Display for Url {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 f.write_str(&self.0)
47 }
48}
49
50impl Serialize for Url {
51 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
52 self.0.serialize(s)
53 }
54}
55
56impl<'de> Deserialize<'de> for Url {
57 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
58 let s = String::deserialize(d)?;
59 Url::parse(&s).map_err(serde::de::Error::custom)
60 }
61}