@@ -288,6 +288,79 @@ pub trait Cast: ObjectType {
288
288
289
289
impl < T : ObjectType > Cast for T { }
290
290
291
+ // rustdoc-stripper-ignore-next
292
+ /// Convenience trait mirroring `Cast`, implemented on `Option<Object>` types.
293
+ ///
294
+ /// # Warning
295
+ /// Inveitably this trait will discard informations about a downcast failure:
296
+ /// you don't know if the object was not of the expected type, or if it was `None`.
297
+ /// If you need to handle the downcast error, use `Cast` over a `glib::Object`.
298
+ ///
299
+ /// # Example
300
+ /// ```ignore
301
+ /// let widget: Option<Widget> = list_item.child();
302
+ ///
303
+ /// // Without using `CastNone`
304
+ /// let label = widget.unwrap().downcast::<gtk::Label>().unwrap();
305
+ ///
306
+ /// // Using `CastNone` we can avoid the first `unwrap()` call
307
+ /// let label = widget.and_downcast::<gtk::Label>().unwrap();
308
+ /// ````
309
+ pub trait CastNone : Sized {
310
+ type Inner ;
311
+ fn and_downcast < T : ObjectType > ( self ) -> Option < T >
312
+ where
313
+ Self :: Inner : CanDowncast < T > ;
314
+ fn and_downcast_ref < T : ObjectType > ( & self ) -> Option < & T >
315
+ where
316
+ Self :: Inner : CanDowncast < T > ;
317
+ fn and_upcast < T : ObjectType > ( self ) -> Option < T >
318
+ where
319
+ Self :: Inner : IsA < T > ;
320
+ fn and_upcast_ref < T : ObjectType > ( & self ) -> Option < & T >
321
+ where
322
+ Self :: Inner : IsA < T > ;
323
+ fn and_dynamic_cast < T : ObjectType > ( self ) -> Result < T , Self > ;
324
+ fn and_dynamic_cast_ref < T : ObjectType > ( & self ) -> Option < & T > ;
325
+ }
326
+ impl < I : ObjectType + Sized > CastNone for Option < I > {
327
+ type Inner = I ;
328
+
329
+ fn and_downcast < T : ObjectType > ( self ) -> Option < T >
330
+ where
331
+ Self :: Inner : CanDowncast < T > ,
332
+ {
333
+ self . and_then ( |i| i. downcast ( ) . ok ( ) )
334
+ }
335
+
336
+ fn and_downcast_ref < T : ObjectType > ( & self ) -> Option < & T >
337
+ where
338
+ Self :: Inner : CanDowncast < T > ,
339
+ {
340
+ self . as_ref ( ) . and_then ( |i| i. downcast_ref ( ) )
341
+ }
342
+ fn and_upcast < T : ObjectType > ( self ) -> Option < T >
343
+ where
344
+ Self :: Inner : IsA < T > ,
345
+ {
346
+ self . map ( |i| i. upcast ( ) )
347
+ }
348
+
349
+ fn and_upcast_ref < T : ObjectType > ( & self ) -> Option < & T >
350
+ where
351
+ Self :: Inner : IsA < T > ,
352
+ {
353
+ self . as_ref ( ) . map ( |i| i. upcast_ref ( ) )
354
+ }
355
+ fn and_dynamic_cast < T : ObjectType > ( self ) -> Result < T , Self > {
356
+ self . ok_or ( None )
357
+ . and_then ( |i| i. dynamic_cast ( ) . map_err ( |e| Some ( e) ) )
358
+ }
359
+ fn and_dynamic_cast_ref < T : ObjectType > ( & self ) -> Option < & T > {
360
+ self . as_ref ( ) . and_then ( |i| i. dynamic_cast_ref ( ) )
361
+ }
362
+ }
363
+
291
364
// rustdoc-stripper-ignore-next
292
365
/// Marker trait for the statically known possibility of downcasting from `Self` to `T`.
293
366
pub trait CanDowncast < T > { }
0 commit comments