Skip to content

Commit b041375

Browse files
authored
Merge pull request #592 from sdroege/optional-values-other-error-types-2
glib: Use the correct value type checker for optional types
2 parents 85454a5 + ef9fbc0 commit b041375

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

glib/src/value.rs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl<T, C, E> ValueType for Option<T>
7878
where
7979
T: for<'a> FromValue<'a, Checker = C> + ValueTypeOptional + StaticType + 'static,
8080
C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError<E>>,
81-
E: error::Error,
81+
E: error::Error + Send + Sized + 'static,
8282
{
8383
type Type = T::Type;
8484
}
@@ -280,7 +280,7 @@ impl<'a, T, C, E> FromValueOptional<'a> for T
280280
where
281281
T: FromValue<'a, Checker = C>,
282282
C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError<E>>,
283-
E: error::Error,
283+
E: error::Error + Send + Sized + 'static,
284284
{
285285
}
286286

@@ -291,26 +291,50 @@ mod private {
291291
where
292292
T: super::FromValue<'a, Checker = C>,
293293
C: super::ValueTypeChecker<Error = super::ValueTypeMismatchOrNoneError<E>>,
294-
E: super::error::Error,
294+
E: super::error::Error + Send + Sized + 'static,
295295
{
296296
}
297297
}
298298

299+
// rustdoc-stripper-ignore-next
300+
/// Wrapped `Value` type checker for optional types.
301+
pub struct ValueTypeOrNoneChecker<T, C, E>(std::marker::PhantomData<(T, C, E)>);
302+
303+
unsafe impl<'a, T, C, E> ValueTypeChecker for ValueTypeOrNoneChecker<T, C, E>
304+
where
305+
T: FromValue<'a, Checker = C> + StaticType,
306+
C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError<E>>,
307+
E: error::Error + Send + Sized + 'static,
308+
{
309+
type Error = E;
310+
311+
fn check(value: &Value) -> Result<(), Self::Error> {
312+
match T::Checker::check(value) {
313+
Err(ValueTypeMismatchOrNoneError::UnexpectedNone) => Ok(()),
314+
Err(ValueTypeMismatchOrNoneError::WrongValueType(err)) => Err(err),
315+
Ok(_) => Ok(()),
316+
}
317+
}
318+
}
319+
299320
// rustdoc-stripper-ignore-next
300321
/// Blanket implementation for all optional types.
301322
unsafe impl<'a, T, C, E> FromValue<'a> for Option<T>
302323
where
303324
T: FromValue<'a, Checker = C> + StaticType,
304325
C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError<E>>,
305-
E: error::Error,
326+
E: error::Error + Send + Sized + 'static,
306327
{
307-
type Checker = GenericValueTypeChecker<T>;
328+
type Checker = ValueTypeOrNoneChecker<T, C, E>;
308329

309330
unsafe fn from_value(value: &'a Value) -> Self {
310-
if let Err(ValueTypeMismatchOrNoneError::UnexpectedNone) = T::Checker::check(value) {
311-
None
312-
} else {
313-
Some(T::from_value(value))
331+
match T::Checker::check(value) {
332+
Err(ValueTypeMismatchOrNoneError::UnexpectedNone) => None,
333+
Err(ValueTypeMismatchOrNoneError::WrongValueType(_err)) => {
334+
// This should've been caught by the caller already.
335+
unreachable!();
336+
}
337+
Ok(_) => Some(T::from_value(value)),
314338
}
315339
}
316340
}

0 commit comments

Comments
 (0)