Skip to main content

mesh_protobuf/
prost.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Support for encoding Prost types as Mesh types.
5
6use super::MessageDecode;
7use super::MessageEncode;
8use super::Result;
9use super::inplace::InplaceOption;
10use super::protobuf;
11use crate::Error;
12use alloc::vec::Vec;
13
14/// Encoding for using Prost messages as Mesh messages.
15pub struct ProstMessage;
16
17impl<T: prost::Message + Default, R> MessageEncode<T, R> for ProstMessage {
18    fn write_message(item: T, mut writer: protobuf::MessageWriter<'_, '_, R>) {
19        let mut v = Vec::with_capacity(item.encoded_len());
20        item.encode(&mut v).unwrap();
21        writer.bytes(&v);
22    }
23
24    fn compute_message_size(item: &mut T, mut sizer: protobuf::MessageSizer<'_>) {
25        sizer.bytes(item.encoded_len())
26    }
27}
28
29impl<T: prost::Message + Default, R> MessageDecode<'_, T, R> for ProstMessage {
30    fn read_message(
31        item: &mut InplaceOption<'_, T>,
32        reader: protobuf::MessageReader<'_, '_, R>,
33    ) -> Result<()> {
34        match item.as_mut() {
35            Some(item) => item.merge(reader.bytes()),
36            None => T::decode(reader.bytes()).map(|m| {
37                item.set(m);
38            }),
39        }
40        .map_err(Error::new)?;
41        Ok(())
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use crate::SerializedMessage;
48    use alloc::string::ToString;
49
50    #[expect(clippy::allow_attributes)]
51    mod items {
52        // Crates used by generated code. Reference them explicitly to ensure that
53        // automated tools do not remove them.
54        use prost as _;
55        use prost_types as _;
56
57        include!(concat!(env!("OUT_DIR"), "/foo.rs"));
58    }
59
60    #[test]
61    fn prost() {
62        let foo = items::Foo {
63            bar: "foo".to_string(),
64            baz: 0,
65            stuff: Some(items::foo::Stuff::Abc(5)),
66        };
67        let foo2 = <SerializedMessage>::from_message(foo.clone())
68            .into_message()
69            .unwrap();
70        assert_eq!(foo, foo2);
71    }
72}