protospec_build/prelude/
utf8.rs1use super::*;
2
3pub struct Utf8;
4
5impl ForeignType for Utf8 {
6 fn assignable_from(&self, type_: &Type) -> bool {
7 match type_ {
8 Type::Array(inner) => {
9 let inner = inner.element.type_.borrow();
10 Type::Scalar(ScalarType::U8).assignable_from(&*inner)
11 }
12 _ => false,
13 }
14 }
15
16 fn assignable_to(&self, type_: &Type) -> bool {
17 self.assignable_from(type_)
18 }
19
20 fn type_ref(&self) -> TokenStream {
21 quote! { String }
22 }
23
24 fn decoding_gen(
25 &self,
26 source: TokenStream,
27 output_ref: TokenStream,
28 arguments: Vec<TokenStream>,
29 is_async: bool,
30 ) -> TokenStream {
31 let async_ = map_async(is_async);
32 if let Some(len) = arguments.first() {
33 quote! {
34 let #output_ref = {
35 let t_count = #len as usize;
36 let mut t: Vec<u8> = Vec::with_capacity(t_count);
37 unsafe { t.set_len(t_count); }
38 let t_borrow = &mut t[..];
39 let t_borrow2 = unsafe {
40 let len = t_borrow.len();
41 let ptr = t.as_ptr() as *mut u8;
42 slice::from_raw_parts_mut(ptr, len)
43 };
44 #source.read_exact(&mut t_borrow2[..])#async_?;
45 String::from_utf8(t)?
46 };
47 }
48 } else {
49 quote! {
50 let #output_ref = {
51 let mut t: Vec<u8> = vec![];
52 #source.read_until(0u8, &mut t)#async_?;
53 if t.len() > 0 && t[t.len() - 1] == 0u8 {
54 t.truncate(t.len() - 1);
55 }
56 String::from_utf8(t)?
57 };
58 }
59 }
60 }
61
62 fn encoding_gen(
63 &self,
64 target: TokenStream,
65 field_ref: TokenStream,
66 arguments: Vec<TokenStream>,
67 is_async: bool,
68 ) -> TokenStream {
69 let async_ = map_async(is_async);
70 if let Some(_) = arguments.first() {
71 quote! {
72 {
73 #target.write_all(#field_ref.as_bytes())#async_?;
74 }
75 }
76 } else {
77 quote! {
78 {
79 #target.write_all(#field_ref.as_bytes())#async_?;
80 #target.write_all(&[0u8])#async_?;
81 }
82 }
83 }
84 }
85
86 fn arguments(&self) -> Vec<TypeArgument> {
87 vec![TypeArgument {
88 name: "length".to_string(),
89 type_: Type::Scalar(ScalarType::U64),
90 default_value: Some(u64::MAX.into()),
91 can_resolve_auto: true,
92 }]
93 }
94
95 fn can_receive_auto(&self) -> Option<ScalarType> {
96 None
97 }
98}