1use serde::{Deserialize, Deserializer, Serialize, Serializer};
8use std::{
9 fmt,
10 io::{Read, Write},
11 str::FromStr,
12};
13use uuid::Uuid;
14
15use crate::encoding::*;
16
17#[derive(Eq, PartialEq, Clone, Hash)]
19pub struct Guid {
20 uuid: Uuid,
21}
22
23impl Serialize for Guid {
24 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
25 where
26 S: Serializer,
27 {
28 self.uuid.to_string().serialize(serializer)
29 }
30}
31
32impl<'de> Deserialize<'de> for Guid {
33 fn deserialize<D>(deserializer: D) -> Result<Guid, D::Error>
34 where
35 D: Deserializer<'de>,
36 {
37 use serde::de::Error;
38
39 let result = String::deserialize(deserializer);
40 match result {
41 Ok(uuid) => Uuid::parse_str(&uuid)
42 .map(|uuid| Guid { uuid })
43 .map_err(|_| D::Error::custom("Invalid uuid")),
44 Err(err) => Err(err),
45 }
46 }
47}
48
49impl fmt::Display for Guid {
50 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51 write!(f, "{}", self.uuid)
52 }
53}
54
55impl fmt::Debug for Guid {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 write!(f, "{}", self.uuid.to_hyphenated())
58 }
59}
60
61impl BinaryEncoder<Guid> for Guid {
62 fn byte_len(&self) -> usize {
63 16
64 }
65
66 fn encode<S: Write>(&self, stream: &mut S) -> EncodingResult<usize> {
67 let mut size: usize = 0;
68 size += process_encode_io_result(stream.write(self.uuid.as_bytes()))?;
69 Ok(size)
70 }
71
72 fn decode<S: Read>(stream: &mut S, _: &DecodingOptions) -> EncodingResult<Self> {
73 let mut bytes = [0u8; 16];
74 process_decode_io_result(stream.read_exact(&mut bytes))?;
75 Ok(Guid {
76 uuid: Uuid::from_bytes(bytes),
77 })
78 }
79}
80
81impl FromStr for Guid {
82 type Err = ();
83
84 fn from_str(s: &str) -> Result<Self, Self::Err> {
85 Uuid::from_str(s).map(|uuid| Guid { uuid }).map_err(|err| {
86 error!("Guid cannot be parsed from string, err = {:?}", err);
87 })
88 }
89}
90
91impl Default for Guid {
92 fn default() -> Self {
93 Guid::null()
94 }
95}
96
97impl Guid {
98 pub fn null() -> Guid {
100 Guid { uuid: Uuid::nil() }
101 }
102
103 pub fn new() -> Guid {
105 Guid {
106 uuid: Uuid::new_v4(),
107 }
108 }
109
110 pub fn as_bytes(&self) -> &[u8; 16] {
112 self.uuid.as_bytes()
113 }
114
115 pub fn from_bytes(bytes: [u8; 16]) -> Guid {
117 Guid {
118 uuid: Uuid::from_bytes(bytes),
119 }
120 }
121}