mesh_protobuf/
encode_with.rs1use super::DefaultEncoding;
8use super::InplaceOption;
9use super::MessageDecode;
10use super::MessageEncode;
11use super::Result;
12use super::encoding::MessageEncoding;
13use super::fmt;
14use super::protobuf::MessageReader;
15use super::protobuf::MessageSizer;
16use super::protobuf::MessageWriter;
17use crate::inplace;
18use core::ops::Deref;
19use core::ops::DerefMut;
20
21pub struct EncodeAs<T, U>(Inner<T, U>);
27
28pub struct EncodedMessage<E>(E);
29
30#[derive(Copy, Clone)]
31enum Inner<T, U> {
32 Unencoded(T),
33 Encoded(U),
34 Invalid,
35}
36
37impl<T, U> Deref for EncodeAs<T, U> {
38 type Target = T;
39
40 fn deref(&self) -> &Self::Target {
41 match &self.0 {
42 Inner::Unencoded(v) => v,
43 _ => unreachable!(),
44 }
45 }
46}
47
48impl<T, U> DerefMut for EncodeAs<T, U> {
49 fn deref_mut(&mut self) -> &mut Self::Target {
50 match &mut self.0 {
51 Inner::Unencoded(v) => v,
52 _ => unreachable!(),
53 }
54 }
55}
56
57impl<T, U> EncodeAs<T, U> {
58 pub fn into_inner(self) -> T {
60 match self.0 {
61 Inner::Unencoded(t) => t,
62 _ => unreachable!(),
63 }
64 }
65}
66
67impl<T, U: From<T>> EncodeAs<T, U> {
68 pub fn new(t: T) -> Self {
70 Self(Inner::Unencoded(t))
71 }
72
73 fn encode(&mut self) -> &mut U {
74 match core::mem::replace(&mut self.0, Inner::Invalid) {
75 Inner::Unencoded(t) => {
76 self.0 = Inner::Encoded(t.into());
77 }
78 _ => unreachable!("already encoded"),
79 }
80 match &mut self.0 {
81 Inner::Encoded(u) => u,
82 _ => unreachable!(),
83 }
84 }
85}
86
87impl<T, U: From<T>> From<T> for EncodeAs<T, U> {
88 fn from(t: T) -> Self {
89 Self::new(t)
90 }
91}
92
93impl<T: Clone, U> Clone for EncodeAs<T, U> {
94 fn clone(&self) -> Self {
95 match &self.0 {
96 Inner::Unencoded(v) => Self(Inner::Unencoded(v.clone())),
97 _ => unreachable!(),
98 }
99 }
100}
101
102impl<T: Copy, U: Copy> Copy for EncodeAs<T, U> {}
103
104impl<T: Default, U> Default for Inner<T, U> {
105 fn default() -> Self {
106 Inner::Unencoded(Default::default())
107 }
108}
109
110impl<T: fmt::Display, U> fmt::Display for EncodeAs<T, U> {
111 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112 fmt::Display::fmt(self.deref(), f)
113 }
114}
115
116impl<T: fmt::Debug, U> fmt::Debug for EncodeAs<T, U> {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 fmt::Debug::fmt(self.deref(), f)
119 }
120}
121
122impl<T, U: From<T>, R, E: MessageEncode<U, R>> MessageEncode<EncodeAs<T, U>, R>
123 for EncodedMessage<E>
124{
125 fn write_message(item: EncodeAs<T, U>, writer: MessageWriter<'_, '_, R>) {
126 match item.0 {
127 Inner::Encoded(err) => E::write_message(err, writer),
128 _ => unreachable!("compute_message_size has not been called"),
129 }
130 }
131
132 fn compute_message_size(item: &mut EncodeAs<T, U>, sizer: MessageSizer<'_>) {
133 E::compute_message_size(item.encode(), sizer);
134 }
135}
136
137impl<'a, T, U: From<T> + Into<T>, R, E: MessageDecode<'a, U, R>>
138 MessageDecode<'a, EncodeAs<T, U>, R> for EncodedMessage<E>
139{
140 fn read_message(
141 item: &mut InplaceOption<'_, EncodeAs<T, U>>,
142 reader: MessageReader<'a, '_, R>,
143 ) -> Result<()> {
144 let encoded = item.take().map(|v| v.into_inner().into());
145 inplace!(encoded);
146 E::read_message(&mut encoded, reader)?;
147 item.set(EncodeAs(Inner::Unencoded(
148 encoded.take().expect("should be constructed").into(),
149 )));
150 Ok(())
151 }
152}
153
154impl<T, U: From<T> + Into<T> + DefaultEncoding> DefaultEncoding for EncodeAs<T, U> {
155 type Encoding = MessageEncoding<EncodedMessage<U::Encoding>>;
156}