Derive derives on Error not ErrorKind
This commit is contained in:
parent
4cb572f64c
commit
1d81b59163
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ctxerr"
|
||||
version = "0.2.0"
|
||||
version = "0.2.3"
|
||||
authors = ["Andrey Tkachenko <andrey@aidev.ru>"]
|
||||
repository = "https://github.com/andreytkachenko/ctxerr.git"
|
||||
keywords = ["error", "handling", "thiserror", "context", "backtrace"]
|
||||
@ -15,5 +15,5 @@ resolver = "2"
|
||||
members = ["derive"]
|
||||
|
||||
[dependencies]
|
||||
ctxerr_derive = {version = "0.3.0", path = "derive"}
|
||||
thiserror = "1.0.39"
|
||||
ctxerr_derive = {version = "0.4.0", path = "derive"}
|
||||
thiserror = "1.0.40"
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ctxerr_derive"
|
||||
version = "0.3.0"
|
||||
version = "0.4.0"
|
||||
authors = ["Andrey Tkachenko <andrey@aidev.ru>"]
|
||||
repository = "https://github.com/andreytkachenko/ctxerr.git"
|
||||
keywords = ["error", "handling", "thiserror", "context", "backtrace"]
|
||||
@ -16,4 +16,4 @@ proc-macro = true
|
||||
[dependencies]
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
syn = {version = "1", features = ["full"]}
|
||||
syn = {version = "2", features = ["full"]}
|
||||
|
@ -11,7 +11,7 @@ pub fn ctxerr(
|
||||
_metadata: proc_macro::TokenStream,
|
||||
input: proc_macro::TokenStream,
|
||||
) -> proc_macro::TokenStream {
|
||||
let ast: DeriveInput = syn::parse(input).unwrap();
|
||||
let mut ast: DeriveInput = syn::parse(input).unwrap();
|
||||
let name = ast.ident.to_string();
|
||||
if !name.ends_with("Kind") {
|
||||
panic!("Ttypename should ends with `Kind`!");
|
||||
@ -19,53 +19,69 @@ pub fn ctxerr(
|
||||
|
||||
let name_ident = &ast.ident;
|
||||
let base_name = Ident::new(&name[0..name.len() - 4], ast.ident.span());
|
||||
let attrs = ast
|
||||
.attrs
|
||||
.drain(..)
|
||||
.filter_map(|x| match x.meta {
|
||||
syn::Meta::List(list) => Some(list.tokens),
|
||||
_ => None,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let tokens = quote! {
|
||||
#[derive(Debug, ctxerr::thiserror::Error)]
|
||||
#ast
|
||||
pub use __private::*;
|
||||
|
||||
#[derive(ctxerr::thiserror::Error)]
|
||||
pub struct #base_name {
|
||||
kind: #name_ident,
|
||||
backtrace: Option<std::backtrace::Backtrace>,
|
||||
location: Option<&'static core::panic::Location<'static>>,
|
||||
}
|
||||
mod __private {
|
||||
use super::*;
|
||||
use ctxerr::thiserror;
|
||||
|
||||
impl std::fmt::Debug for #base_name {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
writeln!(f, "{:?}: {}", self.kind, self.kind)?;
|
||||
if let Some(b) = &self.backtrace {
|
||||
writeln!(f, "backtrace: \n{}", b)?;
|
||||
}
|
||||
#[derive(Debug, ctxerr::thiserror::Error)]
|
||||
#ast
|
||||
|
||||
Ok(())
|
||||
#[derive(ctxerr::thiserror::Error #(, #attrs)*)]
|
||||
pub struct #base_name {
|
||||
kind: #name_ident,
|
||||
backtrace: Option<std::backtrace::Backtrace>,
|
||||
location: Option<&'static core::panic::Location<'static>>,
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for #base_name {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{:?}: {}", self.kind, self.kind)?;
|
||||
if let Some(loc) = self.location {
|
||||
writeln!(f, " file: {}:{}:{}", loc.file(), loc.line(), loc.column())?;
|
||||
} else {
|
||||
writeln!(f)?;
|
||||
impl std::fmt::Debug for #base_name {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
writeln!(f, "{:?}: {}", self.kind, self.kind)?;
|
||||
if let Some(b) = &self.backtrace {
|
||||
writeln!(f, "backtrace: \n{}", b)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
if let Some(b) = &self.backtrace {
|
||||
writeln!(f, "backtrace: \n{}", b)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<ErrorKind>> From<T> for #base_name {
|
||||
#[track_caller]
|
||||
fn from(val: T) -> Self {
|
||||
let b = std::backtrace::Backtrace::capture();
|
||||
Self{
|
||||
kind: val.into(),
|
||||
backtrace: Some(std::backtrace::Backtrace::capture()),
|
||||
location: Some(core::panic::Location::caller()),
|
||||
impl std::fmt::Display for #base_name {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{:?}: {}", self.kind, self.kind)?;
|
||||
if let Some(loc) = self.location {
|
||||
writeln!(f, " file: {}:{}:{}", loc.file(), loc.line(), loc.column())?;
|
||||
} else {
|
||||
writeln!(f)?;
|
||||
}
|
||||
|
||||
if let Some(b) = &self.backtrace {
|
||||
writeln!(f, "backtrace: \n{}", b)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<ErrorKind>> From<T> for #base_name {
|
||||
#[track_caller]
|
||||
fn from(val: T) -> Self {
|
||||
let b = std::backtrace::Backtrace::capture();
|
||||
Self{
|
||||
kind: val.into(),
|
||||
backtrace: Some(std::backtrace::Backtrace::capture()),
|
||||
location: Some(core::panic::Location::caller()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user