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