Skip to main content

nrc_protobuf/
core.rs

1use std::any::Any;
2use std::any::TypeId;
3use std::fmt;
4use std::fmt::Write as _;
5use std::io::Read;
6use std::io::Write;
7
8#[cfg(feature = "bytes")]
9use bytes::Bytes;
10
11use clear::Clear;
12use error::ProtobufError;
13use error::ProtobufResult;
14use reflect::MessageDescriptor;
15use stream::with_coded_output_stream_to_bytes;
16use stream::CodedInputStream;
17use stream::CodedOutputStream;
18use stream::WithCodedInputStream;
19use stream::WithCodedOutputStream;
20use unknown::UnknownFields;
21use repeated::RepeatedField;
22use singular::{SingularField, SingularPtrField};
23
24/// Trait implemented for all generated structs for protobuf messages.
25///
26/// Also, generated messages implement `Clone + Default + PartialEq`
27pub trait Message: fmt::Debug + Clear + Any + Send + Sync {
28    /// Message descriptor for this message, used for reflection.
29    fn descriptor(&self) -> &'static MessageDescriptor;
30
31    /// True iff all required fields are initialized.
32    /// Always returns `true` for protobuf 3.
33    fn is_initialized(&self) -> bool;
34
35    /// Update this message object with fields read from given stream.
36    fn merge_from(&mut self, is: &mut CodedInputStream) -> ProtobufResult<()>;
37
38    /// Write message to the stream.
39    ///
40    /// Sizes of this messages and nested messages must be cached
41    /// by calling `compute_size` prior to this call.
42    fn write_to_with_cached_sizes(&self, os: &mut CodedOutputStream) -> ProtobufResult<()>;
43
44    /// Compute and cache size of this message and all nested messages
45    fn compute_size(&self) -> u32;
46
47    /// Get size previously computed by `compute_size`.
48    fn get_cached_size(&self) -> u32;
49
50    /// Write the message to the stream.
51    ///
52    /// Results in error if message is not fully initialized.
53    fn write_to(&self, os: &mut CodedOutputStream) -> ProtobufResult<()> {
54        self.check_initialized()?;
55
56        // cache sizes
57        self.compute_size();
58        // TODO: reserve additional
59        self.write_to_with_cached_sizes(os)?;
60
61        Ok(())
62    }
63
64    /// Write the message to the stream prepending the message with message length
65    /// encoded as varint.
66    fn write_length_delimited_to(&self, os: &mut CodedOutputStream) -> ProtobufResult<()> {
67        let size = self.compute_size();
68        os.write_raw_varint32(size)?;
69        self.write_to_with_cached_sizes(os)?;
70
71        // TODO: assert we've written same number of bytes as computed
72
73        Ok(())
74    }
75
76    /// Write the message to the vec, prepend the message with message length
77    /// encoded as varint.
78    fn write_length_delimited_to_vec(&self, vec: &mut Vec<u8>) -> ProtobufResult<()> {
79        let mut os = CodedOutputStream::vec(vec);
80        self.write_length_delimited_to(&mut os)?;
81        os.flush()?;
82        Ok(())
83    }
84
85    /// Update this message object with fields read from given stream.
86    fn merge_from_bytes(&mut self, bytes: &[u8]) -> ProtobufResult<()> {
87        let mut is = CodedInputStream::from_bytes(bytes);
88        self.merge_from(&mut is)
89    }
90
91    /// Check if all required fields of this object are initialized.
92    fn check_initialized(&self) -> ProtobufResult<()> {
93        if !self.is_initialized() {
94            Err(ProtobufError::message_not_initialized(
95                self.descriptor().name(),
96            ))
97        } else {
98            Ok(())
99        }
100    }
101
102    /// Write the message to the writer.
103    fn write_to_writer(&self, w: &mut Write) -> ProtobufResult<()> {
104        w.with_coded_output_stream(|os| self.write_to(os))
105    }
106
107    /// Write the message to bytes vec.
108    fn write_to_vec(&self, v: &mut Vec<u8>) -> ProtobufResult<()> {
109        v.with_coded_output_stream(|os| self.write_to(os))
110    }
111
112    /// Write the message to bytes vec.
113    fn write_to_bytes(&self) -> ProtobufResult<Vec<u8>> {
114        self.check_initialized()?;
115
116        let size = self.compute_size() as usize;
117        let mut v = Vec::with_capacity(size);
118        // skip zerofill
119        unsafe {
120            v.set_len(size);
121        }
122        {
123            let mut os = CodedOutputStream::bytes(&mut v);
124            self.write_to_with_cached_sizes(&mut os)?;
125            os.check_eof();
126        }
127        Ok(v)
128    }
129
130    /// Write the message to the writer, prepend the message with message length
131    /// encoded as varint.
132    fn write_length_delimited_to_writer(&self, w: &mut Write) -> ProtobufResult<()> {
133        w.with_coded_output_stream(|os| self.write_length_delimited_to(os))
134    }
135
136    /// Write the message to the bytes vec, prepend the message with message length
137    /// encoded as varint.
138    fn write_length_delimited_to_bytes(&self) -> ProtobufResult<Vec<u8>> {
139        with_coded_output_stream_to_bytes(|os| self.write_length_delimited_to(os))
140    }
141
142    /// Get a reference to unknown fields.
143    fn get_unknown_fields<'s>(&'s self) -> &'s UnknownFields;
144    /// Get a mutable reference to unknown fields.
145    fn mut_unknown_fields<'s>(&'s mut self) -> &'s mut UnknownFields;
146
147    /// Get type id for downcasting.
148    fn type_id(&self) -> TypeId {
149        TypeId::of::<Self>()
150    }
151
152    /// View self as `Any`.
153    fn as_any(&self) -> &Any;
154
155    /// View self as mutable `Any`.
156    fn as_any_mut(&mut self) -> &mut Any {
157        panic!()
158    }
159
160    /// Convert boxed self to boxed `Any`.
161    fn into_any(self: Box<Self>) -> Box<Any> {
162        panic!()
163    }
164
165    // Rust does not allow implementation of trait for trait:
166    // impl<M : Message> fmt::Debug for M {
167    // ...
168    // }
169
170    /// Create an empty message object.
171    ///
172    ///
173    /// ```
174    /// # use protobuf::Message;
175    /// # fn foo<MyMessage: Message>() {
176    /// let m = MyMessage::new();
177    /// # }
178    /// ```
179    fn new() -> Self
180    where
181        Self: Sized;
182
183    /// Get message descriptor for message type.
184    ///
185    /// ```
186    /// # use protobuf::Message;
187    /// # fn foo<MyMessage: Message>() {
188    /// let descriptor = MyMessage::descriptor_static();
189    /// assert_eq!("MyMessage", descriptor.name());
190    /// # }
191    /// ```
192    fn descriptor_static() -> &'static MessageDescriptor
193    where
194        Self: Sized,
195    {
196        panic!(
197            "descriptor_static is not implemented for message, \
198             LITE_RUNTIME must be used"
199        );
200    }
201
202    /// Return a pointer to default immutable message with static lifetime.
203    ///
204    /// ```
205    /// # use protobuf::Message;
206    /// # fn foo<MyMessage: Message>() {
207    /// let m: &MyMessage = MyMessage::default_instance();
208    /// # }
209    /// ```
210    fn default_instance() -> &'static Self
211    where
212        Self: Sized;
213}
214
215pub fn message_down_cast<'a, M: Message + 'a>(m: &'a Message) -> &'a M {
216    m.as_any().downcast_ref::<M>().unwrap()
217}
218
219/// Parse message from stream.
220pub fn parse_from<M: Message>(is: &mut CodedInputStream) -> ProtobufResult<M> {
221    let mut r: M = Message::new();
222    r.merge_from(is)?;
223    r.check_initialized()?;
224    Ok(r)
225}
226
227/// Parse message from reader.
228/// Parse stops on EOF or when error encountered.
229pub fn parse_from_reader<M: Message>(reader: &mut Read) -> ProtobufResult<M> {
230    reader.with_coded_input_stream(|is| parse_from::<M>(is))
231}
232
233/// Parse message from byte array.
234pub fn parse_from_bytes<M: Message>(bytes: &[u8]) -> ProtobufResult<M> {
235    bytes.with_coded_input_stream(|is| parse_from::<M>(is))
236}
237
238/// Parse message from `Bytes` object.
239/// Resulting message may share references to the passed bytes object.
240#[cfg(feature = "bytes")]
241pub fn parse_from_carllerche_bytes<M: Message>(bytes: &Bytes) -> ProtobufResult<M> {
242    // Call trait explicitly to avoid accidental construction from `&[u8]`
243    WithCodedInputStream::with_coded_input_stream(bytes, |is| parse_from::<M>(is))
244}
245
246/// Parse length-delimited message from stream.
247///
248/// Read varint length first, and read messages of that length then.
249///
250/// This function is deprecated and will be removed in the next major release.
251#[deprecated]
252pub fn parse_length_delimited_from<M: Message>(is: &mut CodedInputStream) -> ProtobufResult<M> {
253    is.read_message::<M>()
254}
255
256/// Parse length-delimited message from `Read`.
257///
258/// This function is deprecated and will be removed in the next major release.
259#[deprecated]
260pub fn parse_length_delimited_from_reader<M: Message>(r: &mut Read) -> ProtobufResult<M> {
261    // TODO: wrong: we may read length first, and then read exact number of bytes needed
262    r.with_coded_input_stream(|is| is.read_message::<M>())
263}
264
265/// Parse length-delimited message from bytes.
266///
267/// This function is deprecated and will be removed in the next major release.
268#[deprecated]
269pub fn parse_length_delimited_from_bytes<M: Message>(bytes: &[u8]) -> ProtobufResult<M> {
270    bytes.with_coded_input_stream(|is| is.read_message::<M>())
271}
272
273/// A trait used for pretty printing protobuf message.
274pub trait PbPrint {
275    /// Format `self` to `buf`.
276    fn fmt(&self, name: &str, buf: &mut String);
277}
278
279pub fn escape(data: &[u8], buf: &mut String) {
280    buf.reserve(data.len() + 2);
281    buf.push('"');
282    for &c in data {
283        match c {
284            b'\n' => buf.push_str(r"\n"),
285            b'\r' => buf.push_str(r"\r"),
286            b'\t' => buf.push_str(r"\t"),
287            b'"' => buf.push_str("\\\""),
288            b'\\' => buf.push_str(r"\\"),
289            _ => {
290                if c >= 0x20 && c < 0x7f {
291                    // c is printable
292                    buf.push(c as char);
293                } else {
294                    buf.push('\\');
295                    buf.push((b'0' + (c >> 6)) as char);
296                    buf.push((b'0' + ((c >> 3) & 7)) as char);
297                    buf.push((b'0' + (c & 7)) as char);
298                }
299            }
300        }
301    }
302    buf.push('"');
303}
304
305pub fn hex_escape(data: &[u8], buf: &mut String) {
306    hex::ToHex::write_hex_upper(&data, buf).unwrap();
307}
308
309#[inline]
310pub fn push_start(name: &str, buf: &mut String) {
311    if !buf.is_empty() {
312        buf.push(' ');
313    }
314    buf.push_str(name);
315}
316
317/// Push name to buf.
318#[inline]
319pub fn push_message_start(name: &str, buf: &mut String) {
320    push_start(name, buf);
321    buf.push_str(" {");
322}
323
324/// Push name to buf.
325#[inline]
326pub fn push_field_start(name: &str, buf: &mut String) {
327    push_start(name, buf);
328    buf.push_str(": ");
329}
330
331impl<T: PbPrint> PbPrint for Option<T> {
332    #[inline]
333    fn fmt(&self, name: &str, buf: &mut String) {
334        match self.as_ref() {
335            None => return,
336            Some(v) => v.fmt(name, buf),
337        }
338    }
339}
340
341impl PbPrint for String {
342    #[inline]
343    fn fmt(&self, name: &str, buf: &mut String) {
344        if self.is_empty() {
345            return;
346        }
347        push_field_start(name, buf);
348        escape(self.as_bytes(), buf);
349    }
350}
351
352impl PbPrint for Vec<u8> {
353    #[inline]
354    fn fmt(&self, name: &str, buf: &mut String) {
355        if self.is_empty() {
356            return;
357        }
358        push_field_start(name, buf);
359        hex_escape(self, buf);
360    }
361}
362
363impl<T: PbPrint> PbPrint for Vec<T> {
364    #[inline]
365    fn fmt(&self, name: &str, buf: &mut String) {
366        if self.is_empty() {
367            return;
368        }
369        for v in self {
370            v.fmt(name, buf);
371        }
372    }
373}
374
375macro_rules! print_number {
376    ($t:ty, $zero:expr) => {
377        impl PbPrint for $t {
378            #[inline]
379            fn fmt(&self, name: &str, buf: &mut String) {
380                if *self == $zero {
381                    return;
382                }
383                push_field_start(name, buf);
384                write!(buf, "{}", self).unwrap();
385            }
386        }
387    };
388}
389
390print_number!(i32, 0);
391print_number!(i64, 0);
392print_number!(u32, 0);
393print_number!(u64, 0);
394print_number!(f32, 0.0);
395print_number!(f64, 0.0);
396
397impl PbPrint for bool {
398    #[inline]
399    fn fmt(&self, name: &str, buf: &mut String) {
400        if !*self {
401            return;
402        }
403        push_field_start(name, buf);
404        buf.push_str("true");
405    }
406}
407
408impl<T: PbPrint> PbPrint for RepeatedField<T> {
409    fn fmt(&self, name: &str, buf: &mut String) {
410        if self.is_empty() {
411            return;
412        }
413        for v in self {
414            v.fmt(name, buf);
415        }
416    }
417}
418
419impl<T: PbPrint> PbPrint for SingularPtrField<T> {
420    #[inline]
421    fn fmt(&self, name: &str, buf: &mut String) {
422        match self.as_ref() {
423            None => return,
424            Some(v) => v.fmt(name, buf),
425        }
426    }
427}
428
429impl<T: PbPrint> PbPrint for SingularField<T> {
430    #[inline]
431    fn fmt(&self, name: &str, buf: &mut String) {
432        match self.as_ref() {
433            None => return,
434            Some(v) => v.fmt(name, buf),
435        }
436    }
437}
438
439/// Impl `PbPrint` if there is a `Debug` impl.
440#[macro_export]
441macro_rules! debug_to_pb_print {
442    ($t:ty) => {
443        impl PbPrint for $t {
444            #[inline]
445            fn fmt(&self, name: &str, buf: &mut String) {
446                ::protobuf::push_message_start(name, buf);
447                let old_len = buf.len();
448                write!(buf, "{:?}", self).unwrap();
449                if buf.len() > old_len {
450                    buf.push_str(" }");
451                } else {
452                    buf.push('}');
453                }
454            }
455        }
456    };
457}