-
Notifications
You must be signed in to change notification settings - Fork 3
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
Add an enum_properties_lazy
macro that allows arbitrary values.
#6
Conversation
Hey! Thank you for your interest in the crate. My chief concern with this PR is that the crate highly encourages one-by-one access of properties, and the introduction of a load operation on a synchronization primitive is not conducive to this pattern. Such loads are better performed without the syntactic sugar provided by this crate. My second concern is that the two types you expressed interest in using within a static property, For these reasons, I am closing the PR. |
Well, it's clear that If you stick to your opinion, I guess I'll just start a new crate, I think my use-case justifies it. |
It is strange that To clarify what I was talking about in the first paragraph of my last post, the syntactic sugar provided by this crate encourages not holding onto the reference to the properties struct, but rather reacquiring it every single time any property needs to be accessed. This pattern makes less sense the higher the cost of acquiring the reference to the properties struct. Another issue is that wrapping the entire properties struct in a synchronization primitive means that accesses to properties which normally do not have the additional overhead now have it too. These issues could be jointly fixed by separating the lazy properties from the const properties, and making access of the lazy properties explicit rather than automatic via |
So true, I'm personally eager to see const_heap getting implemented, but I think that very long shoot.
Sure thing, I do agree to the general premise, but I want to point out two things: First, as you already indicated with by using comparative, this not a binary situation, it's more gradually, and the additional cost essentially boils down to a single atomic Second, it also depends on the use-case how much overhead is acceptable, e.g. some sparse accesses vs a lot in a tight loop. Thus, I already proposed to keep those two approaches separate, so one is free to choose whether one stays restricted to more efficient const data or pays to allow more general types. Tho, I think, it could be worth to point out these implications/differences in the documentation.
Well, this is unfortunate.
So, I assume you mean that the user can implement two property structs on the same enum, one const initialized would be accessed via On the off chance of making this too long, I think, it is a good point to tell about another idea that I had. I got inspired to this via However, I think, we can improve on that: the current Adding to that I could image instead of simply implementing pub trait EnumProp<Prop> {
fn get(&self) -> &'static Prop;
} Allowing multiple property types on the same struct. Then one of them can be redirected to Having this trait, would allow to have a more unified macro independent on which impl gets used as But of course these are just ideas. |
I experimented a bit with my idea to separate the impls from the enum definition: see playground The basic syntax so far would be like this: enum Foo {
Alpha,
Beta(u8),
}
struct PropsConst {
name: &'static str,
}
// a const impl & Deref
props!{
const deref props PropsConst for crate::Foo {
Self::Alpha => {
name: "Alpha"
}
Self::Beta(42) => {
name: "Best Beta"
}
Self::Beta(_) => {
name: "Normal Beta"
}
}
}
struct PropsLazy {
name: String,
}
// a lazy impl
props!{
lazy props PropsLazy for crate::Foo {
Self::Alpha => {
name: [1,2,3].iter().map(ToString::to_string).collect()
}
Self::Beta(_) => {
name: "Just Beta".into()
}
}
}
fn main() {
assert_eq!(Foo::Alpha.name, "Alpha");
// Using universal function call
assert_eq!(EnumProp::<PropsLazy>::get(&Foo::Alpha).name, "123");
} This just a draft at that point. It is still missing some features of the current macro, most notably default values, and there are still some open questions (apart from universal syntax bikeshedding, I'm also open for alternatives here):
|
A pretty huge part of this crate is just making things as simple and succinct as possible, which is why everything is defined at the same time as the enum itself (you never have to write the name of a variant twice). So that kind of design I'd rule as being out of scope of this project, but I can see value in a separate crate providing something along those lines. Regarding the non-const initialization problem, I'm investigating the possibility of pre-main initialization in the style of |
Well, I see the appeal of the brevity of the current macro. But it comes with its limits, whereas my proposal gives a more general macro. However, I don't see them necessarily as mutually exclusive, I mean, they both could coexist. Thus, letting the user choose between the two variants. Additionally, I think they can also be composed together, for example using the current macro to concisely add a const-init deref property and then the more general version to just add another (e.g. lazy) property as well to the same enum. However, if you insist, I could just spin-up a new crate.
|
I think your |
Closing this PR, because I implement the macro that I proposed here in my own spin-off crate, I call it: Also, see this example, where I show how both crates can cooperate. I'm still working on it and plan then to release it on crates.io. |
The current
enum_properties
macro seems to require that the properties struct can be const initialized. This excludes properties that containString
orVec
or any other non-trivially initialized types. Otherwise, some error "returns a reference to data owned by the current function" is encountered.This PR adds the
enum_properties_lazy
macro that support runtime initialized properties structs by utilizinglazy_static
.lazy_static
allows to initialize static data at runtime, lifting the const initialization constraint while still allowing to obtain a reference with static lifetime (which is needed in thedefer
function).Since this introduces a new dependency, it is gated behind a crate feature, i.e.
lazy_static
is an optional dependency andenum_properties_lazy
will only exist if it was enabled.