• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Implementations of `ProtobufType` for all types.
2 
3 use std::marker;
4 use std::mem;
5 
6 #[cfg(feature = "bytes")]
7 use crate::chars::Chars;
8 #[cfg(feature = "bytes")]
9 use bytes::Bytes;
10 
11 use crate::coded_input_stream::CodedInputStream;
12 use crate::coded_output_stream::CodedOutputStream;
13 use crate::enums::ProtobufEnum;
14 use crate::error::ProtobufResult;
15 use crate::message::Message;
16 use crate::reflect::ProtobufValue;
17 use crate::rt;
18 use crate::unknown::UnknownValues;
19 use crate::wire_format::WireType;
20 use crate::zigzag::decode_zig_zag_32;
21 use crate::zigzag::decode_zig_zag_64;
22 
23 /// Protobuf elementary type as generic trait
24 pub trait ProtobufType {
25     /// Rust type of value
26     type Value: ProtobufValue + Clone + 'static;
27 
28     /// Wire type when writing to stream
wire_type() -> WireType29     fn wire_type() -> WireType;
30 
31     /// Read value from `CodedInputStream`
read(is: &mut CodedInputStream) -> ProtobufResult<Self::Value>32     fn read(is: &mut CodedInputStream) -> ProtobufResult<Self::Value>;
33 
34     /// Compute wire size
compute_size(value: &Self::Value) -> u3235     fn compute_size(value: &Self::Value) -> u32;
36 
37     /// Get value from `UnknownValues`
get_from_unknown(unknown_values: &UnknownValues) -> Option<Self::Value>38     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<Self::Value>;
39 
40     /// Compute size adding length prefix if wire type is length delimited
41     /// (i. e. string, bytes, message)
compute_size_with_length_delimiter(value: &Self::Value) -> u3242     fn compute_size_with_length_delimiter(value: &Self::Value) -> u32 {
43         let size = Self::compute_size(value);
44         if Self::wire_type() == WireType::WireTypeLengthDelimited {
45             rt::compute_raw_varint32_size(size) + size
46         } else {
47             size
48         }
49     }
50 
51     /// Get previously computed size
52     #[inline]
get_cached_size(value: &Self::Value) -> u3253     fn get_cached_size(value: &Self::Value) -> u32 {
54         Self::compute_size(value)
55     }
56 
57     /// Get previously cached size with length prefix
58     #[inline]
get_cached_size_with_length_delimiter(value: &Self::Value) -> u3259     fn get_cached_size_with_length_delimiter(value: &Self::Value) -> u32 {
60         let size = Self::get_cached_size(value);
61         if Self::wire_type() == WireType::WireTypeLengthDelimited {
62             rt::compute_raw_varint32_size(size) + size
63         } else {
64             size
65         }
66     }
67 
68     /// Write a value with previously cached size
write_with_cached_size( field_number: u32, value: &Self::Value, os: &mut CodedOutputStream, ) -> ProtobufResult<()>69     fn write_with_cached_size(
70         field_number: u32,
71         value: &Self::Value,
72         os: &mut CodedOutputStream,
73     ) -> ProtobufResult<()>;
74 }
75 
76 /// `float`
77 pub struct ProtobufTypeFloat;
78 /// `double`
79 pub struct ProtobufTypeDouble;
80 /// `uint32`
81 pub struct ProtobufTypeInt32;
82 /// `int64`
83 pub struct ProtobufTypeInt64;
84 /// `uint32`
85 pub struct ProtobufTypeUint32;
86 /// `uint64`
87 pub struct ProtobufTypeUint64;
88 /// `sint32`
89 pub struct ProtobufTypeSint32;
90 /// `sint64`
91 pub struct ProtobufTypeSint64;
92 /// `fixed32`
93 pub struct ProtobufTypeFixed32;
94 /// `fixed64`
95 pub struct ProtobufTypeFixed64;
96 /// `sfixed32`
97 pub struct ProtobufTypeSfixed32;
98 /// `sfixed64`
99 pub struct ProtobufTypeSfixed64;
100 /// `bool`
101 pub struct ProtobufTypeBool;
102 /// `string`
103 pub struct ProtobufTypeString;
104 /// `bytes`
105 pub struct ProtobufTypeBytes;
106 /// Something which should be deleted
107 pub struct ProtobufTypeChars;
108 
109 /// `bytes` as [`Bytes`](bytes::Bytes)
110 #[cfg(feature = "bytes")]
111 pub struct ProtobufTypeCarllercheBytes;
112 /// `string` as [`Chars`](crate::Chars)
113 #[cfg(feature = "bytes")]
114 pub struct ProtobufTypeCarllercheChars;
115 
116 /// `enum`
117 pub struct ProtobufTypeEnum<E: ProtobufEnum>(marker::PhantomData<E>);
118 /// `message`
119 pub struct ProtobufTypeMessage<M: Message>(marker::PhantomData<M>);
120 
121 impl ProtobufType for ProtobufTypeFloat {
122     type Value = f32;
123 
wire_type() -> WireType124     fn wire_type() -> WireType {
125         WireType::WireTypeFixed32
126     }
127 
read(is: &mut CodedInputStream) -> ProtobufResult<f32>128     fn read(is: &mut CodedInputStream) -> ProtobufResult<f32> {
129         is.read_float()
130     }
131 
compute_size(_value: &f32) -> u32132     fn compute_size(_value: &f32) -> u32 {
133         4
134     }
135 
get_from_unknown(unknown_values: &UnknownValues) -> Option<f32>136     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<f32> {
137         unknown_values
138             .fixed32
139             .iter()
140             .rev()
141             .next()
142             .map(|&bits| unsafe { mem::transmute::<u32, f32>(bits) })
143     }
144 
write_with_cached_size( field_number: u32, value: &f32, os: &mut CodedOutputStream, ) -> ProtobufResult<()>145     fn write_with_cached_size(
146         field_number: u32,
147         value: &f32,
148         os: &mut CodedOutputStream,
149     ) -> ProtobufResult<()> {
150         os.write_float(field_number, *value)
151     }
152 }
153 
154 impl ProtobufType for ProtobufTypeDouble {
155     type Value = f64;
156 
wire_type() -> WireType157     fn wire_type() -> WireType {
158         WireType::WireTypeFixed64
159     }
160 
read(is: &mut CodedInputStream) -> ProtobufResult<f64>161     fn read(is: &mut CodedInputStream) -> ProtobufResult<f64> {
162         is.read_double()
163     }
164 
get_from_unknown(unknown_values: &UnknownValues) -> Option<f64>165     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<f64> {
166         unknown_values
167             .fixed64
168             .iter()
169             .rev()
170             .next()
171             .map(|&bits| unsafe { mem::transmute::<u64, f64>(bits) })
172     }
173 
compute_size(_value: &f64) -> u32174     fn compute_size(_value: &f64) -> u32 {
175         8
176     }
177 
write_with_cached_size( field_number: u32, value: &f64, os: &mut CodedOutputStream, ) -> ProtobufResult<()>178     fn write_with_cached_size(
179         field_number: u32,
180         value: &f64,
181         os: &mut CodedOutputStream,
182     ) -> ProtobufResult<()> {
183         os.write_double(field_number, *value)
184     }
185 }
186 
187 impl ProtobufType for ProtobufTypeInt32 {
188     type Value = i32;
189 
wire_type() -> WireType190     fn wire_type() -> WireType {
191         WireType::WireTypeVarint
192     }
193 
read(is: &mut CodedInputStream) -> ProtobufResult<i32>194     fn read(is: &mut CodedInputStream) -> ProtobufResult<i32> {
195         is.read_int32()
196     }
197 
compute_size(value: &i32) -> u32198     fn compute_size(value: &i32) -> u32 {
199         // See also: https://github.com/protocolbuffers/protobuf/blob/bd00671b924310c0353a730bf8fa77c44e0a9c72/src/google/protobuf/io/coded_stream.h#L1300-L1306
200         if *value < 0 {
201             return 10;
202         }
203         rt::compute_raw_varint32_size(*value as u32)
204     }
205 
write_with_cached_size( field_number: u32, value: &i32, os: &mut CodedOutputStream, ) -> ProtobufResult<()>206     fn write_with_cached_size(
207         field_number: u32,
208         value: &i32,
209         os: &mut CodedOutputStream,
210     ) -> ProtobufResult<()> {
211         os.write_int32(field_number, *value)
212     }
213 
get_from_unknown(unknown_values: &UnknownValues) -> Option<i32>214     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<i32> {
215         unknown_values.varint.iter().rev().next().map(|&v| v as i32)
216     }
217 }
218 
219 impl ProtobufType for ProtobufTypeInt64 {
220     type Value = i64;
221 
wire_type() -> WireType222     fn wire_type() -> WireType {
223         WireType::WireTypeVarint
224     }
225 
read(is: &mut CodedInputStream) -> ProtobufResult<i64>226     fn read(is: &mut CodedInputStream) -> ProtobufResult<i64> {
227         is.read_int64()
228     }
229 
get_from_unknown(unknown_values: &UnknownValues) -> Option<i64>230     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<i64> {
231         unknown_values.varint.iter().rev().next().map(|&v| v as i64)
232     }
233 
compute_size(value: &i64) -> u32234     fn compute_size(value: &i64) -> u32 {
235         rt::compute_raw_varint64_size(*value as u64)
236     }
237 
write_with_cached_size( field_number: u32, value: &i64, os: &mut CodedOutputStream, ) -> ProtobufResult<()>238     fn write_with_cached_size(
239         field_number: u32,
240         value: &i64,
241         os: &mut CodedOutputStream,
242     ) -> ProtobufResult<()> {
243         os.write_int64(field_number, *value)
244     }
245 }
246 
247 impl ProtobufType for ProtobufTypeUint32 {
248     type Value = u32;
249 
wire_type() -> WireType250     fn wire_type() -> WireType {
251         WireType::WireTypeVarint
252     }
253 
read(is: &mut CodedInputStream) -> ProtobufResult<u32>254     fn read(is: &mut CodedInputStream) -> ProtobufResult<u32> {
255         is.read_uint32()
256     }
257 
get_from_unknown(unknown_values: &UnknownValues) -> Option<u32>258     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<u32> {
259         unknown_values.varint.iter().rev().next().map(|&v| v as u32)
260     }
261 
compute_size(value: &u32) -> u32262     fn compute_size(value: &u32) -> u32 {
263         rt::compute_raw_varint32_size(*value)
264     }
265 
write_with_cached_size( field_number: u32, value: &u32, os: &mut CodedOutputStream, ) -> ProtobufResult<()>266     fn write_with_cached_size(
267         field_number: u32,
268         value: &u32,
269         os: &mut CodedOutputStream,
270     ) -> ProtobufResult<()> {
271         os.write_uint32(field_number, *value)
272     }
273 }
274 
275 impl ProtobufType for ProtobufTypeUint64 {
276     type Value = u64;
277 
wire_type() -> WireType278     fn wire_type() -> WireType {
279         WireType::WireTypeVarint
280     }
281 
read(is: &mut CodedInputStream) -> ProtobufResult<u64>282     fn read(is: &mut CodedInputStream) -> ProtobufResult<u64> {
283         is.read_uint64()
284     }
285 
get_from_unknown(unknown_values: &UnknownValues) -> Option<u64>286     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<u64> {
287         unknown_values.varint.iter().cloned().rev().next()
288     }
289 
compute_size(value: &u64) -> u32290     fn compute_size(value: &u64) -> u32 {
291         rt::compute_raw_varint64_size(*value)
292     }
293 
write_with_cached_size( field_number: u32, value: &u64, os: &mut CodedOutputStream, ) -> ProtobufResult<()>294     fn write_with_cached_size(
295         field_number: u32,
296         value: &u64,
297         os: &mut CodedOutputStream,
298     ) -> ProtobufResult<()> {
299         os.write_uint64(field_number, *value)
300     }
301 }
302 
303 impl ProtobufType for ProtobufTypeSint32 {
304     type Value = i32;
305 
wire_type() -> WireType306     fn wire_type() -> WireType {
307         WireType::WireTypeVarint
308     }
309 
read(is: &mut CodedInputStream) -> ProtobufResult<i32>310     fn read(is: &mut CodedInputStream) -> ProtobufResult<i32> {
311         is.read_sint32()
312     }
313 
get_from_unknown(unknown_values: &UnknownValues) -> Option<i32>314     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<i32> {
315         ProtobufTypeUint32::get_from_unknown(unknown_values).map(decode_zig_zag_32)
316     }
317 
compute_size(value: &i32) -> u32318     fn compute_size(value: &i32) -> u32 {
319         rt::value_varint_zigzag_size_no_tag(*value)
320     }
321 
write_with_cached_size( field_number: u32, value: &i32, os: &mut CodedOutputStream, ) -> ProtobufResult<()>322     fn write_with_cached_size(
323         field_number: u32,
324         value: &i32,
325         os: &mut CodedOutputStream,
326     ) -> ProtobufResult<()> {
327         os.write_sint32(field_number, *value)
328     }
329 }
330 
331 impl ProtobufType for ProtobufTypeSint64 {
332     type Value = i64;
333 
wire_type() -> WireType334     fn wire_type() -> WireType {
335         WireType::WireTypeVarint
336     }
337 
read(is: &mut CodedInputStream) -> ProtobufResult<i64>338     fn read(is: &mut CodedInputStream) -> ProtobufResult<i64> {
339         is.read_sint64()
340     }
341 
get_from_unknown(unknown_values: &UnknownValues) -> Option<i64>342     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<i64> {
343         ProtobufTypeUint64::get_from_unknown(unknown_values).map(decode_zig_zag_64)
344     }
345 
compute_size(value: &i64) -> u32346     fn compute_size(value: &i64) -> u32 {
347         rt::value_varint_zigzag_size_no_tag(*value)
348     }
349 
write_with_cached_size( field_number: u32, value: &i64, os: &mut CodedOutputStream, ) -> ProtobufResult<()>350     fn write_with_cached_size(
351         field_number: u32,
352         value: &i64,
353         os: &mut CodedOutputStream,
354     ) -> ProtobufResult<()> {
355         os.write_sint64(field_number, *value)
356     }
357 }
358 
359 impl ProtobufType for ProtobufTypeFixed32 {
360     type Value = u32;
361 
wire_type() -> WireType362     fn wire_type() -> WireType {
363         WireType::WireTypeFixed32
364     }
365 
read(is: &mut CodedInputStream) -> ProtobufResult<u32>366     fn read(is: &mut CodedInputStream) -> ProtobufResult<u32> {
367         is.read_fixed32()
368     }
369 
get_from_unknown(unknown_values: &UnknownValues) -> Option<u32>370     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<u32> {
371         unknown_values.fixed32.iter().cloned().rev().next()
372     }
373 
compute_size(_value: &u32) -> u32374     fn compute_size(_value: &u32) -> u32 {
375         4
376     }
377 
write_with_cached_size( field_number: u32, value: &u32, os: &mut CodedOutputStream, ) -> ProtobufResult<()>378     fn write_with_cached_size(
379         field_number: u32,
380         value: &u32,
381         os: &mut CodedOutputStream,
382     ) -> ProtobufResult<()> {
383         os.write_fixed32(field_number, *value)
384     }
385 }
386 
387 impl ProtobufType for ProtobufTypeFixed64 {
388     type Value = u64;
389 
wire_type() -> WireType390     fn wire_type() -> WireType {
391         WireType::WireTypeFixed64
392     }
393 
read(is: &mut CodedInputStream) -> ProtobufResult<u64>394     fn read(is: &mut CodedInputStream) -> ProtobufResult<u64> {
395         is.read_fixed64()
396     }
397 
get_from_unknown(unknown_values: &UnknownValues) -> Option<u64>398     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<u64> {
399         unknown_values.fixed64.iter().cloned().rev().next()
400     }
401 
compute_size(_value: &u64) -> u32402     fn compute_size(_value: &u64) -> u32 {
403         8
404     }
405 
write_with_cached_size( field_number: u32, value: &u64, os: &mut CodedOutputStream, ) -> ProtobufResult<()>406     fn write_with_cached_size(
407         field_number: u32,
408         value: &u64,
409         os: &mut CodedOutputStream,
410     ) -> ProtobufResult<()> {
411         os.write_fixed64(field_number, *value)
412     }
413 }
414 
415 impl ProtobufType for ProtobufTypeSfixed32 {
416     type Value = i32;
417 
wire_type() -> WireType418     fn wire_type() -> WireType {
419         WireType::WireTypeFixed32
420     }
421 
read(is: &mut CodedInputStream) -> ProtobufResult<i32>422     fn read(is: &mut CodedInputStream) -> ProtobufResult<i32> {
423         is.read_sfixed32()
424     }
425 
get_from_unknown(unknown_values: &UnknownValues) -> Option<i32>426     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<i32> {
427         ProtobufTypeFixed32::get_from_unknown(unknown_values).map(|u| u as i32)
428     }
429 
compute_size(_value: &i32) -> u32430     fn compute_size(_value: &i32) -> u32 {
431         4
432     }
433 
write_with_cached_size( field_number: u32, value: &i32, os: &mut CodedOutputStream, ) -> ProtobufResult<()>434     fn write_with_cached_size(
435         field_number: u32,
436         value: &i32,
437         os: &mut CodedOutputStream,
438     ) -> ProtobufResult<()> {
439         os.write_sfixed32(field_number, *value)
440     }
441 }
442 
443 impl ProtobufType for ProtobufTypeSfixed64 {
444     type Value = i64;
445 
wire_type() -> WireType446     fn wire_type() -> WireType {
447         WireType::WireTypeFixed64
448     }
449 
read(is: &mut CodedInputStream) -> ProtobufResult<i64>450     fn read(is: &mut CodedInputStream) -> ProtobufResult<i64> {
451         is.read_sfixed64()
452     }
453 
get_from_unknown(unknown_values: &UnknownValues) -> Option<i64>454     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<i64> {
455         ProtobufTypeFixed64::get_from_unknown(unknown_values).map(|u| u as i64)
456     }
457 
compute_size(_value: &i64) -> u32458     fn compute_size(_value: &i64) -> u32 {
459         8
460     }
461 
write_with_cached_size( field_number: u32, value: &i64, os: &mut CodedOutputStream, ) -> ProtobufResult<()>462     fn write_with_cached_size(
463         field_number: u32,
464         value: &i64,
465         os: &mut CodedOutputStream,
466     ) -> ProtobufResult<()> {
467         os.write_sfixed64(field_number, *value)
468     }
469 }
470 
471 impl ProtobufType for ProtobufTypeBool {
472     type Value = bool;
473 
wire_type() -> WireType474     fn wire_type() -> WireType {
475         WireType::WireTypeVarint
476     }
477 
read(is: &mut CodedInputStream) -> ProtobufResult<bool>478     fn read(is: &mut CodedInputStream) -> ProtobufResult<bool> {
479         is.read_bool()
480     }
481 
get_from_unknown(unknown: &UnknownValues) -> Option<bool>482     fn get_from_unknown(unknown: &UnknownValues) -> Option<bool> {
483         unknown.varint.iter().rev().next().map(|&v| v != 0)
484     }
485 
compute_size(_value: &bool) -> u32486     fn compute_size(_value: &bool) -> u32 {
487         1
488     }
489 
write_with_cached_size( field_number: u32, value: &bool, os: &mut CodedOutputStream, ) -> ProtobufResult<()>490     fn write_with_cached_size(
491         field_number: u32,
492         value: &bool,
493         os: &mut CodedOutputStream,
494     ) -> ProtobufResult<()> {
495         os.write_bool(field_number, *value)
496     }
497 }
498 
499 impl ProtobufType for ProtobufTypeString {
500     type Value = String;
501 
wire_type() -> WireType502     fn wire_type() -> WireType {
503         WireType::WireTypeLengthDelimited
504     }
505 
read(is: &mut CodedInputStream) -> ProtobufResult<String>506     fn read(is: &mut CodedInputStream) -> ProtobufResult<String> {
507         is.read_string()
508     }
509 
get_from_unknown(unknown_values: &UnknownValues) -> Option<String>510     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<String> {
511         // TODO: should not panic
512         ProtobufTypeBytes::get_from_unknown(unknown_values)
513             .map(|b| String::from_utf8(b).expect("not a valid string"))
514     }
515 
compute_size(value: &String) -> u32516     fn compute_size(value: &String) -> u32 {
517         value.len() as u32
518     }
519 
write_with_cached_size( field_number: u32, value: &String, os: &mut CodedOutputStream, ) -> ProtobufResult<()>520     fn write_with_cached_size(
521         field_number: u32,
522         value: &String,
523         os: &mut CodedOutputStream,
524     ) -> ProtobufResult<()> {
525         os.write_string(field_number, &value)
526     }
527 }
528 
529 impl ProtobufType for ProtobufTypeBytes {
530     type Value = Vec<u8>;
531 
wire_type() -> WireType532     fn wire_type() -> WireType {
533         WireType::WireTypeLengthDelimited
534     }
535 
read(is: &mut CodedInputStream) -> ProtobufResult<Vec<u8>>536     fn read(is: &mut CodedInputStream) -> ProtobufResult<Vec<u8>> {
537         is.read_bytes()
538     }
539 
get_from_unknown(unknown_values: &UnknownValues) -> Option<Vec<u8>>540     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<Vec<u8>> {
541         unknown_values.length_delimited.iter().cloned().rev().next()
542     }
543 
compute_size(value: &Vec<u8>) -> u32544     fn compute_size(value: &Vec<u8>) -> u32 {
545         value.len() as u32
546     }
547 
write_with_cached_size( field_number: u32, value: &Vec<u8>, os: &mut CodedOutputStream, ) -> ProtobufResult<()>548     fn write_with_cached_size(
549         field_number: u32,
550         value: &Vec<u8>,
551         os: &mut CodedOutputStream,
552     ) -> ProtobufResult<()> {
553         os.write_bytes(field_number, &value)
554     }
555 }
556 
557 #[cfg(feature = "bytes")]
558 impl ProtobufType for ProtobufTypeCarllercheBytes {
559     type Value = Bytes;
560 
wire_type() -> WireType561     fn wire_type() -> WireType {
562         ProtobufTypeBytes::wire_type()
563     }
564 
read(is: &mut CodedInputStream) -> ProtobufResult<Self::Value>565     fn read(is: &mut CodedInputStream) -> ProtobufResult<Self::Value> {
566         is.read_carllerche_bytes()
567     }
568 
get_from_unknown(unknown_values: &UnknownValues) -> Option<Bytes>569     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<Bytes> {
570         ProtobufTypeBytes::get_from_unknown(unknown_values).map(Bytes::from)
571     }
572 
compute_size(value: &Bytes) -> u32573     fn compute_size(value: &Bytes) -> u32 {
574         value.len() as u32
575     }
576 
write_with_cached_size( field_number: u32, value: &Bytes, os: &mut CodedOutputStream, ) -> ProtobufResult<()>577     fn write_with_cached_size(
578         field_number: u32,
579         value: &Bytes,
580         os: &mut CodedOutputStream,
581     ) -> ProtobufResult<()> {
582         os.write_bytes(field_number, &value)
583     }
584 }
585 
586 #[cfg(feature = "bytes")]
587 impl ProtobufType for ProtobufTypeCarllercheChars {
588     type Value = Chars;
589 
wire_type() -> WireType590     fn wire_type() -> WireType {
591         ProtobufTypeBytes::wire_type()
592     }
593 
read(is: &mut CodedInputStream) -> ProtobufResult<Self::Value>594     fn read(is: &mut CodedInputStream) -> ProtobufResult<Self::Value> {
595         is.read_carllerche_chars()
596     }
597 
get_from_unknown(unknown_values: &UnknownValues) -> Option<Chars>598     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<Chars> {
599         ProtobufTypeString::get_from_unknown(unknown_values).map(Chars::from)
600     }
601 
compute_size(value: &Chars) -> u32602     fn compute_size(value: &Chars) -> u32 {
603         value.len() as u32
604     }
605 
write_with_cached_size( field_number: u32, value: &Chars, os: &mut CodedOutputStream, ) -> ProtobufResult<()>606     fn write_with_cached_size(
607         field_number: u32,
608         value: &Chars,
609         os: &mut CodedOutputStream,
610     ) -> ProtobufResult<()> {
611         os.write_string(field_number, &value)
612     }
613 }
614 
615 impl<E: ProtobufEnum + ProtobufValue> ProtobufType for ProtobufTypeEnum<E> {
616     type Value = E;
617 
wire_type() -> WireType618     fn wire_type() -> WireType {
619         WireType::WireTypeVarint
620     }
621 
read(is: &mut CodedInputStream) -> ProtobufResult<E>622     fn read(is: &mut CodedInputStream) -> ProtobufResult<E> {
623         is.read_enum()
624     }
625 
get_from_unknown(unknown_values: &UnknownValues) -> Option<E>626     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<E> {
627         // TODO: do not panic
628         ProtobufTypeInt32::get_from_unknown(unknown_values)
629             .map(|i| E::from_i32(i).expect("not a valid enum value"))
630     }
631 
compute_size(value: &E) -> u32632     fn compute_size(value: &E) -> u32 {
633         rt::compute_raw_varint32_size(value.value() as u32) // TODO: wrap
634     }
635 
write_with_cached_size( field_number: u32, value: &E, os: &mut CodedOutputStream, ) -> ProtobufResult<()>636     fn write_with_cached_size(
637         field_number: u32,
638         value: &E,
639         os: &mut CodedOutputStream,
640     ) -> ProtobufResult<()> {
641         os.write_enum_obj(field_number, *value)
642     }
643 }
644 
645 impl<M: Message + Clone + ProtobufValue> ProtobufType for ProtobufTypeMessage<M> {
646     type Value = M;
647 
wire_type() -> WireType648     fn wire_type() -> WireType {
649         WireType::WireTypeLengthDelimited
650     }
651 
read(is: &mut CodedInputStream) -> ProtobufResult<M>652     fn read(is: &mut CodedInputStream) -> ProtobufResult<M> {
653         is.read_message()
654     }
655 
get_from_unknown(unknown_values: &UnknownValues) -> Option<M>656     fn get_from_unknown(unknown_values: &UnknownValues) -> Option<M> {
657         // TODO: do not panic
658         unknown_values
659             .length_delimited
660             .iter()
661             .rev()
662             .next()
663             .map(|bytes| M::parse_from_bytes(bytes).expect("cannot parse message"))
664     }
665 
compute_size(value: &M) -> u32666     fn compute_size(value: &M) -> u32 {
667         value.compute_size()
668     }
669 
get_cached_size(value: &M) -> u32670     fn get_cached_size(value: &M) -> u32 {
671         value.get_cached_size()
672     }
673 
write_with_cached_size( field_number: u32, value: &Self::Value, os: &mut CodedOutputStream, ) -> ProtobufResult<()>674     fn write_with_cached_size(
675         field_number: u32,
676         value: &Self::Value,
677         os: &mut CodedOutputStream,
678     ) -> ProtobufResult<()> {
679         os.write_tag(field_number, WireType::WireTypeLengthDelimited)?;
680         os.write_raw_varint32(value.get_cached_size())?;
681         value.write_to_with_cached_sizes(os)?;
682         Ok(())
683     }
684 }
685