prototk/
field_types.rs

1//! Field types supported by prototk.
2//!
3//! Add `use prototk::field_types::*` to your includes to access all field types in the derive
4//! macros.
5
6#![allow(non_camel_case_types)]
7
8// We allow non-CamelCase types here because we want the struct names to appear as close to they do
9// in the proto documentation and official implementation.  Thus, `uint64` is how we represent the
10// type of `u64`.  The primary use of these field types is to pull the token from a field annotated
11// with e.g. #[prototk(7, uint64)], where the uint64 token is used verbatim.
12
13use std::convert::TryInto;
14use std::ffi::OsStr;
15use std::os::unix::ffi::OsStrExt;
16use std::path::PathBuf;
17
18use buffertk::{stack_pack, Unpackable, Unpacker};
19
20use super::*;
21
22/////////////////////////////////////////////// int32 //////////////////////////////////////////////
23
24/// [int32] corresponds to the protobuf type of the same name.  It's a signed 32-bit integer
25/// represented as a varint.
26#[derive(Clone, Debug, Default)]
27pub struct int32(pub i32);
28
29impl FieldType<'_> for int32 {
30    const WIRE_TYPE: WireType = WireType::Varint;
31
32    type Native = i32;
33
34    fn from_native(x: Self::Native) -> Self {
35        Self(x)
36    }
37
38    fn into_native(self) -> Self::Native {
39        self.0
40    }
41}
42
43impl FieldPackHelper<'_, int32> for i32 {
44    fn field_pack_sz(&self, tag: &Tag) -> usize {
45        stack_pack(tag).pack(int32(*self)).pack_sz()
46    }
47
48    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
49        stack_pack(tag).pack(int32(*self)).into_slice(out);
50    }
51}
52
53impl FieldUnpackHelper<'_, int32> for i32 {
54    fn merge_field(&mut self, proto: int32) {
55        *self = proto.into();
56    }
57}
58
59impl From<int32> for i32 {
60    fn from(f: int32) -> Self {
61        f.0
62    }
63}
64
65impl Packable for int32 {
66    fn pack_sz(&self) -> usize {
67        let v: v64 = v64::from(self.0);
68        stack_pack(v).pack_sz()
69    }
70
71    fn pack(&self, out: &mut [u8]) {
72        let v: v64 = v64::from(self.0);
73        stack_pack(v).into_slice(out);
74    }
75}
76
77impl<'a> Unpackable<'a> for int32 {
78    type Error = Error;
79
80    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
81        let (v, buf) = v64::unpack(buf)?;
82        let x: i32 = v.try_into()?;
83        Ok((int32(x), buf))
84    }
85}
86
87/////////////////////////////////////////////// int64 //////////////////////////////////////////////
88
89/// [int64] corresponds to the protobuf type of the same name.  It's a signed 64-bit integer
90/// represented as a varint.
91#[derive(Clone, Debug, Default)]
92pub struct int64(pub i64);
93
94impl FieldType<'_> for int64 {
95    const WIRE_TYPE: WireType = WireType::Varint;
96
97    type Native = i64;
98
99    fn from_native(x: Self::Native) -> Self {
100        Self(x)
101    }
102
103    fn into_native(self) -> Self::Native {
104        self.0
105    }
106}
107
108impl FieldPackHelper<'_, int64> for i64 {
109    fn field_pack_sz(&self, tag: &Tag) -> usize {
110        stack_pack(tag).pack(int64(*self)).pack_sz()
111    }
112
113    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
114        stack_pack(tag).pack(int64(*self)).into_slice(out);
115    }
116}
117
118impl FieldUnpackHelper<'_, int64> for i64 {
119    fn merge_field(&mut self, proto: int64) {
120        *self = proto.into();
121    }
122}
123
124impl From<int64> for i64 {
125    fn from(f: int64) -> i64 {
126        f.0
127    }
128}
129
130impl Packable for int64 {
131    fn pack_sz(&self) -> usize {
132        let v: v64 = v64::from(self.0);
133        stack_pack(v).pack_sz()
134    }
135
136    fn pack(&self, out: &mut [u8]) {
137        let v: v64 = v64::from(self.0);
138        stack_pack(v).into_slice(out);
139    }
140}
141
142impl<'a> Unpackable<'a> for int64 {
143    type Error = Error;
144
145    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
146        let (v, buf) = v64::unpack(buf)?;
147        let x: i64 = v.into();
148        Ok((int64(x), buf))
149    }
150}
151
152////////////////////////////////////////////// uint32 //////////////////////////////////////////////
153
154/// [uint32] corresponds to the protobuf type of the same name.  It's a signed 32-bit integer
155/// represented as a varint.
156#[derive(Clone, Debug, Default)]
157pub struct uint32(pub u32);
158
159impl FieldType<'_> for uint32 {
160    const WIRE_TYPE: WireType = WireType::Varint;
161
162    type Native = u32;
163
164    fn from_native(x: Self::Native) -> Self {
165        Self(x)
166    }
167
168    fn into_native(self) -> Self::Native {
169        self.0
170    }
171}
172
173impl FieldPackHelper<'_, uint32> for u32 {
174    fn field_pack_sz(&self, tag: &Tag) -> usize {
175        stack_pack(tag).pack(uint32(*self)).pack_sz()
176    }
177
178    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
179        stack_pack(tag).pack(uint32(*self)).into_slice(out);
180    }
181}
182
183impl FieldUnpackHelper<'_, uint32> for u32 {
184    fn merge_field(&mut self, proto: uint32) {
185        *self = proto.into();
186    }
187}
188
189impl From<uint32> for u32 {
190    fn from(f: uint32) -> u32 {
191        f.0
192    }
193}
194
195impl Packable for uint32 {
196    fn pack_sz(&self) -> usize {
197        let v: v64 = v64::from(self.0);
198        stack_pack(v).pack_sz()
199    }
200
201    fn pack(&self, out: &mut [u8]) {
202        let v: v64 = v64::from(self.0);
203        stack_pack(v).into_slice(out);
204    }
205}
206
207impl<'a> Unpackable<'a> for uint32 {
208    type Error = Error;
209
210    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
211        let (v, buf) = v64::unpack(buf)?;
212        let x: u32 = v.try_into()?;
213        Ok((uint32(x), buf))
214    }
215}
216
217////////////////////////////////////////////// uint64 //////////////////////////////////////////////
218
219/// [uint64] corresponds to the protobuf type of the same name.  It's a signed 64-bit integer
220/// represented as a varint.
221#[derive(Clone, Debug, Default)]
222pub struct uint64(pub u64);
223
224impl FieldType<'_> for uint64 {
225    const WIRE_TYPE: WireType = WireType::Varint;
226
227    type Native = u64;
228
229    fn from_native(x: Self::Native) -> Self {
230        Self(x)
231    }
232
233    fn into_native(self) -> Self::Native {
234        self.0
235    }
236}
237
238impl FieldPackHelper<'_, uint64> for u64 {
239    fn field_pack_sz(&self, tag: &Tag) -> usize {
240        let v: v64 = v64::from(*self);
241        stack_pack(tag).pack(v).pack_sz()
242    }
243
244    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
245        let v: v64 = v64::from(*self);
246        stack_pack(tag).pack(v).into_slice(out);
247    }
248}
249
250impl FieldUnpackHelper<'_, uint64> for u64 {
251    fn merge_field(&mut self, proto: uint64) {
252        *self = proto.into();
253    }
254}
255
256impl From<uint64> for u64 {
257    fn from(f: uint64) -> u64 {
258        f.0
259    }
260}
261
262impl FieldPackHelper<'_, uint64> for usize {
263    fn field_pack_sz(&self, tag: &Tag) -> usize {
264        stack_pack(tag).pack(uint64(*self as u64)).pack_sz()
265    }
266
267    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
268        stack_pack(tag).pack(uint64(*self as u64)).into_slice(out);
269    }
270}
271
272impl FieldUnpackHelper<'_, uint64> for usize {
273    fn merge_field(&mut self, proto: uint64) {
274        *self = proto.into();
275    }
276}
277
278impl From<uint64> for usize {
279    fn from(f: uint64) -> usize {
280        f.0 as usize
281    }
282}
283
284impl Packable for uint64 {
285    fn pack_sz(&self) -> usize {
286        let v: v64 = v64::from(self.0);
287        stack_pack(v).pack_sz()
288    }
289
290    fn pack(&self, out: &mut [u8]) {
291        let v: v64 = v64::from(self.0);
292        stack_pack(v).into_slice(out);
293    }
294}
295
296impl<'a> Unpackable<'a> for uint64 {
297    type Error = Error;
298
299    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
300        let (v, buf) = v64::unpack(buf)?;
301        let x: u64 = v.into();
302        Ok((uint64(x), buf))
303    }
304}
305
306////////////////////////////////////////////// sint32 //////////////////////////////////////////////
307
308/// [sint32] corresponds to the protobuf type of the same name.  It's a signed 32-bit
309/// zig-zag-integer represented as a varint.
310#[derive(Clone, Debug, Default)]
311pub struct sint32(pub i32);
312
313impl FieldType<'_> for sint32 {
314    const WIRE_TYPE: WireType = WireType::Varint;
315
316    type Native = i32;
317
318    fn from_native(x: Self::Native) -> Self {
319        Self(x)
320    }
321
322    fn into_native(self) -> Self::Native {
323        self.0
324    }
325}
326
327impl FieldPackHelper<'_, sint32> for i32 {
328    fn field_pack_sz(&self, tag: &Tag) -> usize {
329        stack_pack(tag).pack(sint32(*self)).pack_sz()
330    }
331
332    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
333        stack_pack(tag).pack(sint32(*self)).into_slice(out);
334    }
335}
336
337impl FieldUnpackHelper<'_, sint32> for i32 {
338    fn merge_field(&mut self, proto: sint32) {
339        *self = proto.into();
340    }
341}
342
343impl From<sint32> for i32 {
344    fn from(f: sint32) -> i32 {
345        f.0
346    }
347}
348
349impl Packable for sint32 {
350    fn pack_sz(&self) -> usize {
351        let v: v64 = v64::from(zigzag(self.0 as i64));
352        stack_pack(v).pack_sz()
353    }
354
355    fn pack(&self, out: &mut [u8]) {
356        let v: v64 = v64::from(zigzag(self.0 as i64));
357        stack_pack(v).into_slice(out);
358    }
359}
360
361impl<'a> Unpackable<'a> for sint32 {
362    type Error = Error;
363
364    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
365        let (v, buf) = v64::unpack(buf)?;
366        let x: i64 = unzigzag(v.into());
367        let x: i32 = match x.try_into() {
368            Ok(x) => x,
369            Err(_) => {
370                return Err(Error::SignedOverflow { value: x });
371            }
372        };
373        Ok((sint32(x), buf))
374    }
375}
376
377////////////////////////////////////////////// sint64 //////////////////////////////////////////////
378
379/// [sint64] corresponds to the protobuf type of the same name.  It's a signed 64-bit
380/// zig-zag-integer represented as a varint.
381#[derive(Clone, Debug, Default)]
382pub struct sint64(pub i64);
383
384impl FieldType<'_> for sint64 {
385    const WIRE_TYPE: WireType = WireType::Varint;
386
387    type Native = i64;
388
389    fn from_native(x: Self::Native) -> Self {
390        Self(x)
391    }
392
393    fn into_native(self) -> Self::Native {
394        self.0
395    }
396}
397
398impl FieldPackHelper<'_, sint64> for i64 {
399    fn field_pack_sz(&self, tag: &Tag) -> usize {
400        stack_pack(tag).pack(sint64(*self)).pack_sz()
401    }
402
403    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
404        stack_pack(tag).pack(sint64(*self)).into_slice(out);
405    }
406}
407
408impl FieldUnpackHelper<'_, sint64> for i64 {
409    fn merge_field(&mut self, proto: sint64) {
410        *self = proto.into();
411    }
412}
413
414impl From<sint64> for i64 {
415    fn from(f: sint64) -> i64 {
416        f.0
417    }
418}
419
420impl Packable for sint64 {
421    fn pack_sz(&self) -> usize {
422        let v: v64 = v64::from(zigzag(self.0));
423        stack_pack(v).pack_sz()
424    }
425
426    fn pack(&self, out: &mut [u8]) {
427        let v: v64 = v64::from(zigzag(self.0));
428        stack_pack(v).into_slice(out);
429    }
430}
431
432impl<'a> Unpackable<'a> for sint64 {
433    type Error = Error;
434
435    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
436        let (v, buf) = v64::unpack(buf)?;
437        let x: i64 = unzigzag(v.into());
438        Ok((sint64(x), buf))
439    }
440}
441
442////////////////////////////////////////////// fixed32 //////////////////////////////////////////////
443
444/// [fixed32] corresponds to the protobuf type of the same name.  It's an unsigned 32-bit integer
445/// represented as a little-endian unsigned integer.
446#[derive(Clone, Debug, Default)]
447pub struct fixed32(pub u32);
448
449impl FieldType<'_> for fixed32 {
450    const WIRE_TYPE: WireType = WireType::ThirtyTwo;
451
452    type Native = u32;
453
454    fn from_native(x: Self::Native) -> Self {
455        Self(x)
456    }
457
458    fn into_native(self) -> Self::Native {
459        self.0
460    }
461}
462
463impl FieldPackHelper<'_, fixed32> for u32 {
464    fn field_pack_sz(&self, tag: &Tag) -> usize {
465        stack_pack(tag).pack(fixed32(*self)).pack_sz()
466    }
467
468    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
469        stack_pack(tag).pack(fixed32(*self)).into_slice(out);
470    }
471}
472
473impl FieldUnpackHelper<'_, fixed32> for u32 {
474    fn merge_field(&mut self, proto: fixed32) {
475        *self = proto.into();
476    }
477}
478
479impl From<fixed32> for u32 {
480    fn from(f: fixed32) -> u32 {
481        f.0
482    }
483}
484
485impl Packable for fixed32 {
486    fn pack_sz(&self) -> usize {
487        stack_pack(self.0).pack_sz()
488    }
489
490    fn pack(&self, out: &mut [u8]) {
491        stack_pack(self.0).into_slice(out);
492    }
493}
494
495impl<'a> Unpackable<'a> for fixed32 {
496    type Error = Error;
497
498    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
499        let (x, buf) = u32::unpack(buf)?;
500        Ok((fixed32(x), buf))
501    }
502}
503
504////////////////////////////////////////////// fixed64 //////////////////////////////////////////////
505
506/// [fixed64] corresponds to the protobuf type of the same name.  It's an unsigned 64-bit integer
507/// represented as a little-endian unsigned integer.
508#[derive(Clone, Debug, Default)]
509pub struct fixed64(pub u64);
510
511impl FieldType<'_> for fixed64 {
512    const WIRE_TYPE: WireType = WireType::SixtyFour;
513
514    type Native = u64;
515
516    fn from_native(x: Self::Native) -> Self {
517        Self(x)
518    }
519
520    fn into_native(self) -> Self::Native {
521        self.0
522    }
523}
524
525impl FieldPackHelper<'_, fixed64> for u64 {
526    fn field_pack_sz(&self, tag: &Tag) -> usize {
527        stack_pack(tag).pack(fixed64(*self)).pack_sz()
528    }
529
530    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
531        stack_pack(tag).pack(fixed64(*self)).into_slice(out);
532    }
533}
534
535impl FieldUnpackHelper<'_, fixed64> for u64 {
536    fn merge_field(&mut self, proto: fixed64) {
537        *self = proto.into();
538    }
539}
540
541impl From<fixed64> for u64 {
542    fn from(f: fixed64) -> u64 {
543        f.0
544    }
545}
546
547impl Packable for fixed64 {
548    fn pack_sz(&self) -> usize {
549        stack_pack(self.0).pack_sz()
550    }
551
552    fn pack(&self, out: &mut [u8]) {
553        stack_pack(self.0).into_slice(out);
554    }
555}
556
557impl<'a> Unpackable<'a> for fixed64 {
558    type Error = Error;
559
560    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
561        let (x, buf) = u64::unpack(buf)?;
562        Ok((fixed64(x), buf))
563    }
564}
565
566///////////////////////////////////////////// sfixed32 //////////////////////////////////////////////
567
568/// [sfixed32] corresponds to the protobuf type of the same name.  It's a signed 32-bit integer
569/// represented as a little-endian unsigned integer.
570#[derive(Clone, Debug, Default)]
571pub struct sfixed32(pub i32);
572
573impl FieldType<'_> for sfixed32 {
574    const WIRE_TYPE: WireType = WireType::ThirtyTwo;
575
576    type Native = i32;
577
578    fn from_native(x: Self::Native) -> Self {
579        Self(x)
580    }
581
582    fn into_native(self) -> Self::Native {
583        self.0
584    }
585}
586
587impl FieldPackHelper<'_, sfixed32> for i32 {
588    fn field_pack_sz(&self, tag: &Tag) -> usize {
589        stack_pack(tag).pack(sfixed32(*self)).pack_sz()
590    }
591
592    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
593        stack_pack(tag).pack(sfixed32(*self)).into_slice(out);
594    }
595}
596
597impl FieldUnpackHelper<'_, sfixed32> for i32 {
598    fn merge_field(&mut self, proto: sfixed32) {
599        *self = proto.into();
600    }
601}
602
603impl From<sfixed32> for i32 {
604    fn from(f: sfixed32) -> i32 {
605        f.0
606    }
607}
608
609impl Packable for sfixed32 {
610    fn pack_sz(&self) -> usize {
611        stack_pack(self.0).pack_sz()
612    }
613
614    fn pack(&self, out: &mut [u8]) {
615        stack_pack(self.0).into_slice(out);
616    }
617}
618
619impl<'a> Unpackable<'a> for sfixed32 {
620    type Error = Error;
621
622    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
623        let (x, buf) = i32::unpack(buf)?;
624        Ok((sfixed32(x), buf))
625    }
626}
627
628///////////////////////////////////////////// sfixed64 //////////////////////////////////////////////
629
630/// [sfixed64] corresponds to the protobuf type of the same name.  It's a signed 64-bit integer
631/// represented as a little-endian unsigned integer.
632#[derive(Clone, Debug, Default)]
633pub struct sfixed64(pub i64);
634
635impl FieldType<'_> for sfixed64 {
636    const WIRE_TYPE: WireType = WireType::SixtyFour;
637
638    type Native = i64;
639
640    fn from_native(x: Self::Native) -> Self {
641        Self(x)
642    }
643
644    fn into_native(self) -> Self::Native {
645        self.0
646    }
647}
648
649impl FieldPackHelper<'_, sfixed64> for i64 {
650    fn field_pack_sz(&self, tag: &Tag) -> usize {
651        stack_pack(tag).pack(sfixed64(*self)).pack_sz()
652    }
653
654    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
655        stack_pack(tag).pack(sfixed64(*self)).into_slice(out);
656    }
657}
658
659impl FieldUnpackHelper<'_, sfixed64> for i64 {
660    fn merge_field(&mut self, proto: sfixed64) {
661        *self = proto.into();
662    }
663}
664
665impl From<sfixed64> for i64 {
666    fn from(f: sfixed64) -> i64 {
667        f.0
668    }
669}
670
671impl Packable for sfixed64 {
672    fn pack_sz(&self) -> usize {
673        stack_pack(self.0).pack_sz()
674    }
675
676    fn pack(&self, out: &mut [u8]) {
677        stack_pack(self.0).into_slice(out);
678    }
679}
680
681impl<'a> Unpackable<'a> for sfixed64 {
682    type Error = Error;
683
684    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
685        let (x, buf) = i64::unpack(buf)?;
686        Ok((sfixed64(x), buf))
687    }
688}
689
690/////////////////////////////////////////////// float //////////////////////////////////////////////
691
692/// [float] corresponds to the protobuf type of the same name.  It's a 32-bit IEEE 754 float point
693/// number in little-endian format.
694#[derive(Clone, Debug, Default)]
695pub struct float(pub f32);
696
697impl FieldType<'_> for float {
698    const WIRE_TYPE: WireType = WireType::SixtyFour;
699
700    type Native = f32;
701
702    fn from_native(x: Self::Native) -> Self {
703        Self(x)
704    }
705
706    fn into_native(self) -> Self::Native {
707        self.0
708    }
709}
710
711impl FieldPackHelper<'_, float> for f32 {
712    fn field_pack_sz(&self, tag: &Tag) -> usize {
713        stack_pack(tag).pack(float(*self)).pack_sz()
714    }
715
716    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
717        stack_pack(tag).pack(float(*self)).into_slice(out);
718    }
719}
720
721impl FieldUnpackHelper<'_, float> for f32 {
722    fn merge_field(&mut self, proto: float) {
723        *self = proto.into();
724    }
725}
726
727impl From<float> for f32 {
728    fn from(f: float) -> f32 {
729        f.0
730    }
731}
732
733impl Packable for float {
734    fn pack_sz(&self) -> usize {
735        stack_pack(self.0).pack_sz()
736    }
737
738    fn pack(&self, out: &mut [u8]) {
739        stack_pack(self.0).into_slice(out);
740    }
741}
742
743impl<'a> Unpackable<'a> for float {
744    type Error = Error;
745
746    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
747        let (x, buf) = f32::unpack(buf)?;
748        Ok((float(x), buf))
749    }
750}
751
752////////////////////////////////////////////// double //////////////////////////////////////////////
753
754/// [double] corresponds to the protobuf type of the same name.  It's a 64-bit IEEE 754 float point
755/// number in little-endian format.
756#[derive(Clone, Debug, Default)]
757pub struct double(pub f64);
758
759impl FieldType<'_> for double {
760    const WIRE_TYPE: WireType = WireType::SixtyFour;
761
762    type Native = f64;
763
764    fn from_native(x: Self::Native) -> Self {
765        Self(x)
766    }
767
768    fn into_native(self) -> Self::Native {
769        self.0
770    }
771}
772
773impl FieldPackHelper<'_, double> for f64 {
774    fn field_pack_sz(&self, tag: &Tag) -> usize {
775        stack_pack(tag).pack(double(*self)).pack_sz()
776    }
777
778    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
779        stack_pack(tag).pack(double(*self)).into_slice(out);
780    }
781}
782
783impl FieldUnpackHelper<'_, double> for f64 {
784    fn merge_field(&mut self, proto: double) {
785        *self = proto.into();
786    }
787}
788
789impl From<double> for f64 {
790    fn from(f: double) -> f64 {
791        f.0
792    }
793}
794
795impl Packable for double {
796    fn pack_sz(&self) -> usize {
797        stack_pack(self.0).pack_sz()
798    }
799
800    fn pack(&self, out: &mut [u8]) {
801        stack_pack(self.0).into_slice(out);
802    }
803}
804
805impl<'a> Unpackable<'a> for double {
806    type Error = Error;
807
808    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
809        let (x, buf) = f64::unpack(buf)?;
810        Ok((double(x), buf))
811    }
812}
813
814/////////////////////////////////////////////// Bool ///////////////////////////////////////////////
815
816/// [Bool] corresponds to the protobuf type of the same name.
817#[derive(Clone, Debug, Default)]
818pub struct Bool(pub bool);
819
820impl FieldType<'_> for Bool {
821    const WIRE_TYPE: WireType = WireType::Varint;
822
823    type Native = bool;
824
825    fn from_native(b: Self::Native) -> Self {
826        Self(b)
827    }
828
829    fn into_native(self) -> Self::Native {
830        self.0
831    }
832}
833
834impl FieldPackHelper<'_, Bool> for bool {
835    fn field_pack_sz(&self, tag: &Tag) -> usize {
836        stack_pack(tag).pack(Bool(*self)).pack_sz()
837    }
838
839    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
840        stack_pack(tag).pack(Bool(*self)).into_slice(out);
841    }
842}
843
844impl FieldUnpackHelper<'_, Bool> for bool {
845    fn merge_field(&mut self, proto: Bool) {
846        *self = proto.into();
847    }
848}
849
850impl From<Bool> for bool {
851    fn from(f: Bool) -> bool {
852        f.0
853    }
854}
855
856impl Packable for Bool {
857    fn pack_sz(&self) -> usize {
858        let v: v64 = v64::from(if self.0 { 1 } else { 0 });
859        stack_pack(v).pack_sz()
860    }
861
862    fn pack(&self, out: &mut [u8]) {
863        let v: v64 = v64::from(if self.0 { 1 } else { 0 });
864        stack_pack(v).into_slice(out);
865    }
866}
867
868impl<'a> Unpackable<'a> for Bool {
869    type Error = Error;
870
871    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
872        let (v, buf) = v64::unpack(buf)?;
873        let x: u64 = v.into();
874        let b = x != 0;
875        Ok((Bool(b), buf))
876    }
877}
878
879/////////////////////////////////////////////// bytes //////////////////////////////////////////////
880
881/// [bytes] represents a variable-number of bytes.
882#[derive(Clone, Debug, Default)]
883pub struct bytes<'a>(pub &'a [u8]);
884
885impl<'a> FieldType<'a> for bytes<'a> {
886    const WIRE_TYPE: WireType = WireType::LengthDelimited;
887
888    type Native = &'a [u8];
889
890    fn from_native(x: Self::Native) -> Self {
891        Self(x)
892    }
893
894    fn into_native(self) -> Self::Native {
895        self.0
896    }
897}
898
899impl<'a> FieldPackHelper<'a, bytes<'a>> for &'a [u8] {
900    fn field_pack_sz(&self, tag: &Tag) -> usize {
901        stack_pack(tag).pack(bytes(self)).pack_sz()
902    }
903
904    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
905        stack_pack(tag).pack(bytes(self)).into_slice(out);
906    }
907}
908
909impl<'a> FieldUnpackHelper<'a, bytes<'a>> for &'a [u8] {
910    fn merge_field(&mut self, proto: bytes<'a>) {
911        *self = proto.into();
912    }
913}
914
915impl<'a> From<bytes<'a>> for &'a [u8] {
916    fn from(f: bytes<'a>) -> &'a [u8] {
917        f.0
918    }
919}
920
921impl<'a> FieldPackHelper<'a, bytes<'a>> for Vec<u8> {
922    fn field_pack_sz(&self, tag: &Tag) -> usize {
923        let field: &[u8] = self;
924        stack_pack(tag).pack(bytes(field)).pack_sz()
925    }
926
927    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
928        let field: &[u8] = self;
929        stack_pack(tag).pack(bytes(field)).into_slice(out);
930    }
931}
932
933impl<'a> FieldUnpackHelper<'a, bytes<'a>> for Vec<u8> {
934    fn merge_field(&mut self, proto: bytes<'a>) {
935        *self = proto.into();
936    }
937}
938
939impl<'a> From<bytes<'a>> for Vec<u8> {
940    fn from(f: bytes<'a>) -> Vec<u8> {
941        f.0.to_vec()
942    }
943}
944
945impl<'a> FieldPackHelper<'a, bytes<'a>> for PathBuf {
946    fn field_pack_sz(&self, tag: &Tag) -> usize {
947        let field: &[u8] = self.as_os_str().as_bytes();
948        stack_pack(tag).pack(bytes(field)).pack_sz()
949    }
950
951    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
952        let field: &[u8] = self.as_os_str().as_bytes();
953        stack_pack(tag).pack(bytes(field)).into_slice(out);
954    }
955}
956
957impl<'a> FieldUnpackHelper<'a, bytes<'a>> for PathBuf {
958    fn merge_field(&mut self, proto: bytes<'a>) {
959        *self = proto.into();
960    }
961}
962
963impl<'a> From<bytes<'a>> for PathBuf {
964    fn from(f: bytes<'a>) -> PathBuf {
965        PathBuf::from(OsStr::from_bytes(f.0))
966    }
967}
968
969impl Packable for bytes<'_> {
970    fn pack_sz(&self) -> usize {
971        stack_pack(self.0).pack_sz()
972    }
973
974    fn pack(&self, out: &mut [u8]) {
975        stack_pack(self.0).into_slice(out);
976    }
977}
978
979impl<'a> Unpackable<'a> for bytes<'a> {
980    type Error = Error;
981
982    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
983        let mut up = Unpacker::new(buf);
984        let v: v64 = up.unpack()?;
985        let v: usize = v.into();
986        let rem = up.remain();
987        if rem.len() < v {
988            return Err(Error::BufferTooShort {
989                required: v,
990                had: rem.len(),
991            });
992        }
993        Ok((Self(&rem[..v]), &rem[v..]))
994    }
995}
996
997////////////////////////////////////////////// bytes16 /////////////////////////////////////////////
998
999/// [bytes] represents 16 bytes.
1000#[derive(Clone, Debug, Default)]
1001pub struct bytes16(pub [u8; 16]);
1002
1003impl FieldType<'_> for bytes16 {
1004    const WIRE_TYPE: WireType = WireType::LengthDelimited;
1005
1006    type Native = [u8; 16];
1007
1008    fn from_native(x: Self::Native) -> Self {
1009        Self(x)
1010    }
1011
1012    fn into_native(self) -> Self::Native {
1013        self.0
1014    }
1015}
1016
1017impl FieldPackHelper<'_, bytes16> for [u8; 16] {
1018    fn field_pack_sz(&self, tag: &Tag) -> usize {
1019        stack_pack(tag).pack(bytes16(*self)).pack_sz()
1020    }
1021
1022    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
1023        stack_pack(tag).pack(bytes16(*self)).into_slice(out);
1024    }
1025}
1026
1027impl FieldUnpackHelper<'_, bytes16> for [u8; 16] {
1028    fn merge_field(&mut self, proto: bytes16) {
1029        *self = proto.into();
1030    }
1031}
1032
1033impl From<bytes16> for [u8; 16] {
1034    fn from(f: bytes16) -> [u8; 16] {
1035        f.0
1036    }
1037}
1038
1039impl Packable for bytes16 {
1040    fn pack_sz(&self) -> usize {
1041        let b: &[u8] = &self.0;
1042        stack_pack(b).pack_sz()
1043    }
1044
1045    fn pack(&self, out: &mut [u8]) {
1046        let b: &[u8] = &self.0;
1047        stack_pack(b).into_slice(out);
1048    }
1049}
1050
1051impl<'a> Unpackable<'a> for bytes16 {
1052    type Error = Error;
1053
1054    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
1055        let mut up = Unpacker::new(buf);
1056        let v: v64 = up.unpack()?;
1057        let v: usize = v.into();
1058        let rem = up.remain();
1059        if rem.len() < v {
1060            return Err(Error::BufferTooShort {
1061                required: v,
1062                had: rem.len(),
1063            });
1064        }
1065        if v < 16 {
1066            return Err(Error::BufferTooShort {
1067                required: 16,
1068                had: v,
1069            });
1070        }
1071        if v != 16 {
1072            return Err(Error::WrongLength {
1073                required: 16,
1074                had: v,
1075            });
1076        }
1077        let mut ret = [0u8; 16];
1078        ret[..16].copy_from_slice(&rem[..16]);
1079        Ok((Self(ret), &rem[v..]))
1080    }
1081}
1082////////////////////////////////////////////// bytes32 /////////////////////////////////////////////
1083
1084/// [bytes] represents 32 bytes.
1085#[derive(Clone, Debug, Default)]
1086pub struct bytes32(pub [u8; 32]);
1087
1088impl FieldType<'_> for bytes32 {
1089    const WIRE_TYPE: WireType = WireType::LengthDelimited;
1090
1091    type Native = [u8; 32];
1092
1093    fn from_native(x: Self::Native) -> Self {
1094        Self(x)
1095    }
1096
1097    fn into_native(self) -> Self::Native {
1098        self.0
1099    }
1100}
1101
1102impl FieldPackHelper<'_, bytes32> for [u8; 32] {
1103    fn field_pack_sz(&self, tag: &Tag) -> usize {
1104        stack_pack(tag).pack(bytes32(*self)).pack_sz()
1105    }
1106
1107    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
1108        stack_pack(tag).pack(bytes32(*self)).into_slice(out);
1109    }
1110}
1111
1112impl FieldUnpackHelper<'_, bytes32> for [u8; 32] {
1113    fn merge_field(&mut self, proto: bytes32) {
1114        *self = proto.into();
1115    }
1116}
1117
1118impl From<bytes32> for [u8; 32] {
1119    fn from(f: bytes32) -> [u8; 32] {
1120        f.0
1121    }
1122}
1123
1124impl Packable for bytes32 {
1125    fn pack_sz(&self) -> usize {
1126        let b: &[u8] = &self.0;
1127        stack_pack(b).pack_sz()
1128    }
1129
1130    fn pack(&self, out: &mut [u8]) {
1131        let b: &[u8] = &self.0;
1132        stack_pack(b).into_slice(out);
1133    }
1134}
1135
1136impl<'a> Unpackable<'a> for bytes32 {
1137    type Error = Error;
1138
1139    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
1140        let mut up = Unpacker::new(buf);
1141        let v: v64 = up.unpack()?;
1142        let v: usize = v.into();
1143        let rem = up.remain();
1144        if rem.len() < v {
1145            return Err(Error::BufferTooShort {
1146                required: v,
1147                had: rem.len(),
1148            });
1149        }
1150        if v < 32 {
1151            return Err(Error::BufferTooShort {
1152                required: 32,
1153                had: v,
1154            });
1155        }
1156        if v != 32 {
1157            return Err(Error::WrongLength {
1158                required: 32,
1159                had: v,
1160            });
1161        }
1162        let mut ret = [0u8; 32];
1163        ret[..32].copy_from_slice(&rem[..32]);
1164        Ok((Self(ret), &rem[v..]))
1165    }
1166}
1167
1168////////////////////////////////////////////// bytes64 /////////////////////////////////////////////
1169
1170/// [bytes] represents 64 bytes.
1171#[derive(Clone, Debug)]
1172pub struct bytes64(pub [u8; 64]);
1173
1174impl FieldType<'_> for bytes64 {
1175    const WIRE_TYPE: WireType = WireType::LengthDelimited;
1176
1177    type Native = [u8; 64];
1178
1179    fn from_native(x: Self::Native) -> Self {
1180        Self(x)
1181    }
1182
1183    fn into_native(self) -> Self::Native {
1184        self.0
1185    }
1186}
1187
1188impl Default for bytes64 {
1189    fn default() -> Self {
1190        Self([0u8; 64])
1191    }
1192}
1193
1194impl FieldPackHelper<'_, bytes64> for [u8; 64] {
1195    fn field_pack_sz(&self, tag: &Tag) -> usize {
1196        stack_pack(tag).pack(bytes64(*self)).pack_sz()
1197    }
1198
1199    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
1200        stack_pack(tag).pack(bytes64(*self)).into_slice(out);
1201    }
1202}
1203
1204impl FieldUnpackHelper<'_, bytes64> for [u8; 64] {
1205    fn merge_field(&mut self, proto: bytes64) {
1206        *self = proto.into();
1207    }
1208}
1209
1210impl From<bytes64> for [u8; 64] {
1211    fn from(f: bytes64) -> [u8; 64] {
1212        f.0
1213    }
1214}
1215
1216impl Packable for bytes64 {
1217    fn pack_sz(&self) -> usize {
1218        let b: &[u8] = &self.0;
1219        stack_pack(b).pack_sz()
1220    }
1221
1222    fn pack(&self, out: &mut [u8]) {
1223        let b: &[u8] = &self.0;
1224        stack_pack(b).into_slice(out);
1225    }
1226}
1227
1228impl<'a> Unpackable<'a> for bytes64 {
1229    type Error = Error;
1230
1231    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
1232        let mut up = Unpacker::new(buf);
1233        let v: v64 = up.unpack()?;
1234        let v: usize = v.into();
1235        let rem = up.remain();
1236        if rem.len() < v {
1237            return Err(Error::BufferTooShort {
1238                required: v,
1239                had: rem.len(),
1240            });
1241        }
1242        if v < 64 {
1243            return Err(Error::BufferTooShort {
1244                required: 64,
1245                had: v,
1246            });
1247        }
1248        if v != 64 {
1249            return Err(Error::WrongLength {
1250                required: 64,
1251                had: v,
1252            });
1253        }
1254        let mut ret = [0u8; 64];
1255        ret[..64].copy_from_slice(&rem[..64]);
1256        Ok((Self(ret), &rem[v..]))
1257    }
1258}
1259
1260///////////////////////////////////////////// string ////////////////////////////////////////////
1261
1262/// [string] represents a UTF-8 string of variable length.
1263#[derive(Clone, Debug, Default)]
1264pub struct string<'a>(pub &'a str);
1265
1266impl<'a> FieldType<'a> for string<'a> {
1267    const WIRE_TYPE: WireType = WireType::LengthDelimited;
1268
1269    type Native = &'a str;
1270
1271    fn from_native(s: Self::Native) -> Self {
1272        Self(s)
1273    }
1274
1275    fn into_native(self) -> Self::Native {
1276        self.0
1277    }
1278}
1279
1280impl<'a> FieldPackHelper<'a, string<'a>> for &'a str {
1281    fn field_pack_sz(&self, tag: &Tag) -> usize {
1282        stack_pack(tag).pack(string(self)).pack_sz()
1283    }
1284
1285    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
1286        stack_pack(tag).pack(string(self)).into_slice(out);
1287    }
1288}
1289
1290impl<'a> FieldUnpackHelper<'a, string<'a>> for &'a str {
1291    fn merge_field(&mut self, proto: string<'a>) {
1292        *self = proto.into();
1293    }
1294}
1295
1296impl<'a> From<string<'a>> for &'a str {
1297    fn from(f: string<'a>) -> &'a str {
1298        f.0
1299    }
1300}
1301
1302impl<'a> FieldPackHelper<'a, string<'a>> for String {
1303    fn field_pack_sz(&self, tag: &Tag) -> usize {
1304        stack_pack(tag).pack(string(self)).pack_sz()
1305    }
1306
1307    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
1308        stack_pack(tag).pack(string(self)).into_slice(out);
1309    }
1310}
1311
1312impl<'a> FieldUnpackHelper<'a, string<'a>> for String {
1313    fn merge_field(&mut self, proto: string<'a>) {
1314        *self = proto.into();
1315    }
1316}
1317
1318impl<'a> From<string<'a>> for String {
1319    fn from(f: string<'a>) -> String {
1320        f.0.to_owned()
1321    }
1322}
1323
1324impl<'a> FieldPackHelper<'a, string<'a>> for PathBuf {
1325    fn field_pack_sz(&self, tag: &Tag) -> usize {
1326        stack_pack(tag).pack(self.as_os_str().as_bytes()).pack_sz()
1327    }
1328
1329    fn field_pack(&self, tag: &Tag, out: &mut [u8]) {
1330        stack_pack(tag)
1331            .pack(self.as_os_str().as_bytes())
1332            .into_slice(out);
1333    }
1334}
1335
1336impl<'a> FieldUnpackHelper<'a, string<'a>> for PathBuf {
1337    fn merge_field(&mut self, proto: string<'a>) {
1338        *self = proto.into();
1339    }
1340}
1341
1342impl<'a> From<string<'a>> for PathBuf {
1343    fn from(f: string<'a>) -> PathBuf {
1344        f.0.into()
1345    }
1346}
1347
1348impl Packable for string<'_> {
1349    fn pack_sz(&self) -> usize {
1350        let b: &[u8] = self.0.as_bytes();
1351        stack_pack(b).pack_sz()
1352    }
1353
1354    fn pack(&self, out: &mut [u8]) {
1355        let b: &[u8] = self.0.as_bytes();
1356        stack_pack(b).into_slice(out);
1357    }
1358}
1359
1360impl<'a> Unpackable<'a> for string<'a> {
1361    type Error = Error;
1362
1363    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Error> {
1364        let mut up = Unpacker::new(buf);
1365        let v: v64 = up.unpack()?;
1366        let v: usize = v.into();
1367        let rem = up.remain();
1368        if rem.len() < v {
1369            return Err(Error::BufferTooShort {
1370                required: v,
1371                had: rem.len(),
1372            });
1373        }
1374        let x: &'a [u8] = &rem[..v];
1375        let s: &'a str = match std::str::from_utf8(x) {
1376            Ok(s) => s,
1377            Err(_) => {
1378                return Err(Error::StringEncoding);
1379            }
1380        };
1381        Ok((string(s), &rem[v..]))
1382    }
1383}
1384
1385////////////////////////////////////////////// message /////////////////////////////////////////////
1386
1387/// [message] represents a ProtoTK message.
1388#[derive(Clone, Debug)]
1389pub struct message<M>(pub M);
1390
1391impl<M> message<M> {
1392    /// Return the message that's held by this [message].
1393    pub fn unwrap_message(self) -> M {
1394        self.0
1395    }
1396}
1397
1398impl<M> FieldType<'_> for message<M> {
1399    const WIRE_TYPE: WireType = WireType::LengthDelimited;
1400
1401    type Native = M;
1402
1403    fn from_native(msg: M) -> Self {
1404        Self(msg)
1405    }
1406
1407    fn into_native(self) -> Self::Native {
1408        self.0
1409    }
1410}
1411
1412impl<M: Packable> Packable for message<M> {
1413    fn pack_sz(&self) -> usize {
1414        self.0.pack_sz()
1415    }
1416
1417    fn pack(&self, buf: &mut [u8]) {
1418        self.0.pack(buf)
1419    }
1420}
1421
1422impl<'a, M> Unpackable<'a> for message<M>
1423where
1424    M: Unpackable<'a>,
1425    <M as Unpackable<'a>>::Error: From<buffertk::Error>,
1426{
1427    type Error = M::Error;
1428
1429    fn unpack<'b: 'a>(buf: &'b [u8]) -> Result<(Self, &'b [u8]), Self::Error> {
1430        let mut up = Unpacker::new(buf);
1431        let v: v64 = match up.unpack() {
1432            Ok(v) => v,
1433            Err(e) => {
1434                return Err(e.into());
1435            }
1436        };
1437        let v: usize = v.into();
1438        let rem = up.remain();
1439        // TODO(rescrv): this pattern multiple times; try to move to Unpacker.
1440        if rem.len() < v {
1441            return Err(buffertk::Error::BufferTooShort {
1442                required: v,
1443                had: rem.len(),
1444            }
1445            .into());
1446        }
1447        let buf: &'b [u8] = &rem[..v];
1448        let rem: &'b [u8] = &rem[v..];
1449        let (m, empty): (M, &'a [u8]) = <M as Unpackable<'a>>::unpack(buf)?;
1450        // TODO(rescrv): assert is nasty
1451        assert_eq!(0, empty.len());
1452        Ok((Self(m), rem))
1453    }
1454}
1455
1456impl<M: Default> Default for message<M> {
1457    fn default() -> Self {
1458        message::from_native(M::default())
1459    }
1460}
1461
1462/////////////////////////////////////////////// tests //////////////////////////////////////////////
1463
1464#[cfg(test)]
1465mod tests {
1466    use std::fmt::Debug;
1467
1468    use crate::field_types::*;
1469
1470    // expect is the body of the field, including length prefix if necessary.
1471    fn helper_test<'a, T, H>(value: H, expect: &'a [u8])
1472    where
1473        T: Clone + FieldType<'a> + Unpackable<'a>,
1474        H: Debug + Default + Eq + From<T> + FieldPackHelper<'a, T> + FieldUnpackHelper<'a, T>,
1475    {
1476        // tag
1477        let tag = Tag {
1478            field_number: FieldNumber::must(1),
1479            wire_type: T::WIRE_TYPE,
1480        };
1481        // pack_sz
1482        assert_eq!(1 + expect.len(), value.field_pack_sz(&tag));
1483        // pack
1484        let mut output: Vec<u8> = vec![0; 1 + expect.len()];
1485        value.field_pack(&tag, &mut output);
1486        assert_eq!(expect, &output[1..]);
1487        // unpack
1488        let mut up = Unpacker::new(expect);
1489        let unpacked: T = match up.unpack() {
1490            Ok(x) => x,
1491            Err(_) => {
1492                panic!("up.unpack() failed");
1493            }
1494        };
1495        let mut field = H::default();
1496        field.merge_field(unpacked.clone());
1497        assert_eq!(value, field);
1498    }
1499
1500    #[test]
1501    fn int32() {
1502        helper_test::<int32, i32>(
1503            i32::MIN,
1504            &[0x80, 0x80, 0x80, 0x80, 0xf8, 0xff, 0xff, 0xff, 0xff, 1],
1505        );
1506        helper_test::<int32, i32>(
1507            -1,
1508            &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1],
1509        );
1510        helper_test::<int32, i32>(0, &[0]);
1511        helper_test::<int32, i32>(1, &[1]);
1512        helper_test::<int32, i32>(i32::MAX, &[0xff, 0xff, 0xff, 0xff, 0x07]);
1513    }
1514
1515    #[test]
1516    fn int64() {
1517        helper_test::<int64, i64>(
1518            i64::MIN,
1519            &[0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 1],
1520        );
1521        helper_test::<int64, i64>(
1522            -1,
1523            &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1],
1524        );
1525        helper_test::<int64, i64>(0, &[0]);
1526        helper_test::<int64, i64>(1, &[1]);
1527        helper_test::<int64, i64>(
1528            i64::MAX,
1529            &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f],
1530        );
1531    }
1532
1533    #[test]
1534    fn uint32() {
1535        helper_test::<uint32, u32>(0, &[0]);
1536        helper_test::<uint32, u32>(1, &[1]);
1537        helper_test::<uint32, u32>(u32::MAX, &[0xff, 0xff, 0xff, 0xff, 0x0f]);
1538    }
1539
1540    #[test]
1541    fn uint64() {
1542        helper_test::<uint64, u64>(0, &[0]);
1543        helper_test::<uint64, u64>(1, &[1]);
1544        helper_test::<uint64, u64>(
1545            u64::MAX,
1546            &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1],
1547        );
1548    }
1549
1550    #[test]
1551    fn sint32() {
1552        helper_test::<sint32, i32>(i32::MIN, &[0xff, 0xff, 0xff, 0xff, 0x0f]);
1553        helper_test::<sint32, i32>(-1, &[1]);
1554        helper_test::<sint32, i32>(0, &[0]);
1555        helper_test::<sint32, i32>(1, &[2]);
1556        helper_test::<sint32, i32>(i32::MAX, &[0xfe, 0xff, 0xff, 0xff, 0x0f]);
1557    }
1558
1559    #[test]
1560    fn sint64() {
1561        helper_test::<sint64, i64>(
1562            i64::MIN,
1563            &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1],
1564        );
1565        helper_test::<sint64, i64>(-1, &[1]);
1566        helper_test::<sint64, i64>(0, &[0]);
1567        helper_test::<sint64, i64>(1, &[2]);
1568        helper_test::<sint64, i64>(
1569            i64::MAX,
1570            &[0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1],
1571        );
1572    }
1573
1574    #[test]
1575    fn fixed32() {
1576        helper_test::<fixed32, u32>(0, &[0, 0, 0, 0]);
1577        helper_test::<fixed32, u32>(1, &[1, 0, 0, 0]);
1578        helper_test::<fixed32, u32>(u32::MAX, &[0xff, 0xff, 0xff, 0xff]);
1579    }
1580
1581    #[test]
1582    fn fixed64() {
1583        helper_test::<fixed64, u64>(0, &[0, 0, 0, 0, 0, 0, 0, 0]);
1584        helper_test::<fixed64, u64>(1, &[1, 0, 0, 0, 0, 0, 0, 0]);
1585        helper_test::<fixed64, u64>(u64::MAX, &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
1586    }
1587
1588    #[test]
1589    fn sfixed32() {
1590        helper_test::<sfixed32, i32>(i32::MIN, &[0, 0, 0, 0x80]);
1591        helper_test::<sfixed32, i32>(-1, &[0xff, 0xff, 0xff, 0xff]);
1592        helper_test::<sfixed32, i32>(0, &[0, 0, 0, 0]);
1593        helper_test::<sfixed32, i32>(1, &[1, 0, 0, 0]);
1594        helper_test::<sfixed32, i32>(i32::MAX, &[0xff, 0xff, 0xff, 0x7f]);
1595    }
1596
1597    #[test]
1598    fn sfixed64() {
1599        helper_test::<sfixed64, i64>(i64::MIN, &[0, 0, 0, 0, 0, 0, 0, 0x80]);
1600        helper_test::<sfixed64, i64>(-1, &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
1601        helper_test::<sfixed64, i64>(0, &[0, 0, 0, 0, 0, 0, 0, 0]);
1602        helper_test::<sfixed64, i64>(1, &[1, 0, 0, 0, 0, 0, 0, 0]);
1603        helper_test::<sfixed64, i64>(i64::MAX, &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]);
1604    }
1605
1606    #[test]
1607    fn float() {
1608        let value = std::f32::consts::PI;
1609        let expect = &[0xdb, 0xf, 0x49, 0x40];
1610
1611        // tag
1612        let tag = Tag {
1613            field_number: FieldNumber::must(1),
1614            wire_type: float::WIRE_TYPE,
1615        };
1616        // pack_sz
1617        assert_eq!(1 + expect.len(), value.field_pack_sz(&tag));
1618        // pack
1619        let mut output: Vec<u8> = vec![0; 1 + expect.len()];
1620        value.field_pack(&tag, &mut output);
1621        assert_eq!(expect, &output[1..]);
1622        // unpack
1623        let mut up = Unpacker::new(expect);
1624        let unpacked: float = match up.unpack() {
1625            Ok(x) => x,
1626            Err(_) => {
1627                panic!("up.unpack() failed");
1628            }
1629        };
1630        let mut field: f32 = f32::default();
1631        field.merge_field(unpacked.clone());
1632        assert!(field * 0.9999 < value && field * 1.0001 > value);
1633    }
1634
1635    #[test]
1636    fn double() {
1637        let value = std::f64::consts::PI;
1638        let expect = &[0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x9, 0x40];
1639
1640        // tag
1641        let tag = Tag {
1642            field_number: FieldNumber::must(1),
1643            wire_type: double::WIRE_TYPE,
1644        };
1645        // pack_sz
1646        assert_eq!(1 + expect.len(), value.field_pack_sz(&tag));
1647        // pack
1648        let mut output: Vec<u8> = vec![0; 1 + expect.len()];
1649        value.field_pack(&tag, &mut output);
1650        assert_eq!(expect, &output[1..]);
1651        // unpack
1652        let mut up = Unpacker::new(expect);
1653        let unpacked: double = match up.unpack() {
1654            Ok(x) => x,
1655            Err(_) => {
1656                panic!("up.unpack() failed");
1657            }
1658        };
1659        let mut field: f64 = f64::default();
1660        field.merge_field(unpacked.clone());
1661        assert!(field * 0.9999 < value && field * 1.0001 > value);
1662    }
1663
1664    #[test]
1665    #[allow(non_snake_case)]
1666    fn Bool() {
1667        helper_test::<Bool, bool>(false, &[0]);
1668        helper_test::<Bool, bool>(true, &[1]);
1669    }
1670
1671    #[test]
1672    fn bytes() {
1673        helper_test::<bytes, &[u8]>(&[0xff, 0x00], &[0x2, 0xff, 0x00]);
1674        helper_test::<bytes, Vec<u8>>(vec![0xff, 0x00], &[0x2, 0xff, 0x00]);
1675    }
1676
1677    #[test]
1678    fn bytes16() {
1679        let mut input: [u8; 16] = [0u8; 16];
1680        let mut expect: Vec<u8> = Vec::new();
1681        expect.push(16);
1682        #[allow(clippy::needless_range_loop)]
1683        for i in 0..16 {
1684            input[i] = i as u8;
1685            expect.push(i as u8);
1686        }
1687        helper_test::<bytes16, [u8; 16]>(input, &expect);
1688    }
1689
1690    #[test]
1691    fn bytes32() {
1692        let mut input: [u8; 32] = [0u8; 32];
1693        let mut expect: Vec<u8> = Vec::new();
1694        expect.push(32);
1695        #[allow(clippy::needless_range_loop)]
1696        for i in 0..32 {
1697            input[i] = i as u8;
1698            expect.push(i as u8);
1699        }
1700        helper_test::<bytes32, [u8; 32]>(input, &expect);
1701    }
1702
1703    #[test]
1704    fn string() {
1705        helper_test::<string, String>(
1706            "string \u{1F600}".to_owned(),
1707            &[
1708                0xb, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0xf0, 0x9f, 0x98, 0x80,
1709            ],
1710        );
1711        helper_test::<string, &str>(
1712            "string \u{1F600}",
1713            &[
1714                0xb, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0xf0, 0x9f, 0x98, 0x80,
1715            ],
1716        );
1717    }
1718}