/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! The `Castable` trait. use std::mem; use crate::conversions::{DerivedFrom, IDLInterface, get_dom_class}; use crate::reflector::DomObject; use crate::script_runtime::runtime_is_alive; /// A trait to hold the cast functions of IDL interfaces that either derive /// or are derived from other interfaces. pub trait Castable: IDLInterface + DomObject + Sized { /// Check whether a DOM object implements one of its deriving interfaces. fn is(&self) -> bool where T: DerivedFrom, { // This is a weird place for this check to live, but it should catch any // attempts to interact with DOM objects from Drop implementations that run // as a result of the runtime shutting down and finalizing all remaining objects. debug_assert!( runtime_is_alive(), "Attempting to interact with DOM objects after JS runtime has shut down." ); let class = unsafe { get_dom_class(self.reflector().get_jsobject().get()).unwrap() }; T::derives(class) } /// Cast a DOM object upwards to one of the interfaces it derives from. fn upcast(&self) -> &T where T: Castable, Self: DerivedFrom, { unsafe { mem::transmute::<&Self, &T>(self) } } /// Cast a DOM object downwards to one of the interfaces it might implement. fn downcast(&self) -> Option<&T> where T: DerivedFrom, { if self.is::() { Some(unsafe { mem::transmute::<&Self, &T>(self) }) } else { None } } } #[allow(missing_docs)] pub trait HasParent { #[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)] type Parent; fn as_parent(&self) -> &Self::Parent; }