uuid/external/
serde_support.rs

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