scale_typegen/typegen/
type_params.rs1use super::TypeParameter;
6use quote::{format_ident, quote};
7use scale_info::form::PortableForm;
8use std::collections::BTreeSet;
9
10#[derive(Clone, Debug, Default)]
16pub struct TypeParameters {
17 params: Vec<TypeParameter>,
18 unused: BTreeSet<TypeParameter>,
19}
20
21impl TypeParameters {
22 pub fn from_scale_info(params: &[scale_info::TypeParameter<PortableForm>]) -> Self {
24 let params = params
25 .iter()
26 .enumerate()
27 .filter_map(|(i, tp)| {
28 tp.ty.as_ref().map(|ty| {
29 let tp_name = format_ident!("_{}", i);
30 TypeParameter {
31 concrete_type_id: ty.id,
32 original_name: tp.name.clone(),
33 name: tp_name,
34 }
35 })
36 })
37 .collect::<Vec<_>>();
38
39 let unused = params.iter().cloned().collect();
40 Self { params, unused }
41 }
42
43 pub fn unused_params_phantom_data(&self) -> Option<syn::TypePath> {
45 if self.unused.is_empty() {
46 return None;
47 }
48 let params = if self.unused.len() == 1 {
49 let param = self
50 .unused
51 .iter()
52 .next()
53 .expect("Checked for exactly one unused param");
54 quote! { #param }
55 } else {
56 let params = self.unused.iter();
57 quote! { ( #( #params ), * ) }
58 };
59 Some(syn::parse_quote! {::core::marker::PhantomData<#params> })
60 }
61
62 pub fn params(&self) -> &[TypeParameter] {
64 &self.params
65 }
66
67 pub fn has_unused_type_params(&self) -> bool {
69 !self.unused.is_empty()
70 }
71 pub(super) fn mark_used(&mut self, param: &TypeParameter) {
72 self.unused.remove(param);
73 }
74}
75
76impl quote::ToTokens for TypeParameters {
77 fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
78 if !self.params.is_empty() {
79 let params = &self.params;
80 tokens.extend(quote! { < #( #params ),* > })
81 }
82 }
83}