mirror of https://github.com/boa-dev/boa.git
HalidOdat
4 years ago
1 changed files with 64 additions and 0 deletions
@ -0,0 +1,64 @@ |
|||||||
|
//! Implementations for storing normal rust structs inside any object as internal state.
|
||||||
|
|
||||||
|
use std::{ |
||||||
|
any::Any, |
||||||
|
fmt::{self, Debug}, |
||||||
|
ops::{Deref, DerefMut}, |
||||||
|
rc::Rc, |
||||||
|
}; |
||||||
|
|
||||||
|
use gc::{unsafe_empty_trace, Finalize, Trace}; |
||||||
|
|
||||||
|
/// Wrapper around `Rc` to implement `Trace` and `Finalize`.
|
||||||
|
#[derive(Clone)] |
||||||
|
pub struct InternalStateCell { |
||||||
|
/// The internal state.
|
||||||
|
state: Rc<dyn Any>, |
||||||
|
} |
||||||
|
|
||||||
|
impl Finalize for InternalStateCell {} |
||||||
|
|
||||||
|
unsafe impl Trace for InternalStateCell { |
||||||
|
unsafe_empty_trace!(); |
||||||
|
} |
||||||
|
|
||||||
|
impl Deref for InternalStateCell { |
||||||
|
type Target = dyn Any; |
||||||
|
fn deref(&self) -> &Self::Target { |
||||||
|
Deref::deref(&self.state) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl DerefMut for InternalStateCell { |
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target { |
||||||
|
Rc::get_mut(&mut self.state).expect("failed to get mutable") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// The derived version would print 'InternalStateCell { state: ... }', this custom implementation
|
||||||
|
/// only prints the actual internal state.
|
||||||
|
impl Debug for InternalStateCell { |
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
||||||
|
Debug::fmt(&self.state, f) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl InternalStateCell { |
||||||
|
/// Create new `InternalStateCell` from a value.
|
||||||
|
pub fn new<T: Any + InternalState>(value: T) -> Self { |
||||||
|
Self { |
||||||
|
state: Rc::new(value), |
||||||
|
} |
||||||
|
} |
||||||
|
/// Get a reference to the stored value and cast it to `T`.
|
||||||
|
pub fn downcast_ref<T: Any + InternalState>(&self) -> Option<&T> { |
||||||
|
self.deref().downcast_ref::<T>() |
||||||
|
} |
||||||
|
/// Get a mutable reference to the stored value and cast it to `T`.
|
||||||
|
pub fn downcast_mut<T: Any + InternalState>(&mut self) -> Option<&mut T> { |
||||||
|
self.deref_mut().downcast_mut::<T>() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// This trait must be implemented by all structs used for internal state.
|
||||||
|
pub trait InternalState: Debug {} |
Loading…
Reference in new issue