prost_uuid/
lib.rs

1use derive_more::{AsMut, AsRef, Constructor, Deref, DerefMut, Display, From, FromStr, Into};
2use prost::{
3    bytes::{Buf, BufMut},
4    encoding::{skip_field, string, DecodeContext, WireType},
5    DecodeError, Message,
6};
7use serde::{Deserialize, Serialize};
8use uuid::Uuid;
9
10/// NewType wrapper around [`uuid::Uuid`] with implementation of [`prost::Message`] for it.
11/// It uses [`prost::encoding::string`] inside.
12//TODO: put serde derive traits under feature
13#[derive(
14    Default,
15    Debug,
16    Clone,
17    Copy,
18    Eq,
19    Hash,
20    Ord,
21    PartialEq,
22    PartialOrd,
23    Serialize,
24    Deserialize,
25    AsMut,
26    AsRef,
27    Constructor,
28    Deref,
29    DerefMut,
30    Display,
31    From,
32    FromStr,
33    Into,
34)]
35pub struct ProstUuid(Uuid);
36
37impl Message for ProstUuid {
38    fn encode_raw<B>(&self, buf: &mut B)
39    where
40        B: BufMut,
41    {
42        string::encode(1, &self.0.to_string(), buf)
43    }
44
45    fn merge_field<B>(
46        &mut self,
47        tag: u32,
48        wire_type: WireType,
49        buf: &mut B,
50        ctx: DecodeContext,
51    ) -> Result<(), DecodeError>
52    where
53        B: Buf,
54    {
55        if tag == 1 {
56            let mut uuid_string = self.0.to_string();
57            let merge_result = string::merge(wire_type, &mut uuid_string, buf, ctx);
58            self.0 = Uuid::parse_str(&uuid_string)
59                .map_err(|error| DecodeError::new(error.to_string()))?;
60            merge_result
61        } else {
62            skip_field(wire_type, tag, buf, ctx)
63        }
64    }
65
66    fn encoded_len(&self) -> usize {
67        string::encoded_len(1, &self.0.to_string())
68    }
69
70    /// Clear the message, resetting inner [`uuid::Uuid`] to [`Uuid::nil`].
71    fn clear(&mut self) {
72        self.0 = Uuid::nil();
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    use uuid::Uuid;
79
80    use crate::ProstUuid;
81
82    #[test]
83    fn test_derive_more() {
84        let prost_uuid = ProstUuid::from(Uuid::nil());
85        let uuid = Uuid::from(prost_uuid);
86        assert_eq!(format!("{}", uuid), format!("{}", prost_uuid));
87        let new_prost_uuid = ProstUuid::new(uuid);
88        let mut mut_prost_uuid = new_prost_uuid;
89        let another_prost_uuid = new_prost_uuid;
90        function_expect_uuid(
91            new_prost_uuid.as_ref(),
92            mut_prost_uuid.as_mut(),
93            *another_prost_uuid,
94        );
95    }
96
97    fn function_expect_uuid(_uuid_ref: &Uuid, _uuid_mut_ref: &mut Uuid, _uuid: Uuid) {}
98}