Skip to content

Commit c913b6c

Browse files
authored
Merge pull request #20 from Ceratosenzaf/main
fix: method call allowed formats
2 parents f72e47a + 7b4aa37 commit c913b6c

File tree

2 files changed

+56
-24
lines changed

2 files changed

+56
-24
lines changed

spec-trait-impl/crates/spec-trait-bin/src/examples/sself.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ impl<T, U, V> SelfTrait<T> for (U, V) {
3131
}
3232
}
3333

34+
impl<T> SelfTrait<T> for i32 {
35+
fn self_method(&self, _x: T) {
36+
println!("i32: Default");
37+
}
38+
}
39+
3440
#[when(T = u8)]
3541
impl<T> SelfTrait<T> for BaseType1 {
3642
fn self_method(&self, _x: T) {
@@ -59,6 +65,13 @@ impl<T, U, V> SelfTrait<T> for (U, V) {
5965
}
6066
}
6167

68+
#[when(T = u8)]
69+
impl<T> SelfTrait<T> for i32 {
70+
fn self_method(&self, _x: T) {
71+
println!("i32: T is u8");
72+
}
73+
}
74+
6275
pub fn run() {
6376
println!("\n- Self Type Examples:");
6477

@@ -70,13 +83,12 @@ pub fn run() {
7083
spec! { y.self_method(42u8); BaseType2; [u8] } // -> "BaseType2: T is u8"
7184
spec! { y.self_method(1i32); BaseType2; [i32] } // -> "BaseType2: Default"
7285

73-
let v1 = vec![1u8];
74-
let v2 = vec![1i32];
75-
spec! { v1.self_method(42u8); Vec<u8>; [u8] } // -> "Vec<U>: T is u8"
76-
spec! { v2.self_method(1i32); Vec<i32>; [i32] } // -> "Vec<U>: Default"
86+
spec! { vec![1u8].self_method(42u8); Vec<u8>; [u8] } // -> "Vec<U>: T is u8"
87+
spec! { vec![1i32].self_method(1i32); Vec<i32>; [i32] } // -> "Vec<U>: Default"
88+
89+
spec! { (1u8, 2u8).self_method(42u8); (u8, u8); [u8] } // -> "(U, V): T is u8"
90+
spec! { (1i32, 2i32).self_method(1i32); (i32, i32); [i32] } // -> "(U, V): Default"
7791

78-
let t1 = (1u8, 2u8);
79-
let t2 = (1i32, 2i32);
80-
spec! { t1.self_method(42u8); (u8, u8); [u8] } // -> "(U, V): T is u8"
81-
spec! { t2.self_method(1i32); (i32, i32); [i32] } // -> "(U, V): Default"
92+
spec! { 1i32.abs().self_method(42u8); i32; [u8] } // -> "i32: T is u8"
93+
spec! { 1i32.abs().self_method(1i32); i32; [i32] } // -> "i32: Default"
8294
}

spec-trait-impl/crates/spec-trait-macro/src/annotations.rs

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use spec_trait_utils::conversions::to_string;
33
use spec_trait_utils::parsing::{ParseTypeOrLifetimeOrTrait, parse_type_or_lifetime_or_trait};
44
use std::fmt::Debug;
55
use syn::parse::{Parse, ParseStream};
6-
use syn::{Error, Expr, Ident, Lit, Token, Type, bracketed, parenthesized, token};
6+
use syn::{Error, Expr, Token, Type, bracketed, token};
77

88
#[derive(Debug, PartialEq, Clone)]
99
pub enum Annotation {
@@ -87,28 +87,25 @@ impl Parse for AnnotationBody {
8787
/// - `x.my_method(1u8, "abc")` -> `("x", "my_method", ["1u8", "abc"])`
8888
/// - `var.foo()` -> `("var", "foo", [])`
8989
fn parse_call(input: ParseStream) -> Result<(String, String, Vec<String>), Error> {
90-
let var = if input.peek(Ident) {
91-
to_string(&input.parse::<Ident>()?)
92-
} else if input.peek(Lit) {
93-
to_string(&input.parse::<Lit>()?)
94-
} else {
95-
return Err(Error::new(input.span(), "Expected identifier or literal"));
90+
let method_call = match input.parse::<Expr>()? {
91+
Expr::MethodCall(mc) => mc,
92+
_ => {
93+
return Err(Error::new(
94+
input.span(),
95+
"Expected a method call of the form `variable.function(args...)`",
96+
));
97+
}
9698
};
9799

98-
input.parse::<Token![.]>()?; // consume the '.' token
99-
100-
let fn_: Ident = input.parse()?;
101-
102-
let content;
103-
parenthesized!(content in input); // consume the '(' and ')' token pair
104-
105-
let args = content.parse_terminated(Expr::parse, Token![,])?;
100+
let var = to_string(&method_call.receiver);
101+
let fn_ = method_call.method.to_string();
102+
let args = method_call.args.iter().map(to_string).collect();
106103

107104
if input.peek(Token![;]) {
108105
input.parse::<Token![;]>()?; // consume the ';' token
109106
}
110107

111-
Ok((var, fn_.to_string(), args.iter().map(to_string).collect()))
108+
Ok((var, fn_, args))
112109
}
113110

114111
/// Parse the variable type and argument types
@@ -229,6 +226,29 @@ mod tests {
229226
}
230227
}
231228

229+
#[test]
230+
fn type_formats() {
231+
let input = quote! { (a,b).foo(); (i32,i32) };
232+
let result = AnnotationBody::try_from(input).unwrap();
233+
234+
assert_eq!(result.var.replace(" ", ""), "(a,b)");
235+
assert_eq!(result.fn_, "foo");
236+
assert!(result.args.is_empty());
237+
assert_eq!(result.var_type.replace(" ", ""), "(i32,i32)");
238+
assert!(result.args_types.is_empty());
239+
assert!(result.annotations.is_empty());
240+
241+
let input = quote! { [1,2].foo(); [i32;2] };
242+
let result = AnnotationBody::try_from(input).unwrap();
243+
244+
assert_eq!(result.var.replace(" ", ""), "[1,2]");
245+
assert_eq!(result.fn_, "foo");
246+
assert!(result.args.is_empty());
247+
assert_eq!(result.var_type.replace(" ", ""), "[i32;2]");
248+
assert!(result.args_types.is_empty());
249+
assert!(result.annotations.is_empty());
250+
}
251+
232252
#[test]
233253
fn annotations() {
234254
let input = quote! {

0 commit comments

Comments
 (0)