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    mod items {
51        // Crates used by generated code. Reference them explicitly to ensure that
52        // automated tools do not remove them.
53        use prost as _;
54        use prost_types as _;
55
56        include!(concat!(env!("OUT_DIR"), "/foo.rs"));
57    }
58
59    #[test]
60    fn prost() {
61        let foo = items::Foo {
62            bar: "foo".to_string(),
63            baz: 0,
64            stuff: Some(items::foo::Stuff::Abc(5)),
65        };
66        let foo2 = <SerializedMessage>::from_message(foo.clone())
67            .into_message()
68            .unwrap();
69        assert_eq!(foo, foo2);
70    }
71}