@@ -461,6 +461,12 @@ impl_dyn_casting!(PlatformWindowAttributes);
461461///
462462/// The surface is closed when dropped.
463463pub trait Surface : AsAny + Send + Sync + fmt:: Debug {
464+ /// Attempts to downcast this surface to a core surface type, e.g. [`Window`].
465+ fn try_downcast ( & self ) -> Option < SurfaceDowncastRef < ' _ > > ;
466+
467+ /// Attempts to downcast this surface mutably to a core surface type, e.g. [`Window`].
468+ fn try_downcast_mut ( & mut self ) -> Option < SurfaceDowncastMut < ' _ > > ;
469+
464470 /// Returns an identifier unique to the window.
465471 fn id ( & self ) -> SurfaceId ;
466472
@@ -1965,3 +1971,47 @@ mod tests {
19651971 . is_some( ) ) ;
19661972 }
19671973}
1974+ /// Dynamic reference to one of the common surface traits.
1975+ pub enum SurfaceDowncastRef < ' a > {
1976+ /// A toplevel window, see [`Window`] for details.
1977+ Window ( & ' a dyn Window ) ,
1978+ }
1979+
1980+ /// Dynamic mutable reference to one of the common surface traits.
1981+ pub enum SurfaceDowncastMut < ' a > {
1982+ /// A toplevel window, see [`Window`] for details.
1983+ Window ( & ' a mut dyn Window ) ,
1984+ }
1985+
1986+ /// Helper macro for implementing [`Surface::try_downcast`] and [`Surface::try_downcast_mut`].
1987+ /// ## Syntax
1988+ /// Use the names of variants of [`SurfaceDowncastRef`] or [`SurfaceDowncastMut`] to return that type:
1989+ /// ```ignore
1990+ /// impl_surface_downcast!(Window);
1991+ /// ```
1992+ /// You may also use the special identifier `None` to cause the downcast to fail.
1993+ /// ```ignore
1994+ /// impl_surface_downcast!(None);
1995+ /// ```
1996+ #[ macro_export]
1997+ macro_rules! impl_surface_downcast {
1998+ ( None ) => {
1999+ fn try_downcast( & self ) -> Option <$crate:: window:: SurfaceDowncastRef <' _>> {
2000+ None
2001+ }
2002+
2003+ fn try_downcast_mut( & mut self ) -> Option <$crate:: window:: SurfaceDowncastMut <' _>> {
2004+ None
2005+ }
2006+ } ;
2007+ ( $variant: ident) => {
2008+ fn try_downcast( & self ) -> Option <$crate:: window:: SurfaceDowncastRef <' _>> {
2009+ Some ( $crate:: window:: SurfaceDowncastRef :: $variant( self ) )
2010+ }
2011+
2012+ fn try_downcast_mut( & mut self ) -> Option <$crate:: window:: SurfaceDowncastMut <' _>> {
2013+ Some ( $crate:: window:: SurfaceDowncastMut :: $variant( self ) )
2014+
2015+ }
2016+ } ;
2017+ }
0 commit comments