copy_value.rs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. use generational_box::GenerationalBoxId;
  2. use generational_box::UnsyncStorage;
  3. use std::ops::Deref;
  4. use dioxus_core::prelude::*;
  5. use generational_box::{GenerationalBox, Storage};
  6. use crate::read_impls;
  7. use crate::Readable;
  8. use crate::ReadableRef;
  9. use crate::Writable;
  10. use crate::WritableRef;
  11. use crate::{default_impl, write_impls};
  12. /// CopyValue is a wrapper around a value to make the value mutable and Copy.
  13. ///
  14. /// It is internally backed by [`generational_box::GenerationalBox`].
  15. pub struct CopyValue<T: 'static, S: Storage<T> = UnsyncStorage> {
  16. pub(crate) value: GenerationalBox<T, S>,
  17. origin_scope: ScopeId,
  18. }
  19. #[cfg(feature = "serialize")]
  20. impl<T: 'static, Store: Storage<T>> serde::Serialize for CopyValue<T, Store>
  21. where
  22. T: serde::Serialize,
  23. {
  24. fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
  25. self.value.read().serialize(serializer)
  26. }
  27. }
  28. #[cfg(feature = "serialize")]
  29. impl<'de, T: 'static, Store: Storage<T>> serde::Deserialize<'de> for CopyValue<T, Store>
  30. where
  31. T: serde::Deserialize<'de>,
  32. {
  33. fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
  34. let value = T::deserialize(deserializer)?;
  35. Ok(Self::new_maybe_sync(value))
  36. }
  37. }
  38. impl<T: 'static> CopyValue<T> {
  39. /// Create a new CopyValue. The value will be stored in the current component.
  40. ///
  41. /// Once the component this value is created in is dropped, the value will be dropped.
  42. #[track_caller]
  43. pub fn new(value: T) -> Self {
  44. Self::new_maybe_sync(value)
  45. }
  46. /// Create a new CopyValue. The value will be stored in the given scope. When the specified scope is dropped, the value will be dropped.
  47. #[track_caller]
  48. pub fn new_in_scope(value: T, scope: ScopeId) -> Self {
  49. Self::new_maybe_sync_in_scope(value, scope)
  50. }
  51. }
  52. impl<T: 'static, S: Storage<T>> CopyValue<T, S> {
  53. /// Create a new CopyValue. The value will be stored in the current component.
  54. ///
  55. /// Once the component this value is created in is dropped, the value will be dropped.
  56. #[track_caller]
  57. pub fn new_maybe_sync(value: T) -> Self {
  58. let owner = current_owner();
  59. Self {
  60. value: owner.insert(value),
  61. origin_scope: current_scope_id().expect("in a virtual dom"),
  62. }
  63. }
  64. pub(crate) fn new_with_caller(
  65. value: T,
  66. #[cfg(debug_assertions)] caller: &'static std::panic::Location<'static>,
  67. ) -> Self {
  68. let owner = current_owner();
  69. Self {
  70. value: owner.insert_with_caller(
  71. value,
  72. #[cfg(debug_assertions)]
  73. caller,
  74. ),
  75. origin_scope: current_scope_id().expect("in a virtual dom"),
  76. }
  77. }
  78. /// Create a new CopyValue. The value will be stored in the given scope. When the specified scope is dropped, the value will be dropped.
  79. #[track_caller]
  80. pub fn new_maybe_sync_in_scope(value: T, scope: ScopeId) -> Self {
  81. let owner = scope.owner();
  82. Self {
  83. value: owner.insert(value),
  84. origin_scope: scope,
  85. }
  86. }
  87. /// Manually drop the value in the CopyValue, invalidating the value in the process.
  88. pub fn manually_drop(&self) -> Option<T> {
  89. self.value.manually_drop()
  90. }
  91. /// Get the scope this value was created in.
  92. pub fn origin_scope(&self) -> ScopeId {
  93. self.origin_scope
  94. }
  95. /// Get the generational id of the value.
  96. pub fn id(&self) -> GenerationalBoxId {
  97. self.value.id()
  98. }
  99. /// Get the underlying [`GenerationalBox`] value.
  100. pub fn value(&self) -> GenerationalBox<T, S> {
  101. self.value
  102. }
  103. }
  104. impl<T: 'static, S: Storage<T>> Readable for CopyValue<T, S> {
  105. type Target = T;
  106. type Storage = S;
  107. #[track_caller]
  108. fn try_read_unchecked(
  109. &self,
  110. ) -> Result<ReadableRef<'static, Self>, generational_box::BorrowError> {
  111. self.value.try_read()
  112. }
  113. #[track_caller]
  114. fn peek_unchecked(&self) -> ReadableRef<'static, Self> {
  115. self.value.read()
  116. }
  117. }
  118. impl<T: 'static, S: Storage<T>> Writable for CopyValue<T, S> {
  119. type Mut<'a, R: ?Sized + 'static> = S::Mut<'a, R>;
  120. fn map_mut<I: ?Sized, U: ?Sized, F: FnOnce(&mut I) -> &mut U>(
  121. mut_: Self::Mut<'_, I>,
  122. f: F,
  123. ) -> Self::Mut<'_, U> {
  124. S::map_mut(mut_, f)
  125. }
  126. fn try_map_mut<I: ?Sized, U: ?Sized, F: FnOnce(&mut I) -> Option<&mut U>>(
  127. mut_: Self::Mut<'_, I>,
  128. f: F,
  129. ) -> Option<Self::Mut<'_, U>> {
  130. S::try_map_mut(mut_, f)
  131. }
  132. fn downcast_lifetime_mut<'a: 'b, 'b, R: ?Sized + 'static>(
  133. mut_: Self::Mut<'a, R>,
  134. ) -> Self::Mut<'b, R> {
  135. S::downcast_lifetime_mut(mut_)
  136. }
  137. #[track_caller]
  138. fn try_write_unchecked(
  139. &self,
  140. ) -> Result<WritableRef<'static, Self>, generational_box::BorrowMutError> {
  141. self.value.try_write()
  142. }
  143. #[track_caller]
  144. fn set(&mut self, value: T) {
  145. self.value.set(value);
  146. }
  147. }
  148. impl<T: 'static, S: Storage<T>> PartialEq for CopyValue<T, S> {
  149. fn eq(&self, other: &Self) -> bool {
  150. self.value.ptr_eq(&other.value)
  151. }
  152. }
  153. impl<T: 'static, S: Storage<T>> Eq for CopyValue<T, S> {}
  154. impl<T: Copy, S: Storage<T>> Deref for CopyValue<T, S> {
  155. type Target = dyn Fn() -> T;
  156. fn deref(&self) -> &Self::Target {
  157. Readable::deref_impl(self)
  158. }
  159. }
  160. impl<T, S: Storage<T>> Clone for CopyValue<T, S> {
  161. fn clone(&self) -> Self {
  162. *self
  163. }
  164. }
  165. impl<T, S: Storage<T>> Copy for CopyValue<T, S> {}
  166. read_impls!(CopyValue<T, S: Storage<T>>);
  167. default_impl!(CopyValue<T, S: Storage<T>>);
  168. write_impls!(CopyValue<T, S: Storage<T>>);