Skip to content

Commit aeebe4e

Browse files
committed
Allow multiple values in message variants
Fix #29
1 parent 32aec08 commit aeebe4e

File tree

3 files changed

+52
-35
lines changed

3 files changed

+52
-35
lines changed

examples/text-fields-attribute.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub struct Model {
4747

4848
#[derive(Msg)]
4949
pub enum Msg {
50-
Change(String),
50+
Change(String, usize),
5151
Quit,
5252
}
5353

@@ -61,7 +61,10 @@ impl Widget for Win {
6161

6262
fn update(&mut self, event: Msg) {
6363
match event {
64-
Change(text) => self.model.content = text,
64+
Change(text, len) => {
65+
self.model.content = text.chars().rev().collect();
66+
self.model.content += &format!(" ({})", len);
67+
},
6568
Quit => gtk::main_quit(),
6669
}
6770
}
@@ -71,10 +74,11 @@ impl Widget for Win {
7174
gtk::Box {
7275
orientation: Vertical,
7376
gtk::Entry {
74-
changed(entry) => Change(
75-
entry.get_text().unwrap()
76-
.chars().rev().collect()
77-
),
77+
changed(entry) => {
78+
let text = entry.get_text().unwrap();
79+
let len = text.len();
80+
Change(text, len)
81+
},
7882
placeholder_text: "Text to reverse",
7983
},
8084
gtk::Label {

relm-derive/src/lib.rs

+39-29
Original file line numberDiff line numberDiff line change
@@ -119,20 +119,12 @@ fn derive_clone(ast: &MacroInput) -> Tokens {
119119
}
120120

121121
fn derive_clone_enum(name: &Ident, typ: Tokens, mut generics: Generics, variants: &[Variant]) -> Tokens {
122-
let variant_idents_values: Vec<_> = variants.iter().map(|variant| {
123-
let has_value =
124-
if let VariantData::Tuple(_) = variant.data {
125-
true
126-
}
127-
else {
128-
false
129-
};
130-
(&variant.ident, has_value)
131-
}).collect();
132-
let variant_patterns = variant_idents_values.iter().map(|&(ref ident, has_value)| {
133-
if has_value {
122+
let variant_idents_values = gen_idents_count(variants);
123+
let variant_patterns = variant_idents_values.iter().map(|&(ref ident, value_count)| {
124+
if value_count > 0 {
125+
let value_idents = gen_idents(value_count);
134126
quote! {
135-
#name::#ident(ref value)
127+
#name::#ident(#(ref #value_idents),*)
136128
}
137129
}
138130
else {
@@ -141,10 +133,11 @@ fn derive_clone_enum(name: &Ident, typ: Tokens, mut generics: Generics, variants
141133
}
142134
}
143135
});
144-
let variant_values = variant_idents_values.iter().map(|&(ref ident, has_value)| {
145-
if has_value {
136+
let variant_values = variant_idents_values.iter().map(|&(ref ident, value_count)| {
137+
if value_count > 0 {
138+
let value_idents = gen_idents(value_count);
146139
quote! {
147-
#name::#ident(value.clone())
140+
#name::#ident(#(#value_idents.clone()),*)
148141
}
149142
}
150143
else {
@@ -222,20 +215,12 @@ fn derive_display_variant(ast: &MacroInput) -> Tokens {
222215
};
223216

224217
if let Body::Enum(ref variants) = ast.body {
225-
let variant_idents_values: Vec<_> = variants.iter().map(|variant| {
226-
let has_value =
227-
if let VariantData::Tuple(_) = variant.data {
228-
true
229-
}
230-
else {
231-
false
232-
};
233-
(&variant.ident, has_value)
234-
}).collect();
235-
let variant_patterns = variant_idents_values.iter().map(|&(ref ident, has_value)| {
236-
if has_value {
218+
let variant_idents_values = gen_idents_count(variants);
219+
let variant_patterns = variant_idents_values.iter().map(|&(ref ident, value_count)| {
220+
let value_idents = gen_ignored_idents(value_count);
221+
if value_count > 0 {
237222
quote! {
238-
#name::#ident(_)
223+
#name::#ident(#(#value_idents),*)
239224
}
240225
}
241226
else {
@@ -297,3 +282,28 @@ fn remove_generic_bounds(generics: &Generics) -> Generics {
297282
}
298283
generics.clone()
299284
}
285+
286+
fn gen_ignored_idents(count: usize) -> Vec<Ident> {
287+
(0..count)
288+
.map(|count| Ident::new("_"))
289+
.collect()
290+
}
291+
292+
fn gen_idents(count: usize) -> Vec<Ident> {
293+
(0..count)
294+
.map(|count| Ident::new(format!("value{}", count)))
295+
.collect()
296+
}
297+
298+
fn gen_idents_count(variants: &[Variant]) -> Vec<(&Ident, usize)> {
299+
variants.iter().map(|variant| {
300+
let value_count =
301+
if let VariantData::Tuple(ref tuple) = variant.data {
302+
tuple.len()
303+
}
304+
else {
305+
0
306+
};
307+
(&variant.ident, value_count)
308+
}).collect()
309+
}

src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@
4444
* TODO: add construct-only properties for relm widget (to replace initial parameters) to allow
4545
* setting them by name (or with default value).
4646
* TODO: find a way to do two-step initialization (to avoid using unitialized in model()).
47+
* TODO: consider using GBinding instead of manually adding calls to set_property().
48+
* TODO: consider using a nested event loop to transform synchronous callback into asynchronous
49+
* (allowing to set Inhibit(true) in the update() method).
4750
*
4851
* TODO: show a warning when components are destroyed after the end of call to Widget::view().
4952
* TODO: warn in the attribute when an event cycle is found.

0 commit comments

Comments
 (0)