mirror of
https://github.com/kristoferssolo/filecaster.git
synced 2025-10-21 19:00:34 +00:00
feat: handle error cases
This commit is contained in:
parent
0d4abce168
commit
f8527d60e7
@ -5,9 +5,15 @@ use unsynn::*;
|
|||||||
pub fn parse_from_file_default_attr(attrs: &[Attribute]) -> Result<Option<TokenStream>> {
|
pub fn parse_from_file_default_attr(attrs: &[Attribute]) -> Result<Option<TokenStream>> {
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
if attr.path == "from_file" {
|
if attr.path == "from_file" {
|
||||||
return extract_default_token(attr.tokens.clone())
|
let tokens = attr.tokens.clone();
|
||||||
.map(Some)
|
let iter = tokens.clone().into_token_iter();
|
||||||
.ok_or_else(|| Error::no_error()); // TODO: different error
|
|
||||||
|
match extract_default_token(tokens) {
|
||||||
|
Some(ts) => return Ok(Some(ts)),
|
||||||
|
None => {
|
||||||
|
return Error::other(&iter, "missing default value in #[from_file]".into());
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
|||||||
@ -97,14 +97,43 @@
|
|||||||
mod from_file;
|
mod from_file;
|
||||||
|
|
||||||
use crate::from_file::impl_from_file;
|
use crate::from_file::impl_from_file;
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream as ProcTokenStream;
|
||||||
|
use quote::quote;
|
||||||
|
use unsynn::*;
|
||||||
|
|
||||||
/// Implements the [`FromFile`] trait.
|
/// Implements the [`FromFile`] trait.
|
||||||
///
|
///
|
||||||
/// This macro processes the `#[from_file]` attribute on structs to generate
|
/// This macro processes the `#[from_file]` attribute on structs to generate
|
||||||
/// code for loading data from files.
|
/// code for loading data from files.
|
||||||
#[proc_macro_derive(FromFile, attributes(from_file))]
|
#[proc_macro_derive(FromFile, attributes(from_file))]
|
||||||
pub fn derive_from_file(input: TokenStream) -> TokenStream {
|
pub fn derive_from_file(input: ProcTokenStream) -> ProcTokenStream {
|
||||||
let ts = input.into();
|
let ts = input.into();
|
||||||
impl_from_file(ts).unwrap().into()
|
match impl_from_file(ts) {
|
||||||
|
Ok(ts) => ts.into(),
|
||||||
|
Err(e) => error_to_compile_error(&e).into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn error_to_compile_error(err: &Error) -> TokenStream {
|
||||||
|
let msg = format_error(err);
|
||||||
|
quote! {
|
||||||
|
compile_error!(#msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_error(err: &Error) -> String {
|
||||||
|
let pos = err.pos();
|
||||||
|
match &err.kind {
|
||||||
|
ErrorKind::NoError => {
|
||||||
|
format!("FromFile derive failed (internal): no error recorded (pos={pos})")
|
||||||
|
}
|
||||||
|
ErrorKind::UnexpectedToken {
|
||||||
|
expected,
|
||||||
|
at: _iter,
|
||||||
|
} => {
|
||||||
|
format!("FromFile derive parse error: expected {expected} at position {pos}",)
|
||||||
|
}
|
||||||
|
ErrorKind::Other { reason } => format!("FromFile derive error: {reason} (pos={pos})"),
|
||||||
|
ErrorKind::Dynamic(inner) => format!("FromFile derive dynamic error: {inner} (pos={pos})"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user