Skip to content

Commit bec688d

Browse files
committed
improve code and add tests
1 parent 908b554 commit bec688d

File tree

2 files changed

+135
-13
lines changed

2 files changed

+135
-13
lines changed

packages/derive/src/into_event.rs

Lines changed: 129 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fn scan_to_string_fn(field: &Field) -> Result<Option<proc_macro2::TokenStream>>
2222
if filtered.is_empty() {
2323
Ok(None)
2424
} else {
25-
Ok(Some(filtered[0].tokens.clone()))
25+
Ok(Some(filtered[0].parse_args()?))
2626
}
2727
}
2828

@@ -35,7 +35,7 @@ fn has_use_to_string(field: &Field) -> Result<bool> {
3535
if filtered.clone().any(|a| !a.tokens.is_empty()) {
3636
return Err(Error::new(
3737
field.span(),
38-
"[IntoEvent] attribute `use_to_string` has some value. If you intend to specify the cast function to string, use `to_string_fn` instead.",
38+
"[IntoEvent] An attribute `use_to_string` has some value. If you intend to specify the cast function to string, use `to_string_fn` instead.",
3939
));
4040
}
4141
Ok(filtered.next().is_some())
@@ -88,12 +88,11 @@ fn make_init_from_struct(id: Ident, struct_data: DataStruct) -> Result<proc_macr
8888
Ok(gen)
8989
}
9090

91-
/// derive `IntoEvent` from a derive input. The input needs to be a struct.
92-
pub fn derive_into_event(input: DeriveInput) -> TokenStream {
91+
fn derive_into_event_impl(input: DeriveInput) -> proc_macro2::TokenStream {
9392
match input.data {
94-
syn::Data::Struct(struct_data) => make_init_from_struct(input.ident, struct_data)
95-
.unwrap_or_else(|e| e.to_compile_error())
96-
.into(),
93+
syn::Data::Struct(struct_data) => {
94+
make_init_from_struct(input.ident, struct_data).unwrap_or_else(|e| e.to_compile_error())
95+
}
9796
syn::Data::Enum(enum_data) => Error::new(
9897
enum_data.enum_token.span,
9998
"[IntoEvent] `derive(IntoEvent)` cannot be applied to Enum.",
@@ -108,3 +107,126 @@ pub fn derive_into_event(input: DeriveInput) -> TokenStream {
108107
.into(),
109108
}
110109
}
110+
111+
/// derive `IntoEvent` from a derive input. The input needs to be a struct.
112+
pub fn derive_into_event(input: DeriveInput) -> TokenStream {
113+
derive_into_event_impl(input).into()
114+
}
115+
116+
#[cfg(test)]
117+
mod tests {
118+
use super::*;
119+
use proc_macro2::TokenStream;
120+
use syn::parse_quote;
121+
122+
fn expect_compile_error(ts: TokenStream, msg: &str) {
123+
assert!(
124+
ts.to_string().starts_with("compile_error ! {"),
125+
"Code does not raise compile error: `{}`",
126+
ts.to_string()
127+
);
128+
129+
assert!(
130+
ts.to_string().contains(msg),
131+
"Error does not have expected message \"{}\": `{}`",
132+
msg,
133+
ts.to_string()
134+
);
135+
}
136+
137+
#[test]
138+
fn test_doc_example() {
139+
let input: DeriveInput = parse_quote! {
140+
struct StructName {
141+
field_name_1: field_type_1,
142+
#[use_to_string]
143+
field_name_2: field_type_2,
144+
#[to_string_fn(cast_fn_3)]
145+
field_name_3: field_type_3,
146+
}
147+
};
148+
let result_implement = derive_into_event_impl(input);
149+
let expected: TokenStream = parse_quote! {
150+
impl Into<cosmwasm_std::Event> for StructName {
151+
fn into(self) -> cosmwasm_std::Event {
152+
cosmwasm_std::Event::new("struct_name")
153+
.add_attribute(stringify!(field_name_1), self.field_name_1)
154+
.add_attribute(stringify!(field_name_2), self.field_name_2.to_string())
155+
.add_attribute(stringify!(field_name_3), cast_fn_3 (self.field_name_3))
156+
}
157+
}
158+
};
159+
assert_eq!(expected.to_string(), result_implement.to_string())
160+
}
161+
162+
#[test]
163+
fn test_error_multiple_to_string_functions() {
164+
let input: DeriveInput = parse_quote! {
165+
struct StructName {
166+
#[to_string_fn(cast_fn_1)]
167+
#[to_string_fn(cast_fn_1)]
168+
field_name_1: field_type_1,
169+
}
170+
};
171+
let result_implement = derive_into_event_impl(input);
172+
expect_compile_error(
173+
result_implement,
174+
"[IntoEvent] Only one or zero `to_string_fn`",
175+
);
176+
}
177+
178+
#[test]
179+
fn test_error_use_to_string_has_value() {
180+
let input: DeriveInput = parse_quote! {
181+
struct StructName {
182+
#[use_to_string(foo)]
183+
field_name_1: field_type_1,
184+
}
185+
};
186+
let result_implement = derive_into_event_impl(input);
187+
expect_compile_error(
188+
result_implement,
189+
"[IntoEvent] An attribute `use_to_string` has some value",
190+
);
191+
}
192+
193+
#[test]
194+
fn test_error_both_two_attributes_is_used() {
195+
let input: DeriveInput = parse_quote! {
196+
struct StructName {
197+
#[use_to_string]
198+
#[to_string_fn(cast_fn_1)]
199+
field_name_1: field_type_1,
200+
}
201+
};
202+
let result_implement = derive_into_event_impl(input);
203+
expect_compile_error(
204+
result_implement,
205+
"[IntoEvent] Both `use_to_string` and `to_string_fn`",
206+
);
207+
}
208+
209+
#[test]
210+
fn test_error_derive_enum() {
211+
let input: DeriveInput = parse_quote! {
212+
enum Enum {}
213+
};
214+
let result_implement = derive_into_event_impl(input);
215+
expect_compile_error(
216+
result_implement,
217+
"[IntoEvent] `derive(IntoEvent)` cannot be applied to Enum",
218+
);
219+
}
220+
221+
#[test]
222+
fn test_error_derive_union() {
223+
let input: DeriveInput = parse_quote! {
224+
union Union {}
225+
};
226+
let result_implement = derive_into_event_impl(input);
227+
expect_compile_error(
228+
result_implement,
229+
"[IntoEvent] `derive(IntoEvent)` cannot be applied to Union",
230+
);
231+
}
232+
}

packages/derive/src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,12 @@ pub fn entry_point(_attr: TokenStream, mut item: TokenStream) -> TokenStream {
109109
/// Output AST:
110110
///
111111
/// ```no_test
112-
/// impl Into<cosmwasm::Event> for `StructName` {
113-
/// fn into(self) -> Event {
114-
/// Event::new("struct_name")
115-
/// .add_attribute("field_name_1", self.field_value_1)
116-
/// .add_attribute("field_name_2", self.field_value_2.to_string())
117-
/// .add_attribute("field_name_3", casting_fn(self.field_value_3))
112+
/// impl Into<cosmwasm_std::Event> for StructName {
113+
/// fn into(self) -> cosmwasm_std::Event {
114+
/// cosmwasm_std::Event::new("struct_name")
115+
/// .add_attribute("field_name_1", self.field_name_1)
116+
/// .add_attribute("field_name_2", self.field_name_2.to_string())
117+
/// .add_attribute("field_name_3", cast_fn_3(self.field_name_3))
118118
/// }
119119
/// }
120120
/// ```

0 commit comments

Comments
 (0)