1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
use derives::DerivesRegistry;
use proc_macro2::Ident;
use quote::{quote, ToTokens};
use substitutes::TypeSubstitutes;
use syn::parse_quote;
use self::substitutes::absolute_path;
/// Settings for which derives should be applied on types
pub mod derives;
/// Settings for which types should be substituted by other types.
pub mod substitutes;
/// A struct containing all the settings for generating rust types from a type registry.
#[derive(Debug, Clone)]
pub struct TypeGeneratorSettings {
/// The name of the module which will contain the generated types.
pub types_mod_ident: Ident,
/// If false, no docs are generated for the types.
pub should_gen_docs: bool,
/// Derive traits on generated types.
pub derives: DerivesRegistry,
/// User defined overrides for generated types.
pub substitutes: TypeSubstitutes,
/// Two generic parameters are expected on this type:
/// - Store (e.g. `u8`/`u16`/`u32`/`u64`)
/// - Order (e.g. LSB, MSB)
///
/// subxt provides a `subxt::utils::DecodedBits` that can be used here.
pub decoded_bits_type_path: Option<syn::Path>,
/// TypePath to the CompactAs trait/derive macro.
/// E.g. `subxt::ext::codec::CompactAs`
pub compact_as_type_path: Option<syn::Path>,
/// TypePath to the Compact<T> struct.
/// E.g. `subxt::ext::codec::Compact`
pub compact_type_path: Option<syn::Path>,
/// If false, no codec attributes like `codec(index=0)` and `codec(compact)` are inserted.
/// This is a useful option if we do not want to derive Decode and Encode on our types.
pub insert_codec_attributes: bool,
/// Configure a custom type path for the `alloc` crate, which is the base for generating type paths like
/// `alloc::string::String`, `alloc::vec::Vec` and `alloc::boxed::Box`. The default is `AllocCratePath::Std` which
/// uses the types from the `std` library instead.
pub alloc_crate_path: AllocCratePath,
}
/// Information about how to construct the type paths for types that need allocation, e.g.
#[derive(Debug, Clone, Default)]
pub enum AllocCratePath {
/// Equivalent to `AllocCratePath::Custom(quote!(::std))`. This is the default.
#[default]
Std,
/// Custom path to the alloc crate, e.g. `::alloc` if `extern crate alloc;` is used
/// or e.g. `::subxt_core::alloc` if the alloc crate is exported from another crate.
///
/// We'd expect the Custom path to export `vec::Vec`, `string::String`, `boxed::Box`
/// and `collections::BTreeMap`.
Custom(syn::Path),
}
impl ToTokens for AllocCratePath {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
match self {
AllocCratePath::Std => quote!(::std).to_tokens(tokens),
AllocCratePath::Custom(alloc_path) => alloc_path.to_tokens(tokens),
}
}
}
impl Default for TypeGeneratorSettings {
fn default() -> Self {
Self {
types_mod_ident: parse_quote!(types),
should_gen_docs: true,
substitutes: TypeSubstitutes::new(),
derives: DerivesRegistry::new(),
decoded_bits_type_path: None,
compact_as_type_path: None,
compact_type_path: None,
insert_codec_attributes: false,
alloc_crate_path: Default::default(),
}
}
}
impl TypeGeneratorSettings {
/// Creates a new `TypeGeneratorSettings`.
pub fn new() -> Self {
Self::default()
}
/// Sets the `type_mod_name` field.
pub fn type_mod_name(mut self, type_mod_name: &str) -> Self {
self.types_mod_ident =
syn::parse_str(type_mod_name).expect("The provided type_mod_name is not a valid ident");
self
}
/// Adds a rule, that a type with path `from` should be replaced with the path `to`.
pub fn substitute(mut self, from: syn::Path, to: syn::Path) -> Self {
self.substitutes
.insert(from, absolute_path(to).unwrap())
.unwrap();
self
}
/// Sets the `compact_as_type_path` field.
pub fn compact_as_type_path(mut self, path: syn::Path) -> Self {
self.compact_as_type_path = Some(path);
self
}
/// Sets the `compact_type_path` field.
pub fn compact_type_path(mut self, path: syn::Path) -> Self {
self.compact_type_path = Some(path);
self
}
/// Sets the `decoded_bits_type_path` field.
pub fn decoded_bits_type_path(mut self, path: syn::Path) -> Self {
self.decoded_bits_type_path = Some(path);
self
}
/// Sets the `should_gen_docs` field.
pub fn should_gen_docs(mut self, should_gen_docs: bool) -> Self {
self.should_gen_docs = should_gen_docs;
self
}
/// Sets the `insert_codec_attributes` field.
pub fn insert_codec_attributes(mut self) -> Self {
self.insert_codec_attributes = true;
self
}
/// Adds some derives for all types.
pub fn add_derives_for_all(
mut self,
derive_paths: impl IntoIterator<Item = syn::Path>,
) -> Self {
self.derives.add_derives_for_all(derive_paths);
self
}
}