read.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. use std::ops::Deref;
  2. /// A trait for states that can be read from like [`crate::Signal`], [`crate::GlobalSignal`], or [`crate::ReadOnlySignal`]. You may choose to accept this trait as a parameter instead of the concrete type to allow for more flexibility in your API. For example, instead of creating two functions, one that accepts a [`crate::Signal`] and one that accepts a [`crate::GlobalSignal`], you can create one function that accepts a [`Readable`] type.
  3. pub trait Readable<T: 'static = ()> {
  4. /// The type of the reference.
  5. type Ref<R: ?Sized + 'static>: Deref<Target = R>;
  6. /// Map the reference to a new type.
  7. fn map_ref<I, U: ?Sized, F: FnOnce(&I) -> &U>(ref_: Self::Ref<I>, f: F) -> Self::Ref<U>;
  8. /// Try to map the reference to a new type.
  9. fn try_map_ref<I, U: ?Sized, F: FnOnce(&I) -> Option<&U>>(
  10. ref_: Self::Ref<I>,
  11. f: F,
  12. ) -> Option<Self::Ref<U>>;
  13. /// Get the current value of the state. If this is a signal, this will subscribe the current scope to the signal. If the value has been dropped, this will panic.
  14. fn read(&self) -> Self::Ref<T>;
  15. /// Get the current value of the state without subscribing to updates. If the value has been dropped, this will panic.
  16. fn peek(&self) -> Self::Ref<T>;
  17. /// Clone the inner value and return it. If the value has been dropped, this will panic.
  18. #[track_caller]
  19. fn cloned(&self) -> T
  20. where
  21. T: Clone,
  22. {
  23. self.read().clone()
  24. }
  25. /// Run a function with a reference to the value. If the value has been dropped, this will panic.
  26. #[track_caller]
  27. fn with<O>(&self, f: impl FnOnce(&T) -> O) -> O {
  28. f(&*self.read())
  29. }
  30. /// Run a function with a reference to the value. If the value has been dropped, this will panic.
  31. #[track_caller]
  32. fn with_peek<O>(&self, f: impl FnOnce(&T) -> O) -> O {
  33. f(&*self.peek())
  34. }
  35. /// Index into the inner value and return a reference to the result. If the value has been dropped or the index is invalid, this will panic.
  36. #[track_caller]
  37. fn index<I>(&self, index: I) -> Self::Ref<T::Output>
  38. where
  39. T: std::ops::Index<I>,
  40. {
  41. Self::map_ref(self.read(), |v| v.index(index))
  42. }
  43. }
  44. /// An extension trait for Readable<Vec<T>> that provides some convenience methods.
  45. pub trait ReadableVecExt<T: 'static>: Readable<Vec<T>> {
  46. /// Returns the length of the inner vector.
  47. #[track_caller]
  48. fn len(&self) -> usize {
  49. self.with(|v| v.len())
  50. }
  51. /// Returns true if the inner vector is empty.
  52. #[track_caller]
  53. fn is_empty(&self) -> bool {
  54. self.with(|v| v.is_empty())
  55. }
  56. /// Get the first element of the inner vector.
  57. #[track_caller]
  58. fn first(&self) -> Option<Self::Ref<T>> {
  59. Self::try_map_ref(self.read(), |v| v.first())
  60. }
  61. /// Get the last element of the inner vector.
  62. #[track_caller]
  63. fn last(&self) -> Option<Self::Ref<T>> {
  64. Self::try_map_ref(self.read(), |v| v.last())
  65. }
  66. /// Get the element at the given index of the inner vector.
  67. #[track_caller]
  68. fn get(&self, index: usize) -> Option<Self::Ref<T>> {
  69. Self::try_map_ref(self.read(), |v| v.get(index))
  70. }
  71. /// Get an iterator over the values of the inner vector.
  72. #[track_caller]
  73. fn iter(&self) -> ReadableValueIterator<T, Self>
  74. where
  75. Self: Sized + Clone,
  76. {
  77. ReadableValueIterator {
  78. index: 0,
  79. value: self.clone(),
  80. phantom: std::marker::PhantomData,
  81. }
  82. }
  83. }
  84. /// An iterator over the values of a `Readable<Vec<T>>`.
  85. pub struct ReadableValueIterator<T, R> {
  86. index: usize,
  87. value: R,
  88. phantom: std::marker::PhantomData<T>,
  89. }
  90. impl<T: 'static, R: Readable<Vec<T>>> Iterator for ReadableValueIterator<T, R> {
  91. type Item = R::Ref<T>;
  92. fn next(&mut self) -> Option<Self::Item> {
  93. let index = self.index;
  94. self.index += 1;
  95. self.value.get(index)
  96. }
  97. }
  98. impl<T, R> ReadableVecExt<T> for R
  99. where
  100. T: 'static,
  101. R: Readable<Vec<T>>,
  102. {
  103. }
  104. /// An extension trait for Readable<Option<T>> that provides some convenience methods.
  105. pub trait ReadableOptionExt<T: 'static>: Readable<Option<T>> {
  106. /// Unwraps the inner value and clones it.
  107. #[track_caller]
  108. fn unwrap(&self) -> T
  109. where
  110. T: Clone,
  111. {
  112. self.as_ref().unwrap().clone()
  113. }
  114. /// Attempts to read the inner value of the Option.
  115. #[track_caller]
  116. fn as_ref(&self) -> Option<Self::Ref<T>> {
  117. Self::try_map_ref(self.read(), |v| v.as_ref())
  118. }
  119. }
  120. impl<T, R> ReadableOptionExt<T> for R
  121. where
  122. T: 'static,
  123. R: Readable<Option<T>>,
  124. {
  125. }