1use core::marker::PhantomData;
13
14use crate::{
15 error::*,
16 fmt::{Braced, Hyphenated, Simple, Urn},
17 non_nil::NonNilUuid,
18 std::fmt,
19 Bytes, Uuid,
20};
21use serde_core::{
22 de::{self, Error as _},
23 Deserialize, Deserializer, Serialize, Serializer,
24};
25
26impl Serialize for Uuid {
27 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
28 if serializer.is_human_readable() {
29 serializer.serialize_str(self.hyphenated().encode_lower(&mut Uuid::encode_buffer()))
30 } else {
31 serializer.serialize_bytes(self.as_bytes())
32 }
33 }
34}
35
36impl Serialize for NonNilUuid {
37 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
38 where
39 S: serde_core::Serializer,
40 {
41 Uuid::from(*self).serialize(serializer)
42 }
43}
44
45impl Serialize for Hyphenated {
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 Simple {
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 Serialize for Urn {
58 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
59 serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
60 }
61}
62
63impl Serialize for Braced {
64 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
65 serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
66 }
67}
68
69struct UuidReadableVisitor<T> {
70 expecting: &'static str,
71 _marker: PhantomData<T>,
72}
73
74impl<'vi, T: UuidDeserialize> de::Visitor<'vi> for UuidReadableVisitor<T> {
75 type Value = T;
76
77 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
78 formatter.write_str(self.expecting)
79 }
80
81 fn visit_str<E: de::Error>(self, value: &str) -> Result<T, E> {
82 T::from_str(value).map_err(de_error)
83 }
84
85 fn visit_bytes<E: de::Error>(self, value: &[u8]) -> Result<T, E> {
86 T::from_slice(value).map_err(de_error)
87 }
88
89 fn visit_seq<A>(self, mut seq: A) -> Result<T, A::Error>
90 where
91 A: de::SeqAccess<'vi>,
92 {
93 #[rustfmt::skip]
94 let bytes = [
95 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(0, &self)) },
96 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(1, &self)) },
97 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(2, &self)) },
98 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(3, &self)) },
99 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(4, &self)) },
100 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(5, &self)) },
101 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(6, &self)) },
102 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(7, &self)) },
103 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(8, &self)) },
104 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(9, &self)) },
105 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(10, &self)) },
106 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(11, &self)) },
107 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(12, &self)) },
108 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(13, &self)) },
109 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(14, &self)) },
110 match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(15, &self)) },
111 ];
112
113 T::from_bytes(bytes).map_err(de_error)
114 }
115}
116
117struct UuidBytesVisitor<T> {
118 _marker: PhantomData<T>,
119}
120
121impl<'vi, T: UuidDeserialize> de::Visitor<'vi> for UuidBytesVisitor<T> {
122 type Value = T;
123
124 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
125 write!(formatter, "a 16 byte array")
126 }
127
128 fn visit_bytes<E: de::Error>(self, value: &[u8]) -> Result<T, E> {
129 T::from_slice(value).map_err(de_error)
130 }
131}
132
133fn de_error<E: de::Error>(e: Error) -> E {
134 E::custom(format_args!("UUID parsing failed: {}", e))
135}
136
137trait UuidDeserialize {
138 fn from_str(formatted: &str) -> Result<Self, Error>
139 where
140 Self: Sized;
141 fn from_slice(bytes: &[u8]) -> Result<Self, Error>
142 where
143 Self: Sized;
144 fn from_bytes(bytes: Bytes) -> Result<Self, Error>
145 where
146 Self: Sized;
147}
148
149impl UuidDeserialize for Uuid {
150 fn from_str(formatted: &str) -> Result<Self, Error> {
151 formatted.parse()
152 }
153
154 fn from_slice(bytes: &[u8]) -> Result<Self, Error> {
155 Uuid::from_slice(bytes)
156 }
157
158 fn from_bytes(bytes: Bytes) -> Result<Self, Error> {
159 Ok(Uuid::from_bytes(bytes))
160 }
161}
162
163impl<'de> Deserialize<'de> for Uuid {
164 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
165 if deserializer.is_human_readable() {
166 deserializer.deserialize_str(UuidReadableVisitor {
167 expecting: "a formatted UUID string",
168 _marker: PhantomData::<Uuid>,
169 })
170 } else {
171 deserializer.deserialize_bytes(UuidBytesVisitor {
172 _marker: PhantomData::<Uuid>,
173 })
174 }
175 }
176}
177
178impl UuidDeserialize for Braced {
179 fn from_str(formatted: &str) -> Result<Self, Error> {
180 formatted.parse()
181 }
182
183 fn from_slice(bytes: &[u8]) -> Result<Self, Error> {
184 Ok(Uuid::from_slice(bytes)?.into())
185 }
186
187 fn from_bytes(bytes: Bytes) -> Result<Self, Error> {
188 Ok(Uuid::from_bytes(bytes).into())
189 }
190}
191
192impl<'de> Deserialize<'de> for Braced {
193 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
194 deserializer.deserialize_str(UuidReadableVisitor {
195 expecting: "a UUID string in the braced format",
196 _marker: PhantomData::<Braced>,
197 })
198 }
199}
200
201impl UuidDeserialize for Hyphenated {
202 fn from_str(formatted: &str) -> Result<Self, Error> {
203 formatted.parse()
204 }
205
206 fn from_slice(bytes: &[u8]) -> Result<Self, Error> {
207 Ok(Uuid::from_slice(bytes)?.into())
208 }
209
210 fn from_bytes(bytes: Bytes) -> Result<Self, Error> {
211 Ok(Uuid::from_bytes(bytes).into())
212 }
213}
214
215impl<'de> Deserialize<'de> for Hyphenated {
216 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
217 deserializer.deserialize_str(UuidReadableVisitor {
218 expecting: "a UUID string in the hyphenated format",
219 _marker: PhantomData::<Hyphenated>,
220 })
221 }
222}
223
224impl UuidDeserialize for Simple {
225 fn from_str(formatted: &str) -> Result<Self, Error> {
226 formatted.parse()
227 }
228
229 fn from_slice(bytes: &[u8]) -> Result<Self, Error> {
230 Ok(Uuid::from_slice(bytes)?.into())
231 }
232
233 fn from_bytes(bytes: Bytes) -> Result<Self, Error> {
234 Ok(Uuid::from_bytes(bytes).into())
235 }
236}
237
238impl<'de> Deserialize<'de> for Simple {
239 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
240 deserializer.deserialize_str(UuidReadableVisitor {
241 expecting: "a UUID string in the simple format",
242 _marker: PhantomData::<Simple>,
243 })
244 }
245}
246
247impl UuidDeserialize for Urn {
248 fn from_str(formatted: &str) -> Result<Self, Error> {
249 formatted.parse()
250 }
251
252 fn from_slice(bytes: &[u8]) -> Result<Self, Error> {
253 Ok(Uuid::from_slice(bytes)?.into())
254 }
255
256 fn from_bytes(bytes: Bytes) -> Result<Self, Error> {
257 Ok(Uuid::from_bytes(bytes).into())
258 }
259}
260
261impl<'de> Deserialize<'de> for Urn {
262 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
263 deserializer.deserialize_str(UuidReadableVisitor {
264 expecting: "a UUID string in the URN format",
265 _marker: PhantomData::<Urn>,
266 })
267 }
268}
269
270impl<'de> Deserialize<'de> for NonNilUuid {
271 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
272 where
273 D: serde_core::Deserializer<'de>,
274 {
275 let uuid = Uuid::deserialize(deserializer)?;
276
277 NonNilUuid::try_from(uuid).map_err(|_| {
278 de::Error::invalid_value(de::Unexpected::Other("nil UUID"), &"a non-nil UUID")
279 })
280 }
281}
282
283pub mod compact {
284 pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
292 where
293 S: serde_core::Serializer,
294 {
295 serde_core::Serialize::serialize(u.as_bytes(), serializer)
296 }
297
298 pub fn deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error>
302 where
303 D: serde_core::Deserializer<'de>,
304 {
305 let bytes: [u8; 16] = serde_core::Deserialize::deserialize(deserializer)?;
306
307 Ok(crate::Uuid::from_bytes(bytes))
308 }
309
310 #[cfg(test)]
311 mod tests {
312 use serde_derive::*;
313 use serde_test::Configure;
314
315 #[test]
316 fn test_serialize_compact() {
317 #[derive(Serialize, Debug, Deserialize, PartialEq)]
318 struct UuidContainer {
319 #[serde(with = "crate::serde::compact")]
320 u: crate::Uuid,
321 }
322
323 let uuid_bytes = b"F9168C5E-CEB2-4F";
324 let container = UuidContainer {
325 u: crate::Uuid::from_slice(uuid_bytes).unwrap(),
326 };
327
328 serde_test::assert_tokens(
331 &container.compact(),
332 &[
333 serde_test::Token::Struct {
334 name: "UuidContainer",
335 len: 1,
336 },
337 serde_test::Token::Str("u"),
338 serde_test::Token::Tuple { len: 16 },
339 serde_test::Token::U8(uuid_bytes[0]),
340 serde_test::Token::U8(uuid_bytes[1]),
341 serde_test::Token::U8(uuid_bytes[2]),
342 serde_test::Token::U8(uuid_bytes[3]),
343 serde_test::Token::U8(uuid_bytes[4]),
344 serde_test::Token::U8(uuid_bytes[5]),
345 serde_test::Token::U8(uuid_bytes[6]),
346 serde_test::Token::U8(uuid_bytes[7]),
347 serde_test::Token::U8(uuid_bytes[8]),
348 serde_test::Token::U8(uuid_bytes[9]),
349 serde_test::Token::U8(uuid_bytes[10]),
350 serde_test::Token::U8(uuid_bytes[11]),
351 serde_test::Token::U8(uuid_bytes[12]),
352 serde_test::Token::U8(uuid_bytes[13]),
353 serde_test::Token::U8(uuid_bytes[14]),
354 serde_test::Token::U8(uuid_bytes[15]),
355 serde_test::Token::TupleEnd,
356 serde_test::Token::StructEnd,
357 ],
358 )
359 }
360 }
361}
362
363pub mod simple {
390 use super::*;
391
392 pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
407 where
408 S: serde_core::Serializer,
409 {
410 serde_core::Serialize::serialize(u.as_simple(), serializer)
411 }
412
413 pub fn deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error>
417 where
418 D: serde_core::Deserializer<'de>,
419 {
420 Ok(Simple::deserialize(deserializer)?.into())
421 }
422
423 #[cfg(test)]
424 mod tests {
425 use serde::de::{self, Error};
426 use serde_test::{Readable, Token};
427
428 use super::*;
429
430 const HYPHENATED_UUID_STR: &str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
431 const SIMPLE_UUID_STR: &str = "f9168c5eceb24faab6bf329bf39fa1e4";
432
433 #[test]
434 fn test_serialize_as_simple() {
435 #[derive(serde_derive::Serialize)]
436 struct Struct(#[serde(with = "super")] crate::Uuid);
437
438 let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
439 serde_test::assert_ser_tokens(
440 &u,
441 &[
442 Token::NewtypeStruct { name: "Struct" },
443 Token::Str(SIMPLE_UUID_STR),
444 ],
445 );
446 }
447
448 #[test]
449 fn test_de_from_simple() {
450 #[derive(PartialEq, Debug, serde_derive::Deserialize)]
451 struct Struct(#[serde(with = "super")] crate::Uuid);
452 let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
453 serde_test::assert_de_tokens::<Struct>(
454 &s,
455 &[
456 Token::TupleStruct {
457 name: "Struct",
458 len: 1,
459 },
460 Token::BorrowedStr(SIMPLE_UUID_STR),
461 Token::TupleStructEnd,
462 ],
463 );
464 }
465
466 #[test]
467 fn test_de_reject_hyphenated() {
468 #[derive(PartialEq, Debug, serde_derive::Deserialize)]
469 struct Struct(#[serde(with = "super")] crate::Uuid);
470 serde_test::assert_de_tokens_error::<Readable<Struct>>(
471 &[
472 Token::TupleStruct {
473 name: "Struct",
474 len: 1,
475 },
476 Token::BorrowedStr(HYPHENATED_UUID_STR),
477 Token::TupleStructEnd,
478 ],
479 &format!(
480 "{}",
481 de::value::Error::custom(
482 "UUID parsing failed: invalid character: found `-` at 8"
483 )
484 ),
485 );
486 }
487 }
488}
489
490pub mod braced {
517 use super::*;
518
519 pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
534 where
535 S: serde_core::Serializer,
536 {
537 serde_core::Serialize::serialize(u.as_braced(), serializer)
538 }
539
540 pub fn deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error>
544 where
545 D: serde_core::Deserializer<'de>,
546 {
547 Ok(Braced::deserialize(deserializer)?.into())
548 }
549
550 #[cfg(test)]
551 mod tests {
552
553 use serde::de::{self, Error};
554 use serde_test::{Readable, Token};
555
556 use super::*;
557
558 const HYPHENATED_UUID_STR: &str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
559 const BRACED_UUID_STR: &str = "{f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4}";
560
561 #[test]
562 fn test_serialize_as_braced() {
563 #[derive(serde_derive::Serialize)]
564 struct Struct(#[serde(with = "super")] crate::Uuid);
565
566 let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
567 serde_test::assert_ser_tokens(
568 &u,
569 &[
570 Token::NewtypeStruct { name: "Struct" },
571 Token::Str(BRACED_UUID_STR),
572 ],
573 );
574 }
575
576 #[test]
577 fn test_de_from_braced() {
578 #[derive(PartialEq, Debug, serde_derive::Deserialize)]
579 struct Struct(#[serde(with = "super")] crate::Uuid);
580 let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
581 serde_test::assert_de_tokens::<Struct>(
582 &s,
583 &[
584 Token::TupleStruct {
585 name: "Struct",
586 len: 1,
587 },
588 Token::BorrowedStr(BRACED_UUID_STR),
589 Token::TupleStructEnd,
590 ],
591 );
592 }
593
594 #[test]
595 fn test_de_reject_hyphenated() {
596 #[derive(PartialEq, Debug, serde_derive::Deserialize)]
597 struct Struct(#[serde(with = "super")] crate::Uuid);
598 serde_test::assert_de_tokens_error::<Readable<Struct>>(
599 &[
600 Token::TupleStruct {
601 name: "Struct",
602 len: 1,
603 },
604 Token::BorrowedStr(HYPHENATED_UUID_STR),
605 Token::TupleStructEnd,
606 ],
607 &format!(
608 "{}",
609 de::value::Error::custom(
610 "UUID parsing failed: invalid character: found `f` at 0"
611 )
612 ),
613 );
614 }
615 }
616}
617
618pub mod hyphenated {
645
646 use super::*;
647
648 pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
663 where
664 S: serde_core::Serializer,
665 {
666 serde_core::Serialize::serialize(u.as_hyphenated(), serializer)
667 }
668
669 pub fn deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error>
673 where
674 D: serde_core::Deserializer<'de>,
675 {
676 Ok(Hyphenated::deserialize(deserializer)?.into())
677 }
678
679 #[cfg(test)]
680 mod tests {
681
682 use serde::de::{self, Error};
683 use serde_test::{Readable, Token};
684
685 use super::*;
686
687 const HYPHENATED_UUID_STR: &str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
688 const BRACED_UUID_STR: &str = "{f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4}";
689
690 #[test]
691 fn test_serialize_as_hyphenated() {
692 #[derive(serde_derive::Serialize)]
693 struct Struct(#[serde(with = "super")] crate::Uuid);
694
695 let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
696 serde_test::assert_ser_tokens(
697 &u,
698 &[
699 Token::NewtypeStruct { name: "Struct" },
700 Token::Str(HYPHENATED_UUID_STR),
701 ],
702 );
703 }
704
705 #[test]
706 fn test_de_from_hyphenated() {
707 #[derive(PartialEq, Debug, serde_derive::Deserialize)]
708 struct Struct(#[serde(with = "super")] crate::Uuid);
709 let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
710 serde_test::assert_de_tokens::<Struct>(
711 &s,
712 &[
713 Token::TupleStruct {
714 name: "Struct",
715 len: 1,
716 },
717 Token::BorrowedStr(HYPHENATED_UUID_STR),
718 Token::TupleStructEnd,
719 ],
720 );
721 }
722
723 #[test]
724 fn test_de_reject_braced() {
725 #[derive(PartialEq, Debug, serde_derive::Deserialize)]
726 struct Struct(#[serde(with = "super")] crate::Uuid);
727 serde_test::assert_de_tokens_error::<Readable<Struct>>(
728 &[
729 Token::TupleStruct {
730 name: "Struct",
731 len: 1,
732 },
733 Token::BorrowedStr(BRACED_UUID_STR),
734 Token::TupleStructEnd,
735 ],
736 &format!(
737 "{}",
738 de::value::Error::custom(
739 "UUID parsing failed: invalid character: found `{` at 0"
740 )
741 ),
742 );
743 }
744 }
745}
746
747pub mod urn {
774 use super::*;
775
776 pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
791 where
792 S: serde_core::Serializer,
793 {
794 serde_core::Serialize::serialize(u.as_urn(), serializer)
795 }
796
797 pub fn deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error>
801 where
802 D: serde_core::Deserializer<'de>,
803 {
804 Ok(Urn::deserialize(deserializer)?.into())
805 }
806
807 #[cfg(test)]
808 mod tests {
809 use serde::de::{self, Error};
810 use serde_test::{Readable, Token};
811
812 use super::*;
813
814 const HYPHENATED_UUID_STR: &str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
815 const URN_UUID_STR: &str = "urn:uuid:f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
816
817 #[test]
818 fn test_serialize_as_urn() {
819 #[derive(serde_derive::Serialize)]
820 struct Struct(#[serde(with = "super")] crate::Uuid);
821
822 let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
823 serde_test::assert_ser_tokens(
824 &u,
825 &[
826 Token::NewtypeStruct { name: "Struct" },
827 Token::Str(URN_UUID_STR),
828 ],
829 );
830 }
831
832 #[test]
833 fn test_de_from_urn() {
834 #[derive(PartialEq, Debug, serde_derive::Deserialize)]
835 struct Struct(#[serde(with = "super")] crate::Uuid);
836 let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
837 serde_test::assert_de_tokens::<Struct>(
838 &s,
839 &[
840 Token::TupleStruct {
841 name: "Struct",
842 len: 1,
843 },
844 Token::BorrowedStr(URN_UUID_STR),
845 Token::TupleStructEnd,
846 ],
847 );
848 }
849
850 #[test]
851 fn test_de_reject_hyphenated() {
852 #[derive(PartialEq, Debug, serde_derive::Deserialize)]
853 struct Struct(#[serde(with = "super")] crate::Uuid);
854 serde_test::assert_de_tokens_error::<Readable<Struct>>(
855 &[
856 Token::TupleStruct {
857 name: "Struct",
858 len: 1,
859 },
860 Token::BorrowedStr(HYPHENATED_UUID_STR),
861 Token::TupleStructEnd,
862 ],
863 &format!(
864 "{}",
865 de::value::Error::custom(
866 "UUID parsing failed: invalid character: found `f` at 0"
867 )
868 ),
869 );
870 }
871 }
872}
873
874#[cfg(test)]
875mod serde_tests {
876 use super::*;
877
878 use serde_test::{Compact, Configure, Readable, Token};
879
880 #[test]
881 fn test_serialize_readable_string() {
882 let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
883 let u = Uuid::parse_str(uuid_str).unwrap();
884 serde_test::assert_tokens(&u.readable(), &[Token::Str(uuid_str)]);
885 }
886
887 #[test]
888 fn test_deserialize_readable_compact() {
889 let uuid_bytes = b"F9168C5E-CEB2-4F";
890 let u = Uuid::from_slice(uuid_bytes).unwrap();
891
892 serde_test::assert_de_tokens(
893 &u.readable(),
894 &[
895 serde_test::Token::Tuple { len: 16 },
896 serde_test::Token::U8(uuid_bytes[0]),
897 serde_test::Token::U8(uuid_bytes[1]),
898 serde_test::Token::U8(uuid_bytes[2]),
899 serde_test::Token::U8(uuid_bytes[3]),
900 serde_test::Token::U8(uuid_bytes[4]),
901 serde_test::Token::U8(uuid_bytes[5]),
902 serde_test::Token::U8(uuid_bytes[6]),
903 serde_test::Token::U8(uuid_bytes[7]),
904 serde_test::Token::U8(uuid_bytes[8]),
905 serde_test::Token::U8(uuid_bytes[9]),
906 serde_test::Token::U8(uuid_bytes[10]),
907 serde_test::Token::U8(uuid_bytes[11]),
908 serde_test::Token::U8(uuid_bytes[12]),
909 serde_test::Token::U8(uuid_bytes[13]),
910 serde_test::Token::U8(uuid_bytes[14]),
911 serde_test::Token::U8(uuid_bytes[15]),
912 serde_test::Token::TupleEnd,
913 ],
914 );
915 }
916
917 #[test]
918 fn test_deserialize_readable_bytes() {
919 let uuid_bytes = b"F9168C5E-CEB2-4F";
920 let u = Uuid::from_slice(uuid_bytes).unwrap();
921
922 serde_test::assert_de_tokens(&u.readable(), &[serde_test::Token::Bytes(uuid_bytes)]);
923 }
924
925 #[test]
926 fn test_serialize_hyphenated() {
927 let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
928 let u = Uuid::parse_str(uuid_str).unwrap();
929 serde_test::assert_ser_tokens(&u.hyphenated(), &[Token::Str(uuid_str)]);
930 serde_test::assert_de_tokens(&u.hyphenated(), &[Token::Str(uuid_str)]);
931 }
932
933 #[test]
934 fn test_serialize_simple() {
935 let uuid_str = "f9168c5eceb24faab6bf329bf39fa1e4";
936 let u = Uuid::parse_str(uuid_str).unwrap();
937 serde_test::assert_ser_tokens(&u.simple(), &[Token::Str(uuid_str)]);
938 serde_test::assert_de_tokens(&u.simple(), &[Token::Str(uuid_str)]);
939 }
940
941 #[test]
942 fn test_serialize_urn() {
943 let uuid_str = "urn:uuid:f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
944 let u = Uuid::parse_str(uuid_str).unwrap();
945 serde_test::assert_ser_tokens(&u.urn(), &[Token::Str(uuid_str)]);
946 serde_test::assert_de_tokens(&u.urn(), &[Token::Str(uuid_str)]);
947 }
948
949 #[test]
950 fn test_serialize_braced() {
951 let uuid_str = "{f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4}";
952 let u = Uuid::parse_str(uuid_str).unwrap();
953 serde_test::assert_ser_tokens(&u.braced(), &[Token::Str(uuid_str)]);
954 serde_test::assert_de_tokens(&u.braced(), &[Token::Str(uuid_str)]);
955 }
956
957 #[test]
958 fn test_serialize_non_human_readable() {
959 let uuid_bytes = b"F9168C5E-CEB2-4F";
960 let u = Uuid::from_slice(uuid_bytes).unwrap();
961 serde_test::assert_tokens(
962 &u.compact(),
963 &[serde_test::Token::Bytes(&[
964 70, 57, 49, 54, 56, 67, 53, 69, 45, 67, 69, 66, 50, 45, 52, 70,
965 ])],
966 );
967 }
968
969 #[test]
970 fn test_de_failure() {
971 serde_test::assert_de_tokens_error::<Readable<Uuid>>(
972 &[Token::Str("hello_world")],
973 "UUID parsing failed: invalid character: found `h` at 0",
974 );
975
976 serde_test::assert_de_tokens_error::<Compact<Uuid>>(
977 &[Token::Bytes(b"hello_world")],
978 "UUID parsing failed: invalid length: expected 16 bytes, found 11",
979 );
980 }
981
982 #[test]
983 fn test_serde_non_nil_uuid() {
984 let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
985 let uuid = Uuid::parse_str(uuid_str).unwrap();
986 let non_nil_uuid = NonNilUuid::try_from(uuid).unwrap();
987
988 serde_test::assert_ser_tokens(&non_nil_uuid.readable(), &[Token::Str(uuid_str)]);
989 serde_test::assert_de_tokens(&non_nil_uuid.readable(), &[Token::Str(uuid_str)]);
990 }
991}