feat: handle error cases

This commit is contained in:
Kristofers Solo 2025-09-12 19:51:06 +03:00
parent 0d4abce168
commit f8527d60e7
Signed by: kristoferssolo
GPG Key ID: 8687F2D3EEE6F0ED
2 changed files with 41 additions and 6 deletions

View File

@ -5,9 +5,15 @@ use unsynn::*;
pub fn parse_from_file_default_attr(attrs: &[Attribute]) -> Result<Option<TokenStream>> {
for attr in attrs {
if attr.path == "from_file" {
return extract_default_token(attr.tokens.clone())
.map(Some)
.ok_or_else(|| Error::no_error()); // TODO: different error
let tokens = attr.tokens.clone();
let iter = tokens.clone().into_token_iter();
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)

View File

@ -97,14 +97,43 @@
mod 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.
///
/// This macro processes the `#[from_file]` attribute on structs to generate
/// code for loading data from files.
#[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();
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})"),
}
}