protospec_build/prelude/
utf16.rs

1use super::*;
2
3pub struct Utf16;
4
5impl ForeignType for Utf16 {
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::U16).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        let len = arguments.first().expect("missing len argument");
33        quote! {
34            let #output_ref = {
35                let t_count = #len as usize;
36                let mut t: Vec<u16> = 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() * 2;
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_utf16(&t[..])?
46            };
47        }
48    }
49
50    fn encoding_gen(
51        &self,
52        target: TokenStream,
53        field_ref: TokenStream,
54        _arguments: Vec<TokenStream>,
55        is_async: bool,
56    ) -> TokenStream {
57        let async_ = map_async(is_async);
58        quote! {
59            {
60                for utf16 in #field_ref.encode_utf16() {
61                    #target.write_all(&utf16.to_be_bytes()[..])#async_?;
62                }
63            }
64        }
65    }
66
67    fn arguments(&self) -> Vec<TypeArgument> {
68        vec![TypeArgument {
69            name: "length".to_string(),
70            type_: Type::Scalar(ScalarType::U64),
71            default_value: None,
72            can_resolve_auto: true,
73        }]
74    }
75
76    fn can_receive_auto(&self) -> Option<ScalarType> {
77        None
78    }
79}