use proc_macro2::{Span, TokenStream as TokenStream2};
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum CodegenError {
#[error("Could not find type with ID {0} in the type registry; please raise a support issue.")]
TypeNotFound(u32),
#[error("Failed to fetch metadata, make sure that you're pointing at a node which is providing substrate-based metadata: {0}")]
Fetch(#[from] FetchMetadataError),
#[error("Failed IO for {0}, make sure that you are providing the correct file path for metadata: {1}")]
Io(String, std::io::Error),
#[error("Could not decode metadata, only V14 and V15 metadata are supported: {0}")]
Decode(#[from] codec::Error),
#[error("Out-of-line subxt modules are not supported, make sure you are providing a body to your module: pub mod polkadot {{ ... }}")]
InvalidModule(Span),
#[error("Fields should either be all named or all unnamed, make sure you are providing a valid metadata: {0}")]
InvalidFields(String),
#[error("Type substitution error: {0}")]
TypeSubstitutionError(#[from] TypeSubstitutionError),
#[error("Invalid type path {0}: {1}")]
InvalidTypePath(String, syn::Error),
#[error("Metadata for constant entry {0}_{1} could not be found. Make sure you are providing a valid substrate-based metadata")]
MissingConstantMetadata(String, String),
#[error("Metadata for storage entry {0}_{1} could not be found. Make sure you are providing a valid substrate-based metadata")]
MissingStorageMetadata(String, String),
#[error("Metadata for call entry {0}_{1} could not be found. Make sure you are providing a valid substrate-based metadata")]
MissingCallMetadata(String, String),
#[error("Metadata for runtime API entry {0}_{1} could not be found. Make sure you are providing a valid substrate-based metadata")]
MissingRuntimeApiMetadata(String, String),
#[error("Call variant for type {0} must have all named fields. Make sure you are providing a valid substrate-based metadata")]
InvalidCallVariant(u32),
#[error(
"{0} type should be an variant/enum type. Make sure you are providing a valid substrate-based metadata"
)]
InvalidType(String),
#[error(
"Extrinsic call type could not be found. Make sure you are providing a valid substrate-based metadata"
)]
MissingCallType,
}
impl CodegenError {
fn get_location(&self) -> Span {
match self {
Self::InvalidModule(span) => *span,
Self::TypeSubstitutionError(err) => err.get_location(),
Self::InvalidTypePath(_, err) => err.span(),
_ => proc_macro2::Span::call_site(),
}
}
pub fn into_compile_error(self) -> TokenStream2 {
let msg = self.to_string();
let span = self.get_location();
syn::Error::new(span, msg).into_compile_error()
}
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum FetchMetadataError {
#[error("Cannot decode hex value: {0}")]
DecodeError(#[from] hex::FromHexError),
#[error("Cannot scale encode/decode value: {0}")]
CodecError(#[from] codec::Error),
#[cfg(feature = "fetch-metadata")]
#[error("Request error: {0}")]
RequestError(#[from] jsonrpsee::core::Error),
#[error("'{0}' not supported, supported URI schemes are http, https, ws or wss.")]
InvalidScheme(String),
#[error("Other error: {0}")]
Other(String),
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum TypeSubstitutionError {
#[error("`substitute_type(with = <path>)` must be a path prefixed with 'crate::' or '::'")]
ExpectedAbsolutePath(Span),
#[error("Substitute types must have a valid path.")]
EmptySubstitutePath(Span),
#[error("Expected the from/to type generics to have the form 'Foo<A,B,C..>'.")]
ExpectedAngleBracketGenerics(Span),
#[error("Expected an ident like 'Foo' or 'A' to mark a type to be substituted.")]
InvalidFromType(Span),
#[error("Expected an ident like 'Foo' or an absolute concrete path like '::path::to::Bar' for the substitute type.")]
InvalidToType(Span),
#[error("Cannot find matching param on 'from' type.")]
NoMatchingFromType(Span),
}
impl TypeSubstitutionError {
fn get_location(&self) -> Span {
match self {
TypeSubstitutionError::ExpectedAbsolutePath(span) => *span,
TypeSubstitutionError::EmptySubstitutePath(span) => *span,
TypeSubstitutionError::ExpectedAngleBracketGenerics(span) => *span,
TypeSubstitutionError::InvalidFromType(span) => *span,
TypeSubstitutionError::InvalidToType(span) => *span,
TypeSubstitutionError::NoMatchingFromType(span) => *span,
}
}
}