Skip to content

Commit ed658d6

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 c892631 commit ed658d6

File tree

2 files changed

+54
-18
lines changed

2 files changed

+54
-18
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

+51-18
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,
@@ -233,25 +249,28 @@ impl Env {
233249
///
234250
/// # Panics
235251
///
236-
/// Panics if the key is not found
252+
/// Panics if the key is not found.
253+
///
237254
/// [`Value`]: enum.Value.html
238255
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)
256+
match self.try_get_untyped(key) {
257+
Ok(val) => val,
258+
Err(err) => panic!("{}", err),
244259
}
245260
}
246261

247262
/// Gets a value from the environment, in its encapsulated [`Value`] form,
248-
/// returning None if a value isn't found.
263+
/// returning `None` if a value isn't found.
264+
///
265+
/// # Note
266+
/// This is not intended for general use, but only for inspecting an `Env`
267+
/// e.g. for debugging, theme editing, and theme loading.
249268
///
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.
252269
/// [`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)
270+
pub fn try_get_untyped(&self, key: impl Borrow<Key<()>>) -> Result<&Value, MissingKeyError> {
271+
self.0.map.get(key.borrow().key).ok_or(MissingKeyError {
272+
key: key.borrow().key.into(),
273+
})
255274
}
256275

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

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

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

0 commit comments

Comments
 (0)