Expose Variant under internals.

This commit is contained in:
Stephen Chung 2021-03-05 14:18:36 +08:00
parent 2052942d9d
commit 8f0830af1c
2 changed files with 59 additions and 37 deletions

View File

@ -43,7 +43,10 @@ mod private {
impl<T: Any + Clone + SendSync> Sealed for T {} impl<T: Any + Clone + SendSync> Sealed for T {}
} }
/// Trait to represent any type. /// _(INTERNALS)_ Trait to represent any type.
/// Exported under the `internals` feature only.
///
/// This trait is sealed and cannot be implemented.
/// ///
/// Currently, [`Variant`] is not [`Send`] nor [`Sync`], so it can practically be any type. /// Currently, [`Variant`] is not [`Send`] nor [`Sync`], so it can practically be any type.
/// Turn on the `sync` feature to restrict it to only types that implement [`Send`] `+` [`Sync`]. /// Turn on the `sync` feature to restrict it to only types that implement [`Send`] `+` [`Sync`].
@ -68,7 +71,10 @@ pub trait Variant: Any + private::Sealed {
fn clone_into_dynamic(&self) -> Dynamic; fn clone_into_dynamic(&self) -> Dynamic;
} }
/// Trait to represent any type. /// _(INTERNALS)_ Trait to represent any type.
/// Exported under the `internals` feature only.
///
/// This trait is sealed and cannot be implemented.
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
pub trait Variant: Any + Send + Sync + private::Sealed { pub trait Variant: Any + Send + Sync + private::Sealed {
/// Convert this [`Variant`] trait object to [`&dyn Any`][Any]. /// Convert this [`Variant`] trait object to [`&dyn Any`][Any].
@ -326,11 +332,14 @@ impl Dynamic {
Union::Variant(value, _) => (***value).type_id(), Union::Variant(value, _) => (***value).type_id(),
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[cfg(not(feature = "sync"))] Union::Shared(cell, _) => {
Union::Shared(cell, _) => (*cell.borrow()).type_id(), #[cfg(not(feature = "sync"))]
#[cfg(not(feature = "no_closure"))] let value = cell.borrow();
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
Union::Shared(cell, _) => (*cell.read().unwrap()).type_id(), let value = cell.read().unwrap();
(*value).type_id()
}
} }
} }
/// Get the name of the type of the value held by this [`Dynamic`]. /// Get the name of the type of the value held by this [`Dynamic`].
@ -397,11 +406,14 @@ impl Hash for Dynamic {
} }
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[cfg(not(feature = "sync"))] Union::Shared(cell, _) => {
Union::Shared(cell, _) => (*cell.borrow()).hash(state), #[cfg(not(feature = "sync"))]
#[cfg(not(feature = "no_closure"))] let value = cell.borrow();
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
Union::Shared(cell, _) => (*cell.read().unwrap()).hash(state), let value = cell.read().unwrap();
(*value).hash(state)
}
_ => unimplemented!("{} cannot be hashed", self.type_name()), _ => unimplemented!("{} cannot be hashed", self.type_name()),
} }
@ -742,11 +754,11 @@ impl Dynamic {
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
Union::Shared(ref cell, _) => { Union::Shared(ref cell, _) => {
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
let access = cell.borrow().access_mode(); let value = cell.borrow();
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
let access = cell.read().unwrap().access_mode(); let value = cell.read().unwrap();
match access { match value.access_mode() {
AccessMode::ReadWrite => false, AccessMode::ReadWrite => false,
AccessMode::ReadOnly => true, AccessMode::ReadOnly => true,
} }
@ -775,11 +787,14 @@ impl Dynamic {
Union::Map(_, _) => true, Union::Map(_, _) => true,
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[cfg(not(feature = "sync"))] Union::Shared(cell, _) => {
Union::Shared(cell, _) => cell.borrow().is_hashable(), #[cfg(not(feature = "sync"))]
#[cfg(not(feature = "no_closure"))] let value = cell.borrow();
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
Union::Shared(cell, _) => cell.read().unwrap().is_hashable(), let value = cell.read().unwrap();
value.is_hashable()
}
_ => false, _ => false,
} }
@ -1126,10 +1141,11 @@ impl Dynamic {
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
Union::Shared(cell, _) => { Union::Shared(cell, _) => {
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
return cell.borrow().clone(); let value = cell.borrow();
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
return cell.read().unwrap().clone(); let value = cell.read().unwrap();
value.clone()
} }
_ => self.clone(), _ => self.clone(),
} }
@ -1147,9 +1163,11 @@ impl Dynamic {
Union::Shared(cell, _) => crate::fn_native::shared_try_take(cell).map_or_else( Union::Shared(cell, _) => crate::fn_native::shared_try_take(cell).map_or_else(
|cell| { |cell| {
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
return cell.borrow().clone(); let value = cell.borrow();
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
return cell.read().unwrap().clone(); let value = cell.read().unwrap();
value.clone()
}, },
|value| { |value| {
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
@ -1197,16 +1215,16 @@ impl Dynamic {
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
Union::Shared(ref cell, _) => { Union::Shared(ref cell, _) => {
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
let data = cell.borrow(); let value = cell.borrow();
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
let data = cell.read().unwrap(); let value = cell.read().unwrap();
let type_id = (*data).type_id(); let type_id = (*value).type_id();
if type_id != TypeId::of::<T>() && TypeId::of::<Dynamic>() != TypeId::of::<T>() { if type_id != TypeId::of::<T>() && TypeId::of::<Dynamic>() != TypeId::of::<T>() {
None None
} else { } else {
Some(DynamicReadLock(DynamicReadLockInner::Guard(data))) Some(DynamicReadLock(DynamicReadLockInner::Guard(value)))
} }
} }
_ => self _ => self
@ -1229,16 +1247,16 @@ impl Dynamic {
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
Union::Shared(ref cell, _) => { Union::Shared(ref cell, _) => {
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
let data = cell.borrow_mut(); let value = cell.borrow_mut();
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
let data = cell.write().unwrap(); let value = cell.write().unwrap();
let type_id = (*data).type_id(); let type_id = (*value).type_id();
if type_id != TypeId::of::<T>() && TypeId::of::<Dynamic>() != TypeId::of::<T>() { if type_id != TypeId::of::<T>() && TypeId::of::<Dynamic>() != TypeId::of::<T>() {
None None
} else { } else {
Some(DynamicWriteLock(DynamicWriteLockInner::Guard(data))) Some(DynamicWriteLock(DynamicWriteLockInner::Guard(value)))
} }
} }
_ => self _ => self
@ -1537,13 +1555,13 @@ impl Dynamic {
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
Union::Shared(cell, _) => { Union::Shared(cell, _) => {
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
let data = cell.borrow(); let value = cell.borrow();
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
let data = cell.read().unwrap(); let value = cell.read().unwrap();
match &data.0 { match &value.0 {
Union::Str(s, _) => Ok(s.clone()), Union::Str(s, _) => Ok(s.clone()),
_ => Err((*data).type_name()), _ => Err((*value).type_name()),
} }
} }
_ => Err(self.type_name()), _ => Err(self.type_name()),

View File

@ -180,6 +180,10 @@ pub mod serde;
#[cfg(not(feature = "no_optimize"))] #[cfg(not(feature = "no_optimize"))]
pub use optimize::OptimizationLevel; pub use optimize::OptimizationLevel;
#[cfg(feature = "internals")]
#[deprecated = "this type is volatile and may change"]
pub use dynamic::Variant;
// Expose internal data structures. // Expose internal data structures.
#[cfg(feature = "internals")] #[cfg(feature = "internals")]
#[deprecated = "this type is volatile and may change"] #[deprecated = "this type is volatile and may change"]