protospec_build/prelude/
var.rs1use crate::{emit_type_ref, PartialType, PartialScalarType};
2
3use super::*;
4
5pub struct VarInt {
6 scalar_type: ScalarType,
7 unsigned: Type,
8}
9
10impl VarInt {
11 pub fn new(scalar_type: ScalarType) -> Self {
12 VarInt {
13 scalar_type,
14 unsigned: Type::Scalar(match scalar_type {
15 x if !x.is_signed() => x,
16 ScalarType::I8 => ScalarType::U8,
17 ScalarType::I16 => ScalarType::U16,
18 ScalarType::I32 => ScalarType::U32,
19 ScalarType::I64 => ScalarType::U64,
20 ScalarType::I128 => ScalarType::U128,
21 _ => unimplemented!(),
22 }),
23 }
24 }
25}
26
27impl ForeignType for VarInt {
28 fn assignable_from(&self, type_: &Type) -> bool {
29 Type::Scalar(self.scalar_type).assignable_from(type_)
30 }
31
32 fn assignable_from_partial(&self, type_: &PartialType) -> bool {
33 match type_ {
34 PartialType::Type(t) => self.assignable_from(t),
35 PartialType::Scalar(PartialScalarType::Some(scalar)) |
36 PartialType::Scalar(PartialScalarType::Defaults(scalar))
37 => self.assignable_from(&Type::Scalar(*scalar)),
38 _ => false,
39 }
40 }
41
42 fn assignable_to_partial(&self, type_: &PartialType) -> bool {
43 match type_ {
44 PartialType::Type(t) => self.assignable_to(t),
45 PartialType::Any => true,
46 PartialType::Scalar(PartialScalarType::Some(scalar)) => self.assignable_from(&Type::Scalar(*scalar)),
47 PartialType::Scalar(_) => true,
48 _ => false,
49 }
50 }
51
52 fn assignable_to(&self, type_: &Type) -> bool {
53 type_.assignable_from(&Type::Scalar(self.scalar_type))
54 }
55
56 fn type_ref(&self) -> TokenStream {
57 emit_type_ref(&Type::Scalar(self.scalar_type))
58 }
59
60 fn decoding_gen(
61 &self,
62 source: TokenStream,
63 output_ref: TokenStream,
64 _arguments: Vec<TokenStream>,
65 is_async: bool,
66 ) -> TokenStream {
67 let inner = self.type_ref();
68 let end = (self.scalar_type.size() as f64 / 7.0).ceil() as usize;
69 let inner_unsigned = emit_type_ref(&self.unsigned);
70 let async_ = map_async(is_async);
71 quote! {
72 let #output_ref = {
73 let mut i = 0usize;
74 let mut buf = [0xffu8; 1];
75 let mut output: #inner = 0;
76 while (buf[0] & 128) == 128 {
77 #source.read_exact(&mut buf[..])#async_?;
78 output |= ((buf[0] as #inner_unsigned & 127) << (i * 7)) as #inner;
79 i += 1;
80 if i > #end {
81 break;
82 }
83 }
84 output
85 };
86 }
87 }
88
89 fn encoding_gen(
90 &self,
91 target: TokenStream,
92 field_ref: TokenStream,
93 _arguments: Vec<TokenStream>,
94 is_async: bool,
95 ) -> TokenStream {
96 let inner_unsigned = emit_type_ref(&self.unsigned);
97 let async_ = map_async(is_async);
98 quote! {
99 {
100 let mut value = #field_ref.clone() as #inner_unsigned;
101 while (value & !0b1111111) != 0 {
102 #target.write_all(&[(value as u8 & 127) | 128])#async_?;
103 value >>= 7;
104 }
105 #target.write_all(&[value as u8])#async_?;
106 }
107 }
108 }
109
110 fn arguments(&self) -> Vec<TypeArgument> {
111 vec![]
112 }
113
114 fn can_receive_auto(&self) -> Option<ScalarType> {
115 Some(self.scalar_type)
116 }
117}