-
-
Notifications
You must be signed in to change notification settings - Fork 24
Support for fn
s in collections?
#154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi, thank you for creating the issue! Unfortunately, Rust's type inference is rather awkward in this case, and I think it's more of an issue with the type inference itself than with I don't think there is a good solution to this problem. The easiest way to work around this error is to construct the hashmap manually from tuples like this: use bon::Builder;
use std::collections::HashMap;
fn main() {
let skills: &[(_, fn(_))] = &[
("slash", |field| { /* ... */ }),
("punch", |field| { /* ... */ }),
];
let skills = skills
.iter()
.copied()
.map(|(name, skill)| (name.to_owned(), skill))
.collect();
let player_1 = Player::builder().skills(skills);
}
#[derive(Builder)]
struct Player {
skills: HashMap<String, fn(Field)>,
}
struct Field(/* ... */); I'd be glad to hear any suggestions of how this could be implemented better though. Right now the snippet above is the only thing that comes to my mind. |
If you find youself creating such maps of functions quite often, then you can declare a helper function like this: use bon::Builder;
use std::collections::HashMap;
fn fn_map<F, const N: usize>(items: [(&'static str, F); N]) -> HashMap<String, F> {
items
.into_iter()
.map(|(name, func)| (name.to_owned(), func))
.collect()
}
fn main() {
let player_1 = Player::builder().skills(fn_map([
("slash", |field| { /* ... */ }),
("punch", |field| { /* ... */ }),
]));
}
#[derive(Builder)]
struct Player {
skills: HashMap<String, fn(Field)>,
}
struct Field(/* ... */); |
Yeah, this wouldn't be an issue if all closures implemented As a workaround, I've currently just manually implemented the builder pattern for the Also could do this if I'm feeling cursed: .skills({
let mut skills = HashMap::<_, fn(Field)>::new();
skills.insert("slash".into(), |field| {});
skills.insert("punch".into(), |field| {});
skills
}); Anyway, thanks for the feedback :^) |
I don't think I understand what "other crates do". Do you mean a method like Btw. it also looks fine to me if the builder could just create a |
Like alternatives to bon I mean, where they generate method
That would make it implicit that the |
I see, that's something to look forward to in the future. As the first step in this direction I'm planning to add an ability to add custom methods to the builder, and then custom fields, which would allow defining such a method that pushes into an internal collection manually. Then this pattern could be granted syntax sugar with an attribute. I don't have a design for that attribute yet though. |
Yeah, I was wondering about custom methods. The attribute design could be something like |
The design includes the name of the attribute and of the generated methods, their parametrization, behavior, API compatibility story, all the things. For example the macro needs to know the type of the element in the collection to generate a method that a accepts a value of that type to push into it. I think that'll require hardcoding the knowledge of the method and type signatures of well known collections such as vec, hashmap, btreemap, hashset, betreeset. |
As for custom builder methods. The design and impl for that is in master pending documentation and release. An example of that is in #145. The type signature of the builder will become stable |
Hey! Really like this crate, especially the lack of unwraps (rest my soul (◡ ‿ ◡ .))
But while making a little toy game, I found that there's really no way to pass a collection of functions into the builder.
The following code:
Gives this error:
I found that both
fn
pointers & dynamic dispatch break because ofimpl Into
, sobon::map
and the like don't work.Maybe you can use
as
or other kind of cast but I imagine that'd be very awkward.The text was updated successfully, but these errors were encountered: