Skip to content

Commit

Permalink
Add MissingKeyError to Env
Browse files Browse the repository at this point in the history
This is a little bit of cleanup while I was looking into making
another addition to the env. This is technically a breaking change
(we return Result instead of Option) but these API are not heavily
used and I'm not too concerned about the breakage.
  • Loading branch information
cmyr committed Sep 2, 2020
1 parent c892631 commit f827c57
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 18 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ You can find its changes [documented below](#060---2020-06-01).
- `Container::rounded` takes `KeyOrValue<f64>` instead of `f64`. ([#1054] by [@binomial0])
- `request_anim_frame` no longer invalidates the entire window. ([#1057] by [@jneem])
- Use new Piet text api ([#1143] by [@cmyr])
- `Env::try_get` (and related methods) return a `Result` instead of an `Option`.
([#1172] by [@cmyr])

### Deprecated

Expand Down Expand Up @@ -403,6 +405,7 @@ Last release without a changelog :(
[#1151]: https://github.com/linebender/druid/pull/1151
[#1152]: https://github.com/linebender/druid/pull/1152
[#1157]: https://github.com/linebender/druid/pull/1157
[#1172]: https://github.com/linebender/druid/pull/1157

[Unreleased]: https://github.com/linebender/druid/compare/v0.6.0...master
[0.6.0]: https://github.com/linebender/druid/compare/v0.5.0...v0.6.0
Expand Down
69 changes: 51 additions & 18 deletions druid/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,16 @@ pub struct ValueTypeError {
found: Value,
}

/// An error type for when a key is missing from the [`Env`].
///
/// [`Env`]: struct.Env.html
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct MissingKeyError {
/// The raw key.
key: Arc<str>,
}

impl Env {
/// State for whether or not to paint colorful rectangles for layout
/// debugging.
Expand Down Expand Up @@ -205,24 +215,30 @@ impl Env {
///
/// Panics if the key is not found, or if it is present with the wrong type.
pub fn get<'a, V: ValueType<'a>>(&'a self, key: impl Borrow<Key<V>>) -> V {
let key = key.borrow();
if let Some(value) = self.0.map.get(key.key) {
value.to_inner_unchecked()
} else {
panic!("key for {} not found", key.key)
match self.try_get(key) {
Ok(value) => value,
Err(err) => panic!("{}", err),
}
}

/// Gets a value from the environment.
/// Trys to get a value from the environment.
///
/// If the value is not found, the raw key is returned as the error.
///
/// # Panics
///
/// Panics if the value for the key is found, but has the wrong type.
pub fn try_get<'a, V: ValueType<'a>>(&'a self, key: impl Borrow<Key<V>>) -> Option<V> {
pub fn try_get<'a, V: ValueType<'a>>(
&'a self,
key: impl Borrow<Key<V>>,
) -> Result<V, MissingKeyError> {
self.0
.map
.get(key.borrow().key)
.map(|value| value.to_inner_unchecked())
.ok_or(MissingKeyError {
key: key.borrow().key.into(),
})
}

/// Gets a value from the environment, in its encapsulated [`Value`] form,
Expand All @@ -233,25 +249,28 @@ impl Env {
///
/// # Panics
///
/// Panics if the key is not found
/// Panics if the key is not found.
///
/// [`Value`]: enum.Value.html
pub fn get_untyped(&self, key: impl Borrow<Key<()>>) -> &Value {
let key = key.borrow();
if let Some(value) = self.0.map.get(key.key) {
value
} else {
panic!("key for {} not found", key.key)
match self.try_get_untyped(key) {
Ok(val) => val,
Err(err) => panic!("{}", err),
}
}

/// Gets a value from the environment, in its encapsulated [`Value`] form,
/// returning None if a value isn't found.
/// returning `None` if a value isn't found.
///
/// # Note
/// This is not intended for general use, but only for inspecting an `Env`
/// e.g. for debugging, theme editing, and theme loading.
///
/// *WARNING:* This is not intended for general use, but only for inspecting an `Env` e.g.
/// for debugging, theme editing, and theme loading.
/// [`Value`]: enum.Value.html
pub fn try_get_untyped(&self, key: impl Borrow<Key<()>>) -> Option<&Value> {
self.0.map.get(key.borrow().key)
pub fn try_get_untyped(&self, key: impl Borrow<Key<()>>) -> Result<&Value, MissingKeyError> {
self.0.map.get(key.borrow().key).ok_or(MissingKeyError {
key: key.borrow().key.into(),
})
}

/// Gets the entire contents of the `Env`, in key-value pairs.
Expand Down Expand Up @@ -484,7 +503,21 @@ impl std::fmt::Display for ValueTypeError {
}
}

impl MissingKeyError {
/// The raw key that was missing.
pub fn raw_key(&self) -> &str {
&self.key
}
}

impl std::fmt::Display for MissingKeyError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Missing key: '{}'", self.key)
}
}

impl std::error::Error for ValueTypeError {}
impl std::error::Error for MissingKeyError {}

/// Use this macro for types which are cheap to clone (ie all `Copy` types).
macro_rules! impl_value_type_owned {
Expand Down

0 comments on commit f827c57

Please sign in to comment.