Skip to content

Commit 79c2362

Browse files
committed
Add MissingKeyError to Env
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.
1 parent b813a50 commit 79c2362

File tree

2 files changed

+51
-17
lines changed

2 files changed

+51
-17
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ You can find its changes [documented below](#060---2020-06-01).
2727
- `Container::rounded` takes `KeyOrValue<f64>` instead of `f64`. ([#1054] by [@binomial0])
2828
- `request_anim_frame` no longer invalidates the entire window. ([#1057] by [@jneem])
2929
- Use new Piet text api ([#1143] by [@cmyr])
30+
- `Env::try_get` (and related methods) return a `Result` instead of an `Option`.
31+
([#1172] by [@cmyr])
3032

3133
### Deprecated
3234

@@ -403,6 +405,7 @@ Last release without a changelog :(
403405
[#1151]: https://github.com/linebender/druid/pull/1151
404406
[#1152]: https://github.com/linebender/druid/pull/1152
405407
[#1157]: https://github.com/linebender/druid/pull/1157
408+
[#1172]: https://github.com/linebender/druid/pull/1157
406409

407410
[Unreleased]: https://github.com/linebender/druid/compare/v0.6.0...master
408411
[0.6.0]: https://github.com/linebender/druid/compare/v0.5.0...v0.6.0

druid/src/env.rs

+48-17
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,16 @@ pub struct ValueTypeError {
156156
found: Value,
157157
}
158158

159+
/// An error type for when a key is missing from the [`Env`].
160+
///
161+
/// [`Env`]: struct.Env.html
162+
#[derive(Debug, Clone)]
163+
#[non_exhaustive]
164+
pub struct MissingKeyError {
165+
/// The raw key.
166+
key: Arc<str>,
167+
}
168+
159169
impl Env {
160170
/// State for whether or not to paint colorful rectangles for layout
161171
/// debugging.
@@ -205,24 +215,30 @@ impl Env {
205215
///
206216
/// Panics if the key is not found, or if it is present with the wrong type.
207217
pub fn get<'a, V: ValueType<'a>>(&'a self, key: impl Borrow<Key<V>>) -> V {
208-
let key = key.borrow();
209-
if let Some(value) = self.0.map.get(key.key) {
210-
value.to_inner_unchecked()
211-
} else {
212-
panic!("key for {} not found", key.key)
218+
match self.try_get(key) {
219+
Ok(value) => value,
220+
Err(err) => panic!("{}", err),
213221
}
214222
}
215223

216-
/// Gets a value from the environment.
224+
/// Trys to get a value from the environment.
225+
///
226+
/// If the value is not found, the raw key is returned as the error.
217227
///
218228
/// # Panics
219229
///
220230
/// Panics if the value for the key is found, but has the wrong type.
221-
pub fn try_get<'a, V: ValueType<'a>>(&'a self, key: impl Borrow<Key<V>>) -> Option<V> {
231+
pub fn try_get<'a, V: ValueType<'a>>(
232+
&'a self,
233+
key: impl Borrow<Key<V>>,
234+
) -> Result<V, MissingKeyError> {
222235
self.0
223236
.map
224237
.get(key.borrow().key)
225238
.map(|value| value.to_inner_unchecked())
239+
.ok_or(MissingKeyError {
240+
key: key.borrow().key.into(),
241+
})
226242
}
227243

228244
/// Gets a value from the environment, in its encapsulated [`Value`] form,
@@ -236,22 +252,23 @@ impl Env {
236252
/// Panics if the key is not found
237253
/// [`Value`]: enum.Value.html
238254
pub fn get_untyped(&self, key: impl Borrow<Key<()>>) -> &Value {
239-
let key = key.borrow();
240-
if let Some(value) = self.0.map.get(key.key) {
241-
value
242-
} else {
243-
panic!("key for {} not found", key.key)
255+
match self.try_get_untyped(key) {
256+
Ok(val) => val,
257+
Err(err) => panic!("{}", err),
244258
}
245259
}
246260

247261
/// Gets a value from the environment, in its encapsulated [`Value`] form,
248-
/// returning None if a value isn't found.
262+
/// returning `None`` if a value isn't found.
263+
///
264+
/// *WARNING:* This is not intended for general use, but only for
265+
/// inspecting an `Env` e.g. for debugging, theme editing, and theme loading.
249266
///
250-
/// *WARNING:* This is not intended for general use, but only for inspecting an `Env` e.g.
251-
/// for debugging, theme editing, and theme loading.
252267
/// [`Value`]: enum.Value.html
253-
pub fn try_get_untyped(&self, key: impl Borrow<Key<()>>) -> Option<&Value> {
254-
self.0.map.get(key.borrow().key)
268+
pub fn try_get_untyped(&self, key: impl Borrow<Key<()>>) -> Result<&Value, MissingKeyError> {
269+
self.0.map.get(key.borrow().key).ok_or(MissingKeyError {
270+
key: key.borrow().key.into(),
271+
})
255272
}
256273

257274
/// Gets the entire contents of the `Env`, in key-value pairs.
@@ -484,7 +501,21 @@ impl std::fmt::Display for ValueTypeError {
484501
}
485502
}
486503

504+
impl MissingKeyError {
505+
/// The raw key that was missing.
506+
pub fn raw_key(&self) -> &str {
507+
&self.key
508+
}
509+
}
510+
511+
impl std::fmt::Display for MissingKeyError {
512+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
513+
write!(f, "Missing key: '{}'", self.key)
514+
}
515+
}
516+
487517
impl std::error::Error for ValueTypeError {}
518+
impl std::error::Error for MissingKeyError {}
488519

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

0 commit comments

Comments
 (0)