-
Notifications
You must be signed in to change notification settings - Fork 566
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 UpdateCtx::env_changed and UpdateCtx::env_key_changed #1207
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -133,6 +133,35 @@ pub enum KeyOrValue<T> { | |
Key(Key<T>), | ||
} | ||
|
||
/// A trait for anything that can resolve a value of some type from the [`Env`]. | ||
/// | ||
/// This is a generalization of the idea of [`KeyOrValue`], mostly motivated | ||
/// by wanting to improve the API used for checking if items in the [`Env`] have changed. | ||
/// | ||
/// [`Env`]: struct.Env.html | ||
/// [`KeyOrValue`]: enum.KeyOrValue.html | ||
pub trait KeyLike<T> { | ||
/// Returns `true` if this item has changed between the old and new [`Env`]. | ||
/// | ||
/// [`Env`]: struct.Env.html | ||
fn changed(&self, old: &Env, new: &Env) -> bool; | ||
} | ||
|
||
impl<T: ValueType> KeyLike<T> for Key<T> { | ||
fn changed(&self, old: &Env, new: &Env) -> bool { | ||
!old.get_untyped(self).same(new.get_untyped(self)) | ||
} | ||
} | ||
|
||
impl<T> KeyLike<T> for KeyOrValue<T> { | ||
fn changed(&self, old: &Env, new: &Env) -> bool { | ||
match self { | ||
KeyOrValue::Concrete(_) => false, | ||
KeyOrValue::Key(key) => !old.get_untyped(key).same(new.get_untyped(key)), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. huh, is your panic that some key is missing from the env? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, pretty sure that's it. I am trying to change the color of a menu label based on the current selection and hot state. I've created a somewhat "minimal" example repo for this, if you want to take a look: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In your example, I wouldn't use a I also wouldn't use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having dug into this a bit more: you have three keys in the when you set a The rationale for this is that you could have different themes that provide different values for various keys, and it would 'just work'. Similarly, if you were using built-in keys we could support things like dark mode, or high-contrast colors for accessibility, and it would 'just work'. Your crash is happening because the Thanks for the detailed example, I'm glad I understand what was going on. :) |
||
} | ||
} | ||
} | ||
|
||
/// Values which can be stored in an environment. | ||
pub trait ValueType: Sized + Into<Value> { | ||
/// Attempt to convert the generic `Value` into this type. | ||
|
@@ -244,7 +273,7 @@ impl Env { | |
/// Panics if the key is not found. | ||
/// | ||
/// [`Value`]: enum.Value.html | ||
pub fn get_untyped(&self, key: impl Borrow<Key<()>>) -> &Value { | ||
pub fn get_untyped<V>(&self, key: impl Borrow<Key<V>>) -> &Value { | ||
match self.try_get_untyped(key) { | ||
Ok(val) => val, | ||
Err(err) => panic!("{}", err), | ||
|
@@ -259,7 +288,7 @@ impl Env { | |
/// e.g. for debugging, theme editing, and theme loading. | ||
/// | ||
/// [`Value`]: enum.Value.html | ||
pub fn try_get_untyped(&self, key: impl Borrow<Key<()>>) -> Result<&Value, MissingKeyError> { | ||
pub fn try_get_untyped<V>(&self, key: impl Borrow<Key<V>>) -> Result<&Value, MissingKeyError> { | ||
self.0.map.get(key.borrow().key).ok_or(MissingKeyError { | ||
key: key.borrow().key.into(), | ||
}) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've got a panic on this line.
I'm not sure if I am doing anything wrong, but I think this would be better written as: