Skip to content

Commit

Permalink
Move argument to the end in macro call
Browse files Browse the repository at this point in the history
This is in preparation for taking extra parameters that will be passed
to specializations.
  • Loading branch information
ozars committed Apr 9, 2024
1 parent 4ae06d1 commit 42d72d6
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 22 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ use specialized_dispatch::specialized_dispatch;

fn example<Arg>(arg: Arg) -> String {
specialized_dispatch!(
// The argument to the dispatched function. This can be an arbitrary expression.
arg,
// Type of the argument -> return type.
Arg -> String,
// Defaut implementation. At least one default value is required.
Expand All @@ -38,6 +36,8 @@ fn example<Arg>(arg: Arg) -> String {
fn (v: u8) => format!("u8: {}", v),
// Specialization for concrete type u16.
fn (v: u16) => format!("u16: {}", v),
// The argument to the dispatched function. This can be an arbitrary expression.
arg,
)
}

Expand Down Expand Up @@ -111,13 +111,13 @@ use specialized_dispatch::specialized_dispatch;
// The argument type must also bind to the same trait.
fn example<Arg: Display>(arg: Arg) -> String {
specialized_dispatch!(
arg,
Arg -> String,
// Notice the trait bound.
default fn <T: Display>(v: T) => format!("default value: {}", v),
// Note that specializations also need to satisfy the same bound.
fn (v: u8) => format!("u8: {}", v),
fn (v: u16) => format!("u16: {}", v),
arg,
)
}

Expand Down
4 changes: 2 additions & 2 deletions examples/simple_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ use specialized_dispatch::specialized_dispatch;

fn example<Arg>(arg: Arg) -> String {
specialized_dispatch!(
// The argument to the dispatched function. This can be an arbitrary expression.
arg,
// Type of the argument -> return type.
Arg -> String,
// Defaut implementation. At least one default value is required.
Expand All @@ -15,6 +13,8 @@ fn example<Arg>(arg: Arg) -> String {
fn (v: u8) => format!("u8: {}", v),
// Specialization for concrete type u16.
fn (v: u16) => format!("u16: {}", v),
// The argument to the dispatched function. This can be an arbitrary expression.
arg,
)
}

Expand Down
2 changes: 1 addition & 1 deletion examples/trait_bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ use specialized_dispatch::specialized_dispatch;
// The argument type must also bind to the same trait.
fn example<Arg: Display>(arg: Arg) -> String {
specialized_dispatch!(
arg,
Arg -> String,
// Notice the trait bound.
default fn <T: Display>(v: T) => format!("default value: {}", v),
// Note that specializations also need to satisfy the same bound.
fn (v: u8) => format!("u8: {}", v),
fn (v: u16) => format!("u16: {}", v),
arg,
)
}

Expand Down
35 changes: 25 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,29 +112,44 @@ impl Parse for DispatchArmExpr {
/// ```
#[derive(Debug, Eq, PartialEq)]
struct SpecializedDispatchExpr {
arg_expr: Expr,
from_type: Type,
to_type: Type,
arms: Vec<DispatchArmExpr>,
arg_expr: Expr,
}

fn parse_punctuated_arms(input: &ParseStream) -> Result<Punctuated<DispatchArmExpr, Token![,]>> {
let mut arms = Punctuated::new();
loop {
if input.peek(Token![default]) || input.peek(Token![fn]) {
arms.push(input.parse()?);
} else {
break;
}
if input.peek(Token![,]) && (input.peek2(Token![default]) || input.peek2(Token![fn])) {
let _ = input.parse::<Token![,]>()?;
} else {
break;
}
}
Ok(arms)
}

impl Parse for SpecializedDispatchExpr {
fn parse(input: ParseStream) -> Result<Self> {
// Parse first argument.
let arg_expr = input.parse()?;
let _ = input.parse::<Token![,]>()?;
let from_type = input.parse()?;
let _ = input.parse::<Token![->]>()?;
let to_type = input.parse()?;
let _ = input.parse::<Token![,]>()?;
let arms = Punctuated::<DispatchArmExpr, Token![,]>::parse_terminated(input)?
.into_iter()
.collect();
let arms = parse_punctuated_arms(&input)?.into_iter().collect();
let _ = input.parse::<Token![,]>()?;
let arg_expr = input.parse()?;
let _ = input.parse::<Token![,]>().ok();
Ok(Self {
arg_expr,
from_type,
to_type,
arms,
arg_expr,
})
}
}
Expand Down Expand Up @@ -255,16 +270,15 @@ mod tests {
#[test]
fn parse_specialized_dispatch_expr() {
let expr: SpecializedDispatchExpr = parse_quote! {
arg,
Arg -> String,
default fn <T>(_: T) => format!("default value"),
fn (v: u8) => format!("u8: {}", v),
fn (v: u16) => format!("u16: {}", v),
arg,
};
assert_eq!(
expr,
SpecializedDispatchExpr {
arg_expr: parse_quote!(arg),
from_type: parse_quote!(Arg),
to_type: parse_quote!(String),
arms: vec![
Expand All @@ -290,6 +304,7 @@ mod tests {
body: parse_quote!(format!("u16: {}", v)),
},
],
arg_expr: parse_quote!(arg),
}
);
}
Expand Down
12 changes: 6 additions & 6 deletions tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ use specialized_dispatch::specialized_dispatch;
fn test_example() {
fn example<Arg>(arg: Arg) -> String {
specialized_dispatch!(
arg,
Arg -> String,
default fn <T>(_: T) => format!("default value"),
fn (v: u8) => format!("u8: {}", v),
fn (v: u16) => format!("u16: {}", v),
arg,
)
}

Expand All @@ -23,11 +23,11 @@ fn test_example() {
fn test_example_different_order() {
fn example<Arg>(arg: Arg) -> String {
specialized_dispatch!(
arg,
Arg -> String,
fn (v: u8) => format!("u8: {}", v),
fn (v: u16) => format!("u16: {}", v),
default fn <T>(_: T) => format!("default value"),
arg,
)
}

Expand All @@ -39,18 +39,18 @@ fn test_example_different_order() {
#[test]
fn test_multiple_calls_in_same_scope() {
let s1 = specialized_dispatch!(
0u8,
u8 -> &'static str,
fn (_: u8) => "u8",
fn (_: u16) => "u16",
default fn <T>(_: T) => "other",
0u8,
);
let s2 = specialized_dispatch!(
0u16,
u16 -> &'static str,
fn (_: u8) => "u8",
fn (_: u16) => "u16",
default fn <T>(_: T) => "other",
0u16,
);
assert_eq!(format!("{}-{}", s1, s2), "u8-u16");
}
Expand All @@ -61,11 +61,11 @@ fn test_bound_traits() {

fn example<Arg: Display + Debug>(arg: Arg) -> String {
specialized_dispatch!(
arg,
Arg -> String,
default fn <T: Display + Debug>(v: T) => format!("default value: {}", v),
fn (v: u8) => format!("u8: {}", v),
fn (v: u16) => format!("u16: {}", v),
arg,
)
}

Expand All @@ -84,11 +84,11 @@ fn test_bound_traits_with_generic() {

fn example<Arg: Display + GenericTrait<()>>(arg: Arg) -> String {
specialized_dispatch!(
arg,
Arg -> String,
default fn <T: Display + GenericTrait<()>>(v: T) => format!("default value: {}", v),
fn (v: u8) => format!("u8: {}", v),
fn (v: u16) => format!("u16: {}", v),
arg,
)
}

Expand Down

0 comments on commit 42d72d6

Please sign in to comment.