• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013-2014 The Rust Project Developers.
2 // Copyright 2018 The Uuid Project Developers.
3 //
4 // See the COPYRIGHT file at the top-level directory of this distribution.
5 //
6 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
7 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
8 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
9 // option. This file may not be copied, modified, or distributed
10 // except according to those terms.
11 
12 use crate::{
13     convert::TryFrom,
14     error::*,
15     fmt::{Braced, Hyphenated, Simple, Urn},
16     non_nil::NonNilUuid,
17     std::fmt,
18     Uuid,
19 };
20 use serde::{
21     de::{self, Error as _},
22     Deserialize, Deserializer, Serialize, Serializer,
23 };
24 
25 impl Serialize for Uuid {
serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>26     fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
27         if serializer.is_human_readable() {
28             serializer.serialize_str(self.hyphenated().encode_lower(&mut Uuid::encode_buffer()))
29         } else {
30             serializer.serialize_bytes(self.as_bytes())
31         }
32     }
33 }
34 
35 impl Serialize for NonNilUuid {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer,36     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
37     where
38         S: serde::Serializer,
39     {
40         Uuid::from(*self).serialize(serializer)
41     }
42 }
43 
44 impl Serialize for Hyphenated {
serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>45     fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
46         serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
47     }
48 }
49 
50 impl Serialize for Simple {
serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>51     fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
52         serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
53     }
54 }
55 
56 impl Serialize for Urn {
serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>57     fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
58         serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
59     }
60 }
61 
62 impl Serialize for Braced {
serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>63     fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
64         serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
65     }
66 }
67 
68 impl<'de> Deserialize<'de> for Uuid {
deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>69     fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
70         fn de_error<E: de::Error>(e: Error) -> E {
71             E::custom(format_args!("UUID parsing failed: {}", e))
72         }
73 
74         if deserializer.is_human_readable() {
75             struct UuidVisitor;
76 
77             impl<'vi> de::Visitor<'vi> for UuidVisitor {
78                 type Value = Uuid;
79 
80                 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
81                     write!(formatter, "a UUID string")
82                 }
83 
84                 fn visit_str<E: de::Error>(self, value: &str) -> Result<Uuid, E> {
85                     value.parse::<Uuid>().map_err(de_error)
86                 }
87 
88                 fn visit_bytes<E: de::Error>(self, value: &[u8]) -> Result<Uuid, E> {
89                     Uuid::from_slice(value).map_err(de_error)
90                 }
91 
92                 fn visit_seq<A>(self, mut seq: A) -> Result<Uuid, A::Error>
93                 where
94                     A: de::SeqAccess<'vi>,
95                 {
96                     #[rustfmt::skip]
97                     let bytes = [
98                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(0, &self)) },
99                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(1, &self)) },
100                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(2, &self)) },
101                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(3, &self)) },
102                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(4, &self)) },
103                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(5, &self)) },
104                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(6, &self)) },
105                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(7, &self)) },
106                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(8, &self)) },
107                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(9, &self)) },
108                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(10, &self)) },
109                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(11, &self)) },
110                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(12, &self)) },
111                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(13, &self)) },
112                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(14, &self)) },
113                         match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(15, &self)) },
114                     ];
115 
116                     Ok(Uuid::from_bytes(bytes))
117                 }
118             }
119 
120             deserializer.deserialize_str(UuidVisitor)
121         } else {
122             struct UuidBytesVisitor;
123 
124             impl<'vi> de::Visitor<'vi> for UuidBytesVisitor {
125                 type Value = Uuid;
126 
127                 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
128                     write!(formatter, "bytes")
129                 }
130 
131                 fn visit_bytes<E: de::Error>(self, value: &[u8]) -> Result<Uuid, E> {
132                     Uuid::from_slice(value).map_err(de_error)
133                 }
134             }
135 
136             deserializer.deserialize_bytes(UuidBytesVisitor)
137         }
138     }
139 }
140 
141 impl<'de> Deserialize<'de> for NonNilUuid {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de>,142     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
143     where
144         D: serde::Deserializer<'de>,
145     {
146         let uuid = Uuid::deserialize(deserializer)?;
147 
148         NonNilUuid::try_from(uuid).map_err(|_| de::Error::invalid_value(de::Unexpected::Other("nil UUID"), &"a non-nil UUID"))
149     }
150 }
151 
152 enum ExpectedFormat {
153     Simple,
154     Braced,
155     Urn,
156 }
157 
158 impl std::fmt::Display for ExpectedFormat {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result159     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160         let s = match self {
161             ExpectedFormat::Simple => "a simple Uuid string like 67e5504410b1426f9247bb680e5fe0c8",
162             ExpectedFormat::Braced => {
163                 "a braced Uuid string like {67e55044-10b1-426f-9247-bb680e5fe0c8}"
164             }
165             ExpectedFormat::Urn => {
166                 "a URN Uuid string like urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8"
167             }
168         };
169         f.write_str(s)
170     }
171 }
172 
173 impl de::Expected for ExpectedFormat {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result174     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
175         <ExpectedFormat as std::fmt::Display>::fmt(self, formatter)
176     }
177 }
178 
179 pub mod compact {
180     //! Serialize a [`Uuid`] as a `[u8; 16]`.
181     //!
182     //! [`Uuid`]: ../../struct.Uuid.html
183 
184     /// Serialize from a [`Uuid`] as a `[u8; 16]`
185     ///
186     /// [`Uuid`]: ../../struct.Uuid.html
serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer,187     pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
188     where
189         S: serde::Serializer,
190     {
191         serde::Serialize::serialize(u.as_bytes(), serializer)
192     }
193 
194     /// Deserialize a `[u8; 16]` as a [`Uuid`]
195     ///
196     /// [`Uuid`]: ../../struct.Uuid.html
deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error> where D: serde::Deserializer<'de>,197     pub fn deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error>
198     where
199         D: serde::Deserializer<'de>,
200     {
201         let bytes: [u8; 16] = serde::Deserialize::deserialize(deserializer)?;
202 
203         Ok(crate::Uuid::from_bytes(bytes))
204     }
205 
206     #[cfg(test)]
207     mod tests {
208         use serde_derive::*;
209         use serde_test::Configure;
210 
211         #[test]
test_serialize_compact()212         fn test_serialize_compact() {
213             #[derive(Serialize, Debug, Deserialize, PartialEq)]
214             struct UuidContainer {
215                 #[serde(with = "crate::serde::compact")]
216                 u: crate::Uuid,
217             }
218 
219             let uuid_bytes = b"F9168C5E-CEB2-4F";
220             let container = UuidContainer {
221                 u: crate::Uuid::from_slice(uuid_bytes).unwrap(),
222             };
223 
224             // more complex because of the struct wrapping the actual UUID
225             // serialization
226             serde_test::assert_tokens(
227                 &container.compact(),
228                 &[
229                     serde_test::Token::Struct {
230                         name: "UuidContainer",
231                         len: 1,
232                     },
233                     serde_test::Token::Str("u"),
234                     serde_test::Token::Tuple { len: 16 },
235                     serde_test::Token::U8(uuid_bytes[0]),
236                     serde_test::Token::U8(uuid_bytes[1]),
237                     serde_test::Token::U8(uuid_bytes[2]),
238                     serde_test::Token::U8(uuid_bytes[3]),
239                     serde_test::Token::U8(uuid_bytes[4]),
240                     serde_test::Token::U8(uuid_bytes[5]),
241                     serde_test::Token::U8(uuid_bytes[6]),
242                     serde_test::Token::U8(uuid_bytes[7]),
243                     serde_test::Token::U8(uuid_bytes[8]),
244                     serde_test::Token::U8(uuid_bytes[9]),
245                     serde_test::Token::U8(uuid_bytes[10]),
246                     serde_test::Token::U8(uuid_bytes[11]),
247                     serde_test::Token::U8(uuid_bytes[12]),
248                     serde_test::Token::U8(uuid_bytes[13]),
249                     serde_test::Token::U8(uuid_bytes[14]),
250                     serde_test::Token::U8(uuid_bytes[15]),
251                     serde_test::Token::TupleEnd,
252                     serde_test::Token::StructEnd,
253                 ],
254             )
255         }
256     }
257 }
258 
259 /// Serialize from a [`Uuid`] as a `uuid::fmt::Simple`
260 ///
261 /// [`Uuid`]: ../../struct.Uuid.html
262 ///
263 /// ## Example
264 ///
265 /// ```rust
266 /// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
267 /// struct StructA {
268 ///     // This will change both serailization and deserialization
269 ///     #[serde(with = "uuid::serde::simple")]
270 ///     id: uuid::Uuid,
271 /// }
272 ///
273 /// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
274 /// struct StructB {
275 ///     // This will be serialized as uuid::fmt::Simple and deserialize from all valid formats
276 ///     #[serde(serialize_with = "uuid::serde::simple::serialize")]
277 ///     id: uuid::Uuid,
278 /// }
279 /// ```
280 pub mod simple {
281     use serde::{de, Deserialize};
282 
283     use crate::{parser::parse_simple, Uuid};
284 
285     use super::ExpectedFormat;
286 
287     /// Serialize from a [`Uuid`] as a `uuid::fmt::Simple`
288     ///
289     /// [`Uuid`]: ../../struct.Uuid.html
290     ///
291     /// # Example
292     ///
293     /// ```rust
294     /// #[derive(serde_derive::Serialize)]
295     /// struct Struct {
296     ///     // This will be serialize as uuid::fmt::Simple
297     ///     #[serde(serialize_with = "uuid::serde::simple::serialize")]
298     ///     id: uuid::Uuid,
299     /// }
300     ///
301     /// ```
serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer,302     pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
303     where
304         S: serde::Serializer,
305     {
306         serde::Serialize::serialize(u.as_simple(), serializer)
307     }
308 
309     /// Deserialize a simple Uuid string as a [`Uuid`]
310     ///
311     /// [`Uuid`]: ../../struct.Uuid.html
deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error> where D: serde::Deserializer<'de>,312     pub fn deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error>
313     where
314         D: serde::Deserializer<'de>,
315     {
316         let s = <&str as Deserialize>::deserialize(deserializer)?;
317         let bytes = parse_simple(s.as_bytes()).map_err(|_| {
318             de::Error::invalid_value(de::Unexpected::Str(s), &ExpectedFormat::Simple)
319         })?;
320         Ok(Uuid::from_bytes(bytes))
321     }
322 
323     #[cfg(test)]
324     mod tests {
325         use serde::de::{self, Error};
326         use serde_test::{Readable, Token};
327 
328         use crate::{external::serde_support::ExpectedFormat, Uuid};
329 
330         const HYPHENATED_UUID_STR: &'static str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
331         const SIMPLE_UUID_STR: &'static str = "f9168c5eceb24faab6bf329bf39fa1e4";
332 
333         #[test]
test_serialize_as_simple()334         fn test_serialize_as_simple() {
335             #[derive(serde_derive::Serialize)]
336             struct Struct(#[serde(with = "super")] crate::Uuid);
337 
338             let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
339             serde_test::assert_ser_tokens(
340                 &u,
341                 &[
342                     Token::NewtypeStruct { name: "Struct" },
343                     Token::Str(SIMPLE_UUID_STR),
344                 ],
345             );
346         }
347 
348         #[test]
test_de_from_simple()349         fn test_de_from_simple() {
350             #[derive(PartialEq, Debug, serde_derive::Deserialize)]
351             struct Struct(#[serde(with = "super")] crate::Uuid);
352             let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
353             serde_test::assert_de_tokens::<Struct>(
354                 &s,
355                 &[
356                     Token::TupleStruct {
357                         name: "Struct",
358                         len: 1,
359                     },
360                     Token::BorrowedStr(SIMPLE_UUID_STR),
361                     Token::TupleStructEnd,
362                 ],
363             );
364         }
365 
366         #[test]
test_de_reject_hypenated()367         fn test_de_reject_hypenated() {
368             #[derive(PartialEq, Debug, serde_derive::Deserialize)]
369             struct Struct(#[serde(with = "super")] crate::Uuid);
370             serde_test::assert_de_tokens_error::<Readable<Struct>>(
371                 &[
372                     Token::TupleStruct {
373                         name: "Struct",
374                         len: 1,
375                     },
376                     Token::BorrowedStr(HYPHENATED_UUID_STR),
377                     Token::TupleStructEnd,
378                 ],
379                 &format!(
380                     "{}",
381                     de::value::Error::invalid_value(
382                         de::Unexpected::Str(HYPHENATED_UUID_STR),
383                         &ExpectedFormat::Simple,
384                     )
385                 ),
386             );
387         }
388     }
389 }
390 
391 /// Serialize from a [`Uuid`] as a `uuid::fmt::Braced`
392 ///
393 /// [`Uuid`]: ../../struct.Uuid.html
394 ///
395 /// ## Example
396 ///
397 /// ```rust
398 /// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
399 /// struct StructA {
400 ///     // This will change both serailization and deserialization
401 ///     #[serde(with = "uuid::serde::braced")]
402 ///     id: uuid::Uuid,
403 /// }
404 ///
405 /// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
406 /// struct StructB {
407 ///     // This will be serialized as uuid::fmt::Urn and deserialize from all valid formats
408 ///     #[serde(serialize_with = "uuid::serde::braced::serialize")]
409 ///     id: uuid::Uuid,
410 /// }
411 /// ```
412 pub mod braced {
413     use serde::{de, Deserialize};
414 
415     use crate::parser::parse_braced;
416 
417     use super::ExpectedFormat;
418 
419     /// Serialize from a [`Uuid`] as a `uuid::fmt::Braced`
420     ///
421     /// [`Uuid`]: ../../struct.Uuid.html
422     ///
423     /// # Example
424     ///
425     /// ```rust
426     /// #[derive(serde_derive::Serialize)]
427     /// struct Struct {
428     ///     // This will be serialize as uuid::fmt::Braced
429     ///     #[serde(serialize_with = "uuid::serde::braced::serialize")]
430     ///     id: uuid::Uuid,
431     /// }
432     ///
433     /// ```
serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer,434     pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
435     where
436         S: serde::Serializer,
437     {
438         serde::Serialize::serialize(u.as_braced(), serializer)
439     }
440 
441     /// Deserialize a braced Uuid string as a [`Uuid`]
442     ///
443     /// [`Uuid`]: ../../struct.Uuid.html
deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error> where D: serde::Deserializer<'de>,444     pub fn deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error>
445     where
446         D: serde::Deserializer<'de>,
447     {
448         let s = <&str as Deserialize>::deserialize(deserializer)?;
449         let bytes = parse_braced(s.as_bytes()).map_err(|_| {
450             de::Error::invalid_value(de::Unexpected::Str(s), &ExpectedFormat::Braced)
451         })?;
452         Ok(crate::Uuid::from_bytes(bytes))
453     }
454 
455     #[cfg(test)]
456     mod tests {
457         use serde::de::{self, Error};
458         use serde_test::{Readable, Token};
459 
460         use crate::{external::serde_support::ExpectedFormat, Uuid};
461 
462         const HYPHENATED_UUID_STR: &'static str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
463         const BRACED_UUID_STR: &'static str = "{f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4}";
464 
465         #[test]
test_serialize_as_braced()466         fn test_serialize_as_braced() {
467             #[derive(serde_derive::Serialize)]
468             struct Struct(#[serde(with = "super")] crate::Uuid);
469 
470             let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
471             serde_test::assert_ser_tokens(
472                 &u,
473                 &[
474                     Token::NewtypeStruct { name: "Struct" },
475                     Token::Str(BRACED_UUID_STR),
476                 ],
477             );
478         }
479 
480         #[test]
test_de_from_braced()481         fn test_de_from_braced() {
482             #[derive(PartialEq, Debug, serde_derive::Deserialize)]
483             struct Struct(#[serde(with = "super")] crate::Uuid);
484             let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
485             serde_test::assert_de_tokens::<Struct>(
486                 &s,
487                 &[
488                     Token::TupleStruct {
489                         name: "Struct",
490                         len: 1,
491                     },
492                     Token::BorrowedStr(BRACED_UUID_STR),
493                     Token::TupleStructEnd,
494                 ],
495             );
496         }
497 
498         #[test]
test_de_reject_hypenated()499         fn test_de_reject_hypenated() {
500             #[derive(PartialEq, Debug, serde_derive::Deserialize)]
501             struct Struct(#[serde(with = "super")] crate::Uuid);
502             serde_test::assert_de_tokens_error::<Readable<Struct>>(
503                 &[
504                     Token::TupleStruct {
505                         name: "Struct",
506                         len: 1,
507                     },
508                     Token::BorrowedStr(HYPHENATED_UUID_STR),
509                     Token::TupleStructEnd,
510                 ],
511                 &format!(
512                     "{}",
513                     de::value::Error::invalid_value(
514                         de::Unexpected::Str(HYPHENATED_UUID_STR),
515                         &ExpectedFormat::Braced,
516                     )
517                 ),
518             );
519         }
520     }
521 }
522 
523 /// Serialize from a [`Uuid`] as a `uuid::fmt::Urn`
524 ///
525 /// [`Uuid`]: ../../struct.Uuid.html
526 ///
527 /// ## Example
528 ///
529 /// ```rust
530 /// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
531 /// struct StructA {
532 ///     // This will change both serailization and deserialization
533 ///     #[serde(with = "uuid::serde::urn")]
534 ///     id: uuid::Uuid,
535 /// }
536 ///
537 /// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
538 /// struct StructB {
539 ///     // This will be serialized as uuid::fmt::Urn and deserialize from all valid formats
540 ///     #[serde(serialize_with = "uuid::serde::urn::serialize")]
541 ///     id: uuid::Uuid,
542 /// }
543 /// ```
544 pub mod urn {
545     use serde::{de, Deserialize};
546 
547     use crate::parser::parse_urn;
548 
549     use super::ExpectedFormat;
550 
551     /// Serialize from a [`Uuid`] as a `uuid::fmt::Urn`
552     ///
553     /// [`Uuid`]: ../../struct.Uuid.html
554     ///
555     /// # Example
556     ///
557     /// ```rust
558     /// #[derive(serde_derive::Serialize)]
559     /// struct Struct {
560     ///     // This will be serialize as uuid::fmt::Urn
561     ///     #[serde(serialize_with = "uuid::serde::urn::serialize")]
562     ///     id: uuid::Uuid,
563     /// }
564     ///
565     /// ```
serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer,566     pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
567     where
568         S: serde::Serializer,
569     {
570         serde::Serialize::serialize(u.as_urn(), serializer)
571     }
572 
573     /// Deserialize a urn Uuid string as a [`Uuid`]
574     ///
575     /// [`Uuid`]: ../../struct.Uuid.html
deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error> where D: serde::Deserializer<'de>,576     pub fn deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error>
577     where
578         D: serde::Deserializer<'de>,
579     {
580         let s = <&str as Deserialize>::deserialize(deserializer)?;
581         let bytes = parse_urn(s.as_bytes())
582             .map_err(|_| de::Error::invalid_value(de::Unexpected::Str(s), &ExpectedFormat::Urn))?;
583         Ok(crate::Uuid::from_bytes(bytes))
584     }
585 
586     #[cfg(test)]
587     mod tests {
588         use serde::de::{self, Error};
589         use serde_test::{Readable, Token};
590 
591         use crate::{external::serde_support::ExpectedFormat, Uuid};
592 
593         const HYPHENATED_UUID_STR: &'static str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
594         const URN_UUID_STR: &'static str = "urn:uuid:f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
595 
596         #[test]
test_serialize_as_urn()597         fn test_serialize_as_urn() {
598             #[derive(serde_derive::Serialize)]
599             struct Struct(#[serde(with = "super")] crate::Uuid);
600 
601             let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
602             serde_test::assert_ser_tokens(
603                 &u,
604                 &[
605                     Token::NewtypeStruct { name: "Struct" },
606                     Token::Str(URN_UUID_STR),
607                 ],
608             );
609         }
610 
611         #[test]
test_de_from_urn()612         fn test_de_from_urn() {
613             #[derive(PartialEq, Debug, serde_derive::Deserialize)]
614             struct Struct(#[serde(with = "super")] crate::Uuid);
615             let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
616             serde_test::assert_de_tokens::<Struct>(
617                 &s,
618                 &[
619                     Token::TupleStruct {
620                         name: "Struct",
621                         len: 1,
622                     },
623                     Token::BorrowedStr(URN_UUID_STR),
624                     Token::TupleStructEnd,
625                 ],
626             );
627         }
628 
629         #[test]
test_de_reject_hypenated()630         fn test_de_reject_hypenated() {
631             #[derive(PartialEq, Debug, serde_derive::Deserialize)]
632             struct Struct(#[serde(with = "super")] crate::Uuid);
633             serde_test::assert_de_tokens_error::<Readable<Struct>>(
634                 &[
635                     Token::TupleStruct {
636                         name: "Struct",
637                         len: 1,
638                     },
639                     Token::BorrowedStr(HYPHENATED_UUID_STR),
640                     Token::TupleStructEnd,
641                 ],
642                 &format!(
643                     "{}",
644                     de::value::Error::invalid_value(
645                         de::Unexpected::Str(HYPHENATED_UUID_STR),
646                         &ExpectedFormat::Urn,
647                     )
648                 ),
649             );
650         }
651     }
652 }
653 
654 #[cfg(test)]
655 mod serde_tests {
656     use super::*;
657 
658     use serde_test::{Compact, Configure, Readable, Token};
659 
660     #[test]
test_serialize_readable_string()661     fn test_serialize_readable_string() {
662         let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
663         let u = Uuid::parse_str(uuid_str).unwrap();
664         serde_test::assert_tokens(&u.readable(), &[Token::Str(uuid_str)]);
665     }
666 
667     #[test]
test_deserialize_readable_compact()668     fn test_deserialize_readable_compact() {
669         let uuid_bytes = b"F9168C5E-CEB2-4F";
670         let u = Uuid::from_slice(uuid_bytes).unwrap();
671 
672         serde_test::assert_de_tokens(
673             &u.readable(),
674             &[
675                 serde_test::Token::Tuple { len: 16 },
676                 serde_test::Token::U8(uuid_bytes[0]),
677                 serde_test::Token::U8(uuid_bytes[1]),
678                 serde_test::Token::U8(uuid_bytes[2]),
679                 serde_test::Token::U8(uuid_bytes[3]),
680                 serde_test::Token::U8(uuid_bytes[4]),
681                 serde_test::Token::U8(uuid_bytes[5]),
682                 serde_test::Token::U8(uuid_bytes[6]),
683                 serde_test::Token::U8(uuid_bytes[7]),
684                 serde_test::Token::U8(uuid_bytes[8]),
685                 serde_test::Token::U8(uuid_bytes[9]),
686                 serde_test::Token::U8(uuid_bytes[10]),
687                 serde_test::Token::U8(uuid_bytes[11]),
688                 serde_test::Token::U8(uuid_bytes[12]),
689                 serde_test::Token::U8(uuid_bytes[13]),
690                 serde_test::Token::U8(uuid_bytes[14]),
691                 serde_test::Token::U8(uuid_bytes[15]),
692                 serde_test::Token::TupleEnd,
693             ],
694         );
695     }
696 
697     #[test]
test_deserialize_readable_bytes()698     fn test_deserialize_readable_bytes() {
699         let uuid_bytes = b"F9168C5E-CEB2-4F";
700         let u = Uuid::from_slice(uuid_bytes).unwrap();
701 
702         serde_test::assert_de_tokens(&u.readable(), &[serde_test::Token::Bytes(uuid_bytes)]);
703     }
704 
705     #[test]
test_serialize_hyphenated()706     fn test_serialize_hyphenated() {
707         let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
708         let u = Uuid::parse_str(uuid_str).unwrap();
709         serde_test::assert_ser_tokens(&u.hyphenated(), &[Token::Str(uuid_str)]);
710     }
711 
712     #[test]
test_serialize_simple()713     fn test_serialize_simple() {
714         let uuid_str = "f9168c5eceb24faab6bf329bf39fa1e4";
715         let u = Uuid::parse_str(uuid_str).unwrap();
716         serde_test::assert_ser_tokens(&u.simple(), &[Token::Str(uuid_str)]);
717     }
718 
719     #[test]
test_serialize_urn()720     fn test_serialize_urn() {
721         let uuid_str = "urn:uuid:f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
722         let u = Uuid::parse_str(uuid_str).unwrap();
723         serde_test::assert_ser_tokens(&u.urn(), &[Token::Str(uuid_str)]);
724     }
725 
726     #[test]
test_serialize_braced()727     fn test_serialize_braced() {
728         let uuid_str = "{f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4}";
729         let u = Uuid::parse_str(uuid_str).unwrap();
730         serde_test::assert_ser_tokens(&u.braced(), &[Token::Str(uuid_str)]);
731     }
732 
733     #[test]
test_serialize_non_human_readable()734     fn test_serialize_non_human_readable() {
735         let uuid_bytes = b"F9168C5E-CEB2-4F";
736         let u = Uuid::from_slice(uuid_bytes).unwrap();
737         serde_test::assert_tokens(
738             &u.compact(),
739             &[serde_test::Token::Bytes(&[
740                 70, 57, 49, 54, 56, 67, 53, 69, 45, 67, 69, 66, 50, 45, 52, 70,
741             ])],
742         );
743     }
744 
745     #[test]
test_de_failure()746     fn test_de_failure() {
747         serde_test::assert_de_tokens_error::<Readable<Uuid>>(
748             &[Token::Str("hello_world")],
749             "UUID parsing failed: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-fA-F-], found `h` at 1",
750         );
751 
752         serde_test::assert_de_tokens_error::<Compact<Uuid>>(
753             &[Token::Bytes(b"hello_world")],
754             "UUID parsing failed: invalid length: expected 16 bytes, found 11",
755         );
756     }
757 
758     #[test]
test_serde_non_nil_uuid()759     fn test_serde_non_nil_uuid() {
760         let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
761         let uuid = Uuid::parse_str(uuid_str).unwrap();
762         let non_nil_uuid = NonNilUuid::try_from(uuid).unwrap();
763 
764         serde_test::assert_ser_tokens(&non_nil_uuid.readable(), &[Token::Str(uuid_str)]);
765         serde_test::assert_de_tokens(&non_nil_uuid.readable(), &[Token::Str(uuid_str)]);
766     }
767 }
768