scale_typegen/typegen/
error.rs1use std::collections::HashSet;
2
3use proc_macro2::Span;
4use quote::ToTokens;
5
6#[derive(Debug, thiserror::Error)]
8#[non_exhaustive]
9pub enum TypegenError {
10 #[error("Could not parse '{string}' into syn type {target}: {error}")]
12 SynParseError {
13 string: String,
15 target: &'static str,
17 error: syn::Error,
19 },
20 #[error("Fields should either be all named or all unnamed, make sure you are providing a valid metadata: {0}")]
22 InvalidFields(String),
23 #[error("A type in the metadata was invalid: {0}")]
25 InvalidType(String),
26 #[error("Could not generate a type that contains a compact type, because the Compact type path is not set in the settings.")]
28 CompactPathNone,
29 #[error("Could not generate a type that contains a bit sequence, because the DecodedBits type path is not set in the settings.")]
31 DecodedBitsPathNone,
32 #[error("Could not find type with ID {0} in the type registry.")]
34 TypeNotFound(u32),
35 #[error("Type substitution error: {0}")]
37 InvalidSubstitute(#[from] TypeSubstitutionError),
38 #[error("Settings do not fit the given type registry: {0}")]
40 SettingsValidation(SettingsValidationError),
41 #[error("There are two types with the the same type path {0} but different structure. Use `scale_typegen::utils::ensure_unique_type_paths` on your `PortableRegistry` before, to avoid this error.")]
44 DuplicateTypePath(String),
45 #[error("PortableRegistry entry has incorrect type_id. expected type_id: {expected_ty_id}, got: {given_ty_id}.\nDefinition of the type: {ty_def}.\nThis can happen if registry was modified with calls to `::retain()` in older versions of scale-info. Try generating a new metadata to fix this.")]
47 RegistryTypeIdsInvalid {
48 given_ty_id: u32,
50 expected_ty_id: u32,
52 ty_def: String,
54 },
55}
56
57#[derive(Debug, thiserror::Error)]
59pub struct TypeSubstitutionError {
60 pub span: Span,
62 pub kind: TypeSubstitutionErrorKind,
64}
65
66impl std::fmt::Display for TypeSubstitutionError {
67 fn fmt(
68 &self,
69 f: &mut scale_info::prelude::fmt::Formatter<'_>,
70 ) -> scale_info::prelude::fmt::Result {
71 f.write_fmt(format_args!("{}", self.kind))
72 }
73}
74
75#[derive(Debug, thiserror::Error)]
77#[non_exhaustive]
78pub enum TypeSubstitutionErrorKind {
79 #[error("`substitute_type(with = <path>)` must be a path prefixed with 'crate::' or '::'")]
81 ExpectedAbsolutePath,
82 #[error("Substitute types must have a valid path.")]
84 EmptySubstitutePath,
85 #[error("Expected the from/to type generics to have the form 'Foo<A,B,C..>'.")]
87 ExpectedAngleBracketGenerics,
88 #[error("Expected an ident like 'Foo' or 'A' to mark a type to be substituted.")]
90 InvalidFromType,
91 #[error("Expected an ident like 'Foo' or an absolute concrete path like '::path::to::Bar' for the substitute type.")]
93 InvalidToType,
94 #[error("Cannot find matching param on 'from' type.")]
96 NoMatchingFromType,
97}
98
99#[derive(Debug, thiserror::Error, Default, PartialEq, Eq)]
101pub struct SettingsValidationError {
102 pub derives_for_unknown_types: Vec<(syn::Path, HashSet<syn::Path>)>,
104 pub attributes_for_unknown_types: Vec<(syn::Path, HashSet<syn::Attribute>)>,
106 pub substitutes_for_unknown_types: Vec<(syn::Path, syn::Path)>,
108}
109
110impl std::fmt::Display for SettingsValidationError {
111 fn fmt(
112 &self,
113 f: &mut scale_info::prelude::fmt::Formatter<'_>,
114 ) -> scale_info::prelude::fmt::Result {
115 fn display_one(e: &impl ToTokens) -> String {
116 e.to_token_stream().to_string().replace(' ', "")
117 }
118
119 fn display_many(set: &HashSet<impl ToTokens>) -> String {
120 set.iter()
121 .map(|e| display_one(e))
122 .collect::<Vec<_>>()
123 .join(", ")
124 }
125
126 writeln!(f, "Settings validation error:")?;
127
128 if !self.derives_for_unknown_types.is_empty() {
129 writeln!(f, " Derives for unknown types:")?;
130 for (path, derives) in &self.derives_for_unknown_types {
131 writeln!(
132 f,
133 " {} (Derives: {})",
134 display_one(path),
135 display_many(derives)
136 )?;
137 }
138 }
139
140 if !self.attributes_for_unknown_types.is_empty() {
141 writeln!(f, " Attributes for unknown types:")?;
142 for (path, attributes) in &self.attributes_for_unknown_types {
143 writeln!(
144 f,
145 " {} (Attributes: {})",
146 display_one(path),
147 display_many(attributes)
148 )?;
149 }
150 }
151
152 if !self.substitutes_for_unknown_types.is_empty() {
153 writeln!(f, " Substitutes for unknown types:")?;
154 for (original, substitute) in &self.substitutes_for_unknown_types {
155 writeln!(
156 f,
157 " {} (Substitute: {})",
158 display_one(original),
159 display_one(substitute),
160 )?;
161 }
162 }
163
164 Ok(())
165 }
166}
167
168impl SettingsValidationError {
169 pub(crate) fn is_empty(&self) -> bool {
170 self.derives_for_unknown_types.is_empty()
171 && self.attributes_for_unknown_types.is_empty()
172 && self.substitutes_for_unknown_types.is_empty()
173 }
174}