lib.rs 12 KB

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