Skip to content

Commit

Permalink
Merge pull request #655 from gabsi26/improve_proc_macro
Browse files Browse the repository at this point in the history
Improve proc macro `model`
  • Loading branch information
hannobraun authored Jun 1, 2022
2 parents 8b6169d + 1ffc086 commit 8719f79
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 58 deletions.
50 changes: 30 additions & 20 deletions crates/fj-proc/src/attributed_arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,37 +18,44 @@ pub fn attributed_arguments(_: TokenStream, input: TokenStream) -> TokenStream {
for arg in args {
let ident = arg.ident;
let ty = arg.ty;

if let Some(default) = arg.attr.get_default() {
let def = default.val;
parameter_extraction.push(quote! {
let #ident: #ty = args.get(stringify!(#ident))
.map(|arg| arg.parse().unwrap())
.unwrap_or(#def);
});
} else {
parameter_extraction.push(quote! {
if let Some(attr) = arg.attr {
if let Some(default) = attr.get_default() {
let def = default.val;
parameter_extraction.push(quote! {
let #ident: #ty = args.get(stringify!(#ident))
.map(|arg| arg.parse().unwrap())
.unwrap_or(#def);
});
} else {
parameter_extraction.push(quote! {
let #ident: #ty = args.get(stringify!(#ident))
.map(|arg| arg.parse().unwrap())
.expect(format!("A value for `{}` has to be provided since no default is specified",stringify!(#ident)).as_str());
});
}
}

if let Some(minimum) = arg.attr.get_minimum() {
let min = minimum.val;
min_checks.push(quote! {
if let Some(minimum) = attr.get_minimum() {
let min = minimum.val;
min_checks.push(quote! {
if #ident < #min {
panic!("Value of `{}` must not be smaller than: {}",stringify!(#ident), #min);
}
});
}
if let Some(maximum) = arg.attr.get_maximum() {
let max = maximum.val;
max_checks.push(quote! {
}
if let Some(maximum) = attr.get_maximum() {
let max = maximum.val;
max_checks.push(quote! {
if #ident > #max {
panic!("Value of `{}` must not be larger than: {}", stringify!(#ident), #max);
}
})
}
} else {
parameter_extraction.push(quote! {
let #ident: #ty = args.get(stringify!(#ident))
.map(|arg| arg.parse().unwrap())
.expect(format!("A value for `{}` has to be provided since no default is specified",stringify!(#ident)).as_str());
});
}
}
let block = item.block;
Expand Down Expand Up @@ -82,14 +89,17 @@ pub fn attributed_arguments(_: TokenStream, input: TokenStream) -> TokenStream {
/// ` attr ident`
#[derive(Debug, Clone)]
struct Argument {
pub attr: HelperAttribute,
pub attr: Option<HelperAttribute>,
pub ident: proc_macro2::Ident,
pub ty: proc_macro2::Ident,
}

impl Parse for Argument {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let attr: HelperAttribute = input.parse()?;
let mut attr = None;
if input.peek(syn::token::Pound) {
attr = Some(input.parse()?);
}
let ident: proc_macro2::Ident = input.parse()?;

let _: syn::token::Colon = input.parse()?;
Expand Down
24 changes: 6 additions & 18 deletions models/cuboid/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,11 @@
use std::collections::HashMap;

#[no_mangle]
pub extern "C" fn model(args: &HashMap<String, String>) -> fj::Shape {
let x: f64 = args
.get("x")
.unwrap_or(&"3.0".to_owned())
.parse()
.expect("Could not parse parameter `x`");
let y: f64 = args
.get("y")
.unwrap_or(&"2.0".to_owned())
.parse()
.expect("Could not parse parameter `y`");
let z: f64 = args
.get("z")
.unwrap_or(&"1.0".to_owned())
.parse()
.expect("Could not parse parameter `z`");

#[fj::model]
pub fn model(
#[value(default = 3.0)] x: f64,
#[value(default = 2.0)] y: f64,
#[value(default = 1.0)] z: f64,
) -> fj::Shape {
#[rustfmt::skip]
let rectangle = fj::Sketch::from_points(vec![
[-x / 2., -y / 2.],
Expand Down
24 changes: 6 additions & 18 deletions models/spacer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,12 @@ use std::collections::HashMap;

use fj::syntax::*;

#[no_mangle]
pub extern "C" fn model(args: &HashMap<String, String>) -> fj::Shape {
let outer = args
.get("outer")
.unwrap_or(&"1.0".to_owned())
.parse()
.expect("Could not parse parameter `outer`");
let inner = args
.get("inner")
.unwrap_or(&"0.5".to_owned())
.parse()
.expect("Could not parse parameter `inner`");
let height: f64 = args
.get("height")
.unwrap_or(&"1.0".to_owned())
.parse()
.expect("Could not parse parameter `height`");

#[fj::model]
pub fn model(
#[value(default = 1.0, min = inner * 1.01)] outer: f64,
#[value(default = 0.5, max = outer * 0.99)] inner: f64,
#[value(default = 1.0)] height: f64,
) -> fj::Shape {
let outer_edge = fj::Circle::from_radius(outer);
let inner_edge = fj::Circle::from_radius(inner);

Expand Down
4 changes: 2 additions & 2 deletions models/test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use std::{collections::HashMap, f64::consts::PI};

use fj::{syntax::*, Angle};

#[no_mangle]
pub extern "C" fn model(_: &HashMap<String, String>) -> fj::Shape {
#[fj::model]
pub fn model() -> fj::Shape {
let a = star(4, [0, 255, 0, 200]);
let b = star(5, [255, 0, 0, 255])
.rotate([1., 1., 1.], Angle::from_deg(45.))
Expand Down

0 comments on commit 8719f79

Please sign in to comment.