daml_codegen/renderer/data_renderer/full/
quote_generic_common.rs

1use daml_lf::element::{DamlKind, DamlTypeVarWithKind};
2use proc_macro2::TokenStream;
3
4use crate::renderer::{normalize_generic_param, quote_ident};
5use quote::quote;
6
7/// Quote `<A, B, C>`
8pub fn quote_unbounded_params(params: &[DamlTypeVarWithKind<'_>]) -> TokenStream {
9    quote_non_empty(params, |params| {
10        let all_params_tokens: Vec<_> = params.iter().map(|type_var| quote_var(type_var.var())).collect();
11        quote!( < #( #all_params_tokens ),* > )
12    })
13}
14
15/// Quote `<A, B: Nat, C>`
16pub fn quote_bounded_params(params: &[DamlTypeVarWithKind<'_>]) -> TokenStream {
17    quote_non_empty(params, |params| {
18        let all_bounds_tokens: Vec<_> = params.iter().map(quote_type_var).collect();
19        quote!( < #( #all_bounds_tokens ),* > )
20    })
21}
22
23/// Quote `where A: DamlSerializeInto<DamlValue>, B: DamlSerializeInto<DamlValue> + Nat`
24pub fn quote_serialize_where(params: &[DamlTypeVarWithKind<'_>]) -> TokenStream {
25    quote_where_clause(params, quote!(DamlSerializeInto<DamlValue>))
26}
27
28/// Quote `where A: DamlDeserializeFrom + Ord, B: DamlDeserializeFrom + Ord + Nat`
29pub fn quote_deserialize_where(params: &[DamlTypeVarWithKind<'_>]) -> TokenStream {
30    quote_where_clause(params, quote!(DamlDeserializeFrom + Ord))
31}
32
33fn quote_where_clause(params: &[DamlTypeVarWithKind<'_>], bound_tokens: TokenStream) -> TokenStream {
34    quote_non_empty(params, |params| {
35        let all_bounds_tokens: Vec<_> =
36            params.iter().map(|type_var| quote_type_var_with_bound(type_var, &bound_tokens)).collect();
37        quote!( where #( #all_bounds_tokens ),* )
38    })
39}
40
41fn quote_type_var(type_var: &DamlTypeVarWithKind<'_>) -> TokenStream {
42    let var_tokens = quote_var(type_var.var());
43    if let DamlKind::Nat = type_var.kind() {
44        quote!(#var_tokens: Nat)
45    } else {
46        quote!(#var_tokens)
47    }
48}
49
50fn quote_type_var_with_bound(type_var: &DamlTypeVarWithKind<'_>, bound: &TokenStream) -> TokenStream {
51    let var_tokens = quote_var(type_var.var());
52    if let DamlKind::Nat = type_var.kind() {
53        quote!(#var_tokens: #bound + Nat)
54    } else {
55        quote!(#var_tokens: #bound)
56    }
57}
58
59fn quote_var(var: &str) -> TokenStream {
60    quote_ident(normalize_generic_param(var).to_uppercase())
61}
62
63fn quote_non_empty<F>(params: &[DamlTypeVarWithKind<'_>], f: F) -> TokenStream
64where
65    F: Fn(&[DamlTypeVarWithKind<'_>]) -> TokenStream,
66{
67    if params.is_empty() {
68        quote!()
69    } else {
70        f(params)
71    }
72}