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 {
385 use super::*;
386
387 pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
403 where
404 S: serde_core::Serializer,
405 {
406 serde_core::Serialize::serialize(u.as_simple(), serializer)
407 }
408
409 pub fn deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error>
413 where
414 D: serde_core::Deserializer<'de>,
415 {
416 Ok(Simple::deserialize(deserializer)?.into())
417 }
418
419 #[cfg(test)]
420 mod tests {
421 use serde::de::{self, Error};
422 use serde_test::{Readable, Token};
423
424 use super::*;
425
426 const HYPHENATED_UUID_STR: &str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
427 const SIMPLE_UUID_STR: &str = "f9168c5eceb24faab6bf329bf39fa1e4";
428
429 #[test]
430 fn test_serialize_as_simple() {
431 #[derive(serde_derive::Serialize)]
432 struct Struct(#[serde(with = "super")] crate::Uuid);
433
434 let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
435 serde_test::assert_ser_tokens(
436 &u,
437 &[
438 Token::NewtypeStruct { name: "Struct" },
439 Token::Str(SIMPLE_UUID_STR),
440 ],
441 );
442 }
443
444 #[test]
445 fn test_de_from_simple() {
446 #[derive(PartialEq, Debug, serde_derive::Deserialize)]
447 struct Struct(#[serde(with = "super")] crate::Uuid);
448 let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
449 serde_test::assert_de_tokens::<Struct>(
450 &s,
451 &[
452 Token::TupleStruct {
453 name: "Struct",
454 len: 1,
455 },
456 Token::BorrowedStr(SIMPLE_UUID_STR),
457 Token::TupleStructEnd,
458 ],
459 );
460 }
461
462 #[test]
463 fn test_de_reject_hypenated() {
464 #[derive(PartialEq, Debug, serde_derive::Deserialize)]
465 struct Struct(#[serde(with = "super")] crate::Uuid);
466 serde_test::assert_de_tokens_error::<Readable<Struct>>(
467 &[
468 Token::TupleStruct {
469 name: "Struct",
470 len: 1,
471 },
472 Token::BorrowedStr(HYPHENATED_UUID_STR),
473 Token::TupleStructEnd,
474 ],
475 &format!("{}", de::value::Error::custom("UUID parsing failed: invalid group length in group 4: expected 12, found 12")),
476 );
477 }
478 }
479}
480
481pub mod braced {
503 use super::*;
504
505 pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
521 where
522 S: serde_core::Serializer,
523 {
524 serde_core::Serialize::serialize(u.as_braced(), serializer)
525 }
526
527 pub fn deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error>
531 where
532 D: serde_core::Deserializer<'de>,
533 {
534 Ok(Braced::deserialize(deserializer)?.into())
535 }
536
537 #[cfg(test)]
538 mod tests {
539
540 use serde::de::{self, Error};
541 use serde_test::{Readable, Token};
542
543 use super::*;
544
545 const HYPHENATED_UUID_STR: &str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
546 const BRACED_UUID_STR: &str = "{f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4}";
547
548 #[test]
549 fn test_serialize_as_braced() {
550 #[derive(serde_derive::Serialize)]
551 struct Struct(#[serde(with = "super")] crate::Uuid);
552
553 let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
554 serde_test::assert_ser_tokens(
555 &u,
556 &[
557 Token::NewtypeStruct { name: "Struct" },
558 Token::Str(BRACED_UUID_STR),
559 ],
560 );
561 }
562
563 #[test]
564 fn test_de_from_braced() {
565 #[derive(PartialEq, Debug, serde_derive::Deserialize)]
566 struct Struct(#[serde(with = "super")] crate::Uuid);
567 let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
568 serde_test::assert_de_tokens::<Struct>(
569 &s,
570 &[
571 Token::TupleStruct {
572 name: "Struct",
573 len: 1,
574 },
575 Token::BorrowedStr(BRACED_UUID_STR),
576 Token::TupleStructEnd,
577 ],
578 );
579 }
580
581 #[test]
582 fn test_de_reject_hypenated() {
583 #[derive(PartialEq, Debug, serde_derive::Deserialize)]
584 struct Struct(#[serde(with = "super")] crate::Uuid);
585 serde_test::assert_de_tokens_error::<Readable<Struct>>(
586 &[
587 Token::TupleStruct {
588 name: "Struct",
589 len: 1,
590 },
591 Token::BorrowedStr(HYPHENATED_UUID_STR),
592 Token::TupleStructEnd,
593 ],
594 &format!("{}", de::value::Error::custom("UUID parsing failed: invalid group length in group 4: expected 12, found 12")),
595 );
596 }
597 }
598}
599
600pub mod urn {
622 use super::*;
623
624 pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
640 where
641 S: serde_core::Serializer,
642 {
643 serde_core::Serialize::serialize(u.as_urn(), serializer)
644 }
645
646 pub fn deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error>
650 where
651 D: serde_core::Deserializer<'de>,
652 {
653 Ok(Urn::deserialize(deserializer)?.into())
654 }
655
656 #[cfg(test)]
657 mod tests {
658 use serde::de::{self, Error};
659 use serde_test::{Readable, Token};
660
661 use super::*;
662
663 const HYPHENATED_UUID_STR: &str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
664 const URN_UUID_STR: &str = "urn:uuid:f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
665
666 #[test]
667 fn test_serialize_as_urn() {
668 #[derive(serde_derive::Serialize)]
669 struct Struct(#[serde(with = "super")] crate::Uuid);
670
671 let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
672 serde_test::assert_ser_tokens(
673 &u,
674 &[
675 Token::NewtypeStruct { name: "Struct" },
676 Token::Str(URN_UUID_STR),
677 ],
678 );
679 }
680
681 #[test]
682 fn test_de_from_urn() {
683 #[derive(PartialEq, Debug, serde_derive::Deserialize)]
684 struct Struct(#[serde(with = "super")] crate::Uuid);
685 let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
686 serde_test::assert_de_tokens::<Struct>(
687 &s,
688 &[
689 Token::TupleStruct {
690 name: "Struct",
691 len: 1,
692 },
693 Token::BorrowedStr(URN_UUID_STR),
694 Token::TupleStructEnd,
695 ],
696 );
697 }
698
699 #[test]
700 fn test_de_reject_hypenated() {
701 #[derive(PartialEq, Debug, serde_derive::Deserialize)]
702 struct Struct(#[serde(with = "super")] crate::Uuid);
703 serde_test::assert_de_tokens_error::<Readable<Struct>>(
704 &[
705 Token::TupleStruct {
706 name: "Struct",
707 len: 1,
708 },
709 Token::BorrowedStr(HYPHENATED_UUID_STR),
710 Token::TupleStructEnd,
711 ],
712 &format!("{}", de::value::Error::custom("UUID parsing failed: invalid group length in group 4: expected 12, found 12")),
713 );
714 }
715 }
716}
717
718#[cfg(test)]
719mod serde_tests {
720 use super::*;
721
722 use serde_test::{Compact, Configure, Readable, Token};
723
724 #[test]
725 fn test_serialize_readable_string() {
726 let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
727 let u = Uuid::parse_str(uuid_str).unwrap();
728 serde_test::assert_tokens(&u.readable(), &[Token::Str(uuid_str)]);
729 }
730
731 #[test]
732 fn test_deserialize_readable_compact() {
733 let uuid_bytes = b"F9168C5E-CEB2-4F";
734 let u = Uuid::from_slice(uuid_bytes).unwrap();
735
736 serde_test::assert_de_tokens(
737 &u.readable(),
738 &[
739 serde_test::Token::Tuple { len: 16 },
740 serde_test::Token::U8(uuid_bytes[0]),
741 serde_test::Token::U8(uuid_bytes[1]),
742 serde_test::Token::U8(uuid_bytes[2]),
743 serde_test::Token::U8(uuid_bytes[3]),
744 serde_test::Token::U8(uuid_bytes[4]),
745 serde_test::Token::U8(uuid_bytes[5]),
746 serde_test::Token::U8(uuid_bytes[6]),
747 serde_test::Token::U8(uuid_bytes[7]),
748 serde_test::Token::U8(uuid_bytes[8]),
749 serde_test::Token::U8(uuid_bytes[9]),
750 serde_test::Token::U8(uuid_bytes[10]),
751 serde_test::Token::U8(uuid_bytes[11]),
752 serde_test::Token::U8(uuid_bytes[12]),
753 serde_test::Token::U8(uuid_bytes[13]),
754 serde_test::Token::U8(uuid_bytes[14]),
755 serde_test::Token::U8(uuid_bytes[15]),
756 serde_test::Token::TupleEnd,
757 ],
758 );
759 }
760
761 #[test]
762 fn test_deserialize_readable_bytes() {
763 let uuid_bytes = b"F9168C5E-CEB2-4F";
764 let u = Uuid::from_slice(uuid_bytes).unwrap();
765
766 serde_test::assert_de_tokens(&u.readable(), &[serde_test::Token::Bytes(uuid_bytes)]);
767 }
768
769 #[test]
770 fn test_serialize_hyphenated() {
771 let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
772 let u = Uuid::parse_str(uuid_str).unwrap();
773 serde_test::assert_ser_tokens(&u.hyphenated(), &[Token::Str(uuid_str)]);
774 serde_test::assert_de_tokens(&u.hyphenated(), &[Token::Str(uuid_str)]);
775 }
776
777 #[test]
778 fn test_serialize_simple() {
779 let uuid_str = "f9168c5eceb24faab6bf329bf39fa1e4";
780 let u = Uuid::parse_str(uuid_str).unwrap();
781 serde_test::assert_ser_tokens(&u.simple(), &[Token::Str(uuid_str)]);
782 serde_test::assert_de_tokens(&u.simple(), &[Token::Str(uuid_str)]);
783 }
784
785 #[test]
786 fn test_serialize_urn() {
787 let uuid_str = "urn:uuid:f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
788 let u = Uuid::parse_str(uuid_str).unwrap();
789 serde_test::assert_ser_tokens(&u.urn(), &[Token::Str(uuid_str)]);
790 serde_test::assert_de_tokens(&u.urn(), &[Token::Str(uuid_str)]);
791 }
792
793 #[test]
794 fn test_serialize_braced() {
795 let uuid_str = "{f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4}";
796 let u = Uuid::parse_str(uuid_str).unwrap();
797 serde_test::assert_ser_tokens(&u.braced(), &[Token::Str(uuid_str)]);
798 serde_test::assert_de_tokens(&u.braced(), &[Token::Str(uuid_str)]);
799 }
800
801 #[test]
802 fn test_serialize_non_human_readable() {
803 let uuid_bytes = b"F9168C5E-CEB2-4F";
804 let u = Uuid::from_slice(uuid_bytes).unwrap();
805 serde_test::assert_tokens(
806 &u.compact(),
807 &[serde_test::Token::Bytes(&[
808 70, 57, 49, 54, 56, 67, 53, 69, 45, 67, 69, 66, 50, 45, 52, 70,
809 ])],
810 );
811 }
812
813 #[test]
814 fn test_de_failure() {
815 serde_test::assert_de_tokens_error::<Readable<Uuid>>(
816 &[Token::Str("hello_world")],
817 "UUID parsing failed: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-fA-F-], found `h` at 1",
818 );
819
820 serde_test::assert_de_tokens_error::<Compact<Uuid>>(
821 &[Token::Bytes(b"hello_world")],
822 "UUID parsing failed: invalid length: expected 16 bytes, found 11",
823 );
824 }
825
826 #[test]
827 fn test_serde_non_nil_uuid() {
828 let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
829 let uuid = Uuid::parse_str(uuid_str).unwrap();
830 let non_nil_uuid = NonNilUuid::try_from(uuid).unwrap();
831
832 serde_test::assert_ser_tokens(&non_nil_uuid.readable(), &[Token::Str(uuid_str)]);
833 serde_test::assert_de_tokens(&non_nil_uuid.readable(), &[Token::Str(uuid_str)]);
834 }
835}