lib.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. // Copyright 2017 The rust-url developers.
  2. //
  3. // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  4. // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  5. // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  6. // option. This file may not be copied, modified, or distributed
  7. // except according to those terms.
  8. /*!
  9. This crate provides wrappers and convenience functions to make rust-url
  10. and Serde work hand in hand.
  11. The supported types are:
  12. * `url::Url`
  13. # How do I use a data type with a `Url` member with Serde?
  14. Use the serde attributes `deserialize_with` and `serialize_with`.
  15. ```
  16. #[derive(serde::Serialize, serde::Deserialize)]
  17. struct MyStruct {
  18. #[serde(deserialize_with = "url_serde::deserialize",
  19. serialize_with = "url_serde::serialize")]
  20. url: Url,
  21. }
  22. ```
  23. # How do I encode a `Url` value with `serde_json::to_string`?
  24. Use the `Ser` wrapper.
  25. ```
  26. serde_json::to_string(&Ser::new(&url))
  27. ```
  28. # How do I decode a `Url` value with `serde_json::parse`?
  29. Use the `De` wrapper.
  30. ```
  31. serde_json::from_str(r"http:://www.rust-lang.org").map(De::into_inner)
  32. ```
  33. # How do I send `Url` values as part of an IPC channel?
  34. Use the `Serde` wrapper. It implements `Deref` and `DerefMut` for convenience.
  35. ```
  36. ipc::channel::<Serde<Url>>()
  37. ```
  38. */
  39. #![deny(missing_docs)]
  40. #![deny(unsafe_code)]
  41. extern crate serde;
  42. #[cfg(test)] #[macro_use] extern crate serde_derive;
  43. #[cfg(test)] extern crate serde_json;
  44. extern crate url;
  45. use serde::{Deserialize, Serialize, Serializer, Deserializer};
  46. use std::cmp::PartialEq;
  47. use std::error::Error;
  48. use std::fmt;
  49. use std::io::Write;
  50. use std::ops::{Deref, DerefMut};
  51. use std::str;
  52. use url::{Url, Host};
  53. /// Serialises `value` with a given serializer.
  54. ///
  55. /// This is useful to serialize `rust-url` types used in structure fields or
  56. /// tuple members with `#[serde(serialize_with = "url_serde::serialize")]`.
  57. pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
  58. where S: Serializer, for<'a> Ser<'a, T>: Serialize
  59. {
  60. Ser::new(value).serialize(serializer)
  61. }
  62. /// A wrapper to serialize `rust-url` types.
  63. ///
  64. /// This is useful with functions such as `serde_json::to_string`.
  65. ///
  66. /// Values of this type can only be passed to the `serde::Serialize` trait.
  67. #[derive(Debug)]
  68. pub struct Ser<'a, T: 'a>(&'a T);
  69. impl<'a, T> Ser<'a, T> where Ser<'a, T>: Serialize {
  70. /// Returns a new `Ser` wrapper.
  71. #[inline(always)]
  72. pub fn new(value: &'a T) -> Self {
  73. Ser(value)
  74. }
  75. }
  76. /// Serializes this URL into a `serde` stream.
  77. impl<'a> Serialize for Ser<'a, Url> {
  78. fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
  79. serializer.serialize_str(self.0.as_str())
  80. }
  81. }
  82. /// Serializes this Option<URL> into a `serde` stream.
  83. impl<'a> Serialize for Ser<'a, Option<Url>> {
  84. fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
  85. if let Some(url) = self.0.as_ref() {
  86. serializer.serialize_some(url.as_str())
  87. } else {
  88. serializer.serialize_none()
  89. }
  90. }
  91. }
  92. impl<'a, String> Serialize for Ser<'a, Host<String>> where String: AsRef<str> {
  93. fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
  94. match *self.0 {
  95. Host::Domain(ref s) => serializer.serialize_str(s.as_ref()),
  96. Host::Ipv4(_) | Host::Ipv6(_) => {
  97. // max("101.102.103.104".len(),
  98. // "[1000:1002:1003:1004:1005:1006:101.102.103.104]".len())
  99. const MAX_LEN: usize = 47;
  100. let mut buffer = [0; MAX_LEN];
  101. serializer.serialize_str(display_into_buffer(&self.0, &mut buffer))
  102. }
  103. }
  104. }
  105. }
  106. /// Like .to_string(), but doesn’t allocate memory for a `String`.
  107. ///
  108. /// Panics if `buffer` is too small.
  109. fn display_into_buffer<'a, T: fmt::Display>(value: &T, buffer: &'a mut [u8]) -> &'a str {
  110. let remaining_len;
  111. {
  112. let mut remaining = &mut *buffer;
  113. write!(remaining, "{}", value).unwrap();
  114. remaining_len = remaining.len()
  115. }
  116. let written_len = buffer.len() - remaining_len;
  117. let written = &buffer[..written_len];
  118. // write! only provides std::fmt::Formatter to Display implementations,
  119. // which has methods write_str and write_char but no method to write arbitrary bytes.
  120. // Therefore, `written` is well-formed in UTF-8.
  121. #[allow(unsafe_code)]
  122. unsafe {
  123. str::from_utf8_unchecked(written)
  124. }
  125. }
  126. /// Deserialises a `T` value with a given deserializer.
  127. ///
  128. /// This is useful to deserialize Url types used in structure fields or
  129. /// tuple members with `#[serde(deserialize_with = "url_serde::deserialize")]`.
  130. pub fn deserialize<T, D>(deserializer: D) -> Result<T, D::Error>
  131. where D: Deserializer, De<T>: Deserialize
  132. {
  133. De::deserialize(deserializer).map(De::into_inner)
  134. }
  135. /// A wrapper to deserialize `rust-url` types.
  136. ///
  137. /// This is useful with functions such as `serde_json::from_str`.
  138. ///
  139. /// Values of this type can only be obtained through
  140. /// the `serde::Deserialize` trait.
  141. #[derive(Debug)]
  142. pub struct De<T>(T);
  143. impl<T> De<T> where De<T>: serde::Deserialize {
  144. /// Consumes this wrapper, returning the deserialized value.
  145. #[inline(always)]
  146. pub fn into_inner(self) -> T {
  147. self.0
  148. }
  149. }
  150. /// Deserializes this URL from a `serde` stream.
  151. impl Deserialize for De<Url> {
  152. fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer {
  153. let string_representation: String = Deserialize::deserialize(deserializer)?;
  154. Url::parse(&string_representation).map(De).map_err(|err| {
  155. serde::de::Error::custom(err.description())
  156. })
  157. }
  158. }
  159. /// Deserializes this Option<URL> from a `serde` stream.
  160. impl Deserialize for De<Option<Url>> {
  161. fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer {
  162. let option_representation: Option<String> = Deserialize::deserialize(deserializer)?;
  163. if let Some(s) = option_representation {
  164. return Url::parse(&s)
  165. .map(Some)
  166. .map(De)
  167. .map_err(|err| {serde::de::Error::custom(err.description())});
  168. }
  169. Ok(De(None))
  170. }
  171. }
  172. impl Deserialize for De<Host> {
  173. fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer {
  174. let string_representation: String = Deserialize::deserialize(deserializer)?;
  175. Host::parse(&string_representation).map(De).map_err(|err| {
  176. serde::de::Error::custom(err.description())
  177. })
  178. }
  179. }
  180. /// A convenience wrapper to be used as a type parameter, for example when
  181. /// a `Vec<T>` or an `HashMap<K, V>` need to be passed to serde.
  182. #[derive(Clone, Eq, Hash, PartialEq)]
  183. pub struct Serde<T>(pub T)
  184. where De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize;
  185. /// A convenience type alias for Serde<Url>.
  186. pub type SerdeUrl = Serde<Url>;
  187. impl<T> Serde<T>
  188. where De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize
  189. {
  190. /// Consumes this wrapper, returning the inner value.
  191. #[inline(always)]
  192. pub fn into_inner(self) -> T {
  193. self.0
  194. }
  195. }
  196. impl<T> fmt::Debug for Serde<T>
  197. where T: fmt::Debug, De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize
  198. {
  199. fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
  200. self.0.fmt(formatter)
  201. }
  202. }
  203. impl<T> Deref for Serde<T>
  204. where De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize
  205. {
  206. type Target = T;
  207. fn deref(&self) -> &T {
  208. &self.0
  209. }
  210. }
  211. impl<T> DerefMut for Serde<T>
  212. where De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize
  213. {
  214. fn deref_mut(&mut self) -> &mut T {
  215. &mut self.0
  216. }
  217. }
  218. impl<T: PartialEq> PartialEq<T> for Serde<T>
  219. where De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize
  220. {
  221. fn eq(&self, other: &T) -> bool {
  222. self.0 == *other
  223. }
  224. }
  225. impl<T> Deserialize for Serde<T>
  226. where De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize
  227. {
  228. fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  229. where D: Deserializer
  230. {
  231. De::deserialize(deserializer).map(De::into_inner).map(Serde)
  232. }
  233. }
  234. impl<T> Serialize for Serde<T>
  235. where De<T>: Deserialize, for<'a> Ser<'a, T>: Serialize
  236. {
  237. fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
  238. where S: Serializer
  239. {
  240. Ser(&self.0).serialize(serializer)
  241. }
  242. }
  243. #[test]
  244. fn test_ser_de_url() {
  245. let url = Url::parse("http://www.test.com/foo/bar?$param=bazz").unwrap();
  246. let s = serde_json::to_string(&Ser::new(&url)).unwrap();
  247. let new_url: Url = serde_json::from_str(&s).map(De::into_inner).unwrap();
  248. assert_eq!(url, new_url);
  249. }
  250. #[test]
  251. fn test_derive_deserialize_with_for_url() {
  252. #[derive(Deserialize, Debug, Eq, PartialEq)]
  253. struct Test {
  254. #[serde(deserialize_with = "deserialize", rename = "_url_")]
  255. url: Url
  256. }
  257. let url_str = "http://www.test.com/foo/bar?$param=bazz";
  258. let expected = Test {
  259. url: Url::parse(url_str).unwrap()
  260. };
  261. let json_string = format!(r#"{{"_url_": "{}"}}"#, url_str);
  262. let got: Test = serde_json::from_str(&json_string).unwrap();
  263. assert_eq!(expected, got);
  264. }
  265. #[test]
  266. fn test_derive_deserialize_with_for_option_url() {
  267. #[derive(Deserialize, Debug, Eq, PartialEq)]
  268. struct Test {
  269. #[serde(deserialize_with = "deserialize", rename = "_url_")]
  270. url: Option<Url>
  271. }
  272. let url_str = "http://www.test.com/foo/bar?$param=bazz";
  273. let expected = Test {
  274. url: Some(Url::parse(url_str).unwrap())
  275. };
  276. let json_string = format!(r#"{{"_url_": "{}"}}"#, url_str);
  277. let got: Test = serde_json::from_str(&json_string).unwrap();
  278. assert_eq!(expected, got);
  279. let expected = Test {
  280. url: None
  281. };
  282. let json_string = r#"{"_url_": null}"#;
  283. let got: Test = serde_json::from_str(&json_string).unwrap();
  284. assert_eq!(expected, got);
  285. }
  286. #[test]
  287. fn test_derive_serialize_with_for_url() {
  288. #[derive(Serialize, Debug, Eq, PartialEq)]
  289. struct Test {
  290. #[serde(serialize_with = "serialize", rename = "_url_")]
  291. url: Url
  292. }
  293. let url_str = "http://www.test.com/foo/bar?$param=bazz";
  294. let expected = format!(r#"{{"_url_":"{}"}}"#, url_str);
  295. let input = Test {url: Url::parse(url_str).unwrap()};
  296. let got = serde_json::to_string(&input).unwrap();
  297. assert_eq!(expected, got);
  298. }
  299. #[test]
  300. fn test_derive_serialize_with_for_option_url() {
  301. #[derive(Serialize, Debug, Eq, PartialEq)]
  302. struct Test {
  303. #[serde(serialize_with = "serialize", rename = "_url_")]
  304. url: Option<Url>
  305. }
  306. let url_str = "http://www.test.com/foo/bar?$param=bazz";
  307. let expected = format!(r#"{{"_url_":"{}"}}"#, url_str);
  308. let input = Test {url: Some(Url::parse(url_str).unwrap())};
  309. let got = serde_json::to_string(&input).unwrap();
  310. assert_eq!(expected, got);
  311. let expected = format!(r#"{{"_url_":null}}"#);
  312. let input = Test {url: None};
  313. let got = serde_json::to_string(&input).unwrap();
  314. assert_eq!(expected, got);
  315. }
  316. #[test]
  317. fn test_host() {
  318. for host in &[
  319. Host::Domain("foo.com".to_owned()),
  320. Host::Ipv4("127.0.0.1".parse().unwrap()),
  321. Host::Ipv6("::1".parse().unwrap()),
  322. ] {
  323. let json = serde_json::to_string(&Ser(host)).unwrap();
  324. let de: De<Host> = serde_json::from_str(&json).unwrap();
  325. assert_eq!(de.into_inner(), *host)
  326. }
  327. }