protospec_build/prelude/
len.rs

1use super::*;
2
3pub struct LenFunction;
4
5impl LenFunction {
6    fn len(&self, type_: &Type, value: &TokenStream) -> TokenStream {
7        match &type_ {
8            Type::Container(_) => panic!("cannot call len on container"),
9            Type::Enum(e) => {
10                let size = e.rep.size();
11                quote! {
12                    #size
13                }
14            }
15            Type::Bitfield(e) => {
16                let size = e.rep.size();
17                quote! {
18                    #size
19                }
20            }
21            Type::F32 => quote! { 4u64 },
22            Type::F64 => quote! { 8u64 },
23            Type::Bool => quote! { 1u64 },
24            Type::Scalar(s) => {
25                let size = s.size();
26                quote! {
27                    #size
28                }
29            }
30            Type::Array(_) | Type::Foreign(_) => {
31                quote! {
32                    (#value).len() as u64
33                }
34            }
35            Type::Ref(type_call) => self.len(&*type_call.target.type_.borrow(), value),
36        }
37    }
38}
39
40impl ForeignFunction for LenFunction {
41    fn arguments(&self) -> Vec<FFIArgument> {
42        vec![FFIArgument {
43            name: "list".to_string(),
44            type_: None,
45            optional: false,
46        }]
47    }
48
49    fn return_type(&self) -> Type {
50        Type::Scalar(ScalarType::U64)
51    }
52
53    fn call(&self, arguments: &[FFIArgumentValue]) -> TokenStream {
54        self.len(&arguments[0].type_, &arguments[0].value)
55    }
56}