summaryrefslogtreecommitdiff
path: root/subplotlib-derive/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'subplotlib-derive/src/lib.rs')
-rw-r--r--subplotlib-derive/src/lib.rs54
1 files changed, 39 insertions, 15 deletions
diff --git a/subplotlib-derive/src/lib.rs b/subplotlib-derive/src/lib.rs
index 7fd1810..8e18c98 100644
--- a/subplotlib-derive/src/lib.rs
+++ b/subplotlib-derive/src/lib.rs
@@ -1,5 +1,6 @@
use proc_macro::TokenStream;
use proc_macro2::Span;
+use std::fmt::Write;
use syn::{
parse_macro_input, parse_quote, Error, FnArg, Ident, ItemFn, Pat, PathArguments, ReturnType,
Type,
@@ -7,7 +8,7 @@ use syn::{
use quote::quote;
-use fehler::{throw, throws};
+use culpa::{throw, throws};
fn ty_is_borrow_str(ty: &Type) -> bool {
if let Type::Reference(ty) = ty {
@@ -28,6 +29,25 @@ fn ty_is_borrow_str(ty: &Type) -> bool {
}
}
+fn ty_is_borrow_path(ty: &Type) -> bool {
+ if let Type::Reference(ty) = ty {
+ if ty.mutability.is_none() && ty.lifetime.is_none() {
+ if let Type::Path(pp) = &*ty.elem {
+ pp.path.is_ident("Path")
+ } else {
+ // not a path, so not &Path
+ false
+ }
+ } else {
+ // mutable, or a lifetime stated, so not &Path
+ false
+ }
+ } else {
+ // Not & so not &Path
+ false
+ }
+}
+
fn ty_is_datafile(ty: &Type) -> bool {
if let Type::Path(ty) = ty {
ty.path.is_ident("SubplotDataFile")
@@ -189,19 +209,19 @@ fn process_step(mut input: ItemFn) -> proc_macro2::TokenStream {
let contexts: Vec<Type> = input
.attrs
.iter()
- .filter(|attr| attr.path.is_ident("context"))
+ .filter(|attr| attr.path().is_ident("context"))
.map(|attr| {
let ty: Type = attr.parse_args()?;
Ok(ty)
})
.collect::<Result<_, Error>>()?;
- input.attrs.retain(|f| !f.path.is_ident("context"));
+ input.attrs.retain(|f| !f.path().is_ident("context"));
let docs: Vec<_> = input
.attrs
.iter()
- .filter(|attr| attr.path.is_ident("doc"))
+ .filter(|attr| attr.path().is_ident("doc"))
.collect();
let fields = input
@@ -241,6 +261,8 @@ fn process_step(mut input: ItemFn) -> proc_macro2::TokenStream {
.map(|(id, ty)| {
let ty = if ty_is_borrow_str(ty) {
parse_quote!(::std::string::String)
+ } else if ty_is_borrow_path(ty) {
+ parse_quote!(::std::path::PathBuf)
} else {
ty.clone()
};
@@ -277,6 +299,13 @@ fn process_step(mut input: ItemFn) -> proc_macro2::TokenStream {
self
}
}
+ } else if ty_is_borrow_path(ty) {
+ quote! {
+ pub fn #id<P: Into<std::path::PathBuf>>(mut self, value: P) -> Self {
+ self.#id = value.into();
+ self
+ }
+ }
} else {
quote! {
pub fn #id(mut self, value: #ty) -> Self {
@@ -291,7 +320,7 @@ fn process_step(mut input: ItemFn) -> proc_macro2::TokenStream {
let buildargs: Vec<_> = fields
.iter()
.map(|(id, ty)| {
- if ty_is_borrow_str(ty) {
+ if ty_is_borrow_str(ty) || ty_is_borrow_path(ty) {
quote! {
&self.#id
}
@@ -321,10 +350,11 @@ fn process_step(mut input: ItemFn) -> proc_macro2::TokenStream {
impl Builder {
#(#fieldfns)*
- pub fn build(self, step_text: String) -> ScenarioStep {
+ pub fn build(self, step_text: String, location: &'static str) -> ScenarioStep {
ScenarioStep::new(step_text, move |ctx, _defuse_poison|
#builder_body,
- |scenario| register_contexts(scenario)
+ |scenario| register_contexts(scenario),
+ location,
)
}
}
@@ -372,12 +402,9 @@ fn process_step(mut input: ItemFn) -> proc_macro2::TokenStream {
Some(&contexttype)
};
for context in outer_ctx.into_iter().chain(contexts.iter()) {
- contextattrs.push_str(&format!("\n #[context({:?})]", ty_as_path(context)?));
+ write!(contextattrs, "\n #[context({:?})]", ty_as_path(context)?).unwrap();
}
- let func_args: Vec<_> = fields
- .iter()
- .map(|(ident, _)| format!("{}", ident))
- .collect();
+ let func_args: Vec<_> = fields.iter().map(|(ident, _)| format!("{ident}")).collect();
let func_args = func_args.join(", ");
format!(
r#"
@@ -395,9 +422,6 @@ fn process_step(mut input: ItemFn) -> proc_macro2::TokenStream {
}}
```
"#,
- stepname = stepname,
- contextattrs = contextattrs,
- func_args = func_args,
)
};
let ret = quote! {