Thanks to visit codestin.com
Credit goes to docs.rs

orx_concurrent_vec/
elem.rs

1use orx_concurrent_option::ConcurrentOption;
2
3/// An element of the `ConcurrentVec` that provides thread safe
4/// read and write methods on the value of the element.
5///
6/// A concurrent element can be created by using the index operator `vec[i]`
7/// or calling [`vec.get(i)`] or [`vec.iter()`] on a concurrent vec or slice.
8///
9/// [`vec.get(i)`]: crate::ConcurrentVec::get
10/// [`vec.iter()`]: crate::ConcurrentVec::iter
11pub struct ConcurrentElement<T>(pub(crate) ConcurrentOption<T>);
12
13impl<T> From<ConcurrentOption<T>> for ConcurrentElement<T> {
14    fn from(value: ConcurrentOption<T>) -> Self {
15        Self(value)
16    }
17}
18
19impl<T> ConcurrentElement<T> {
20    /// Returns a clone of value of the element.
21    ///
22    /// # Examples
23    ///
24    /// ```rust
25    /// use orx_concurrent_vec::*;
26    ///
27    /// let vec = ConcurrentVec::new();
28    /// vec.extend(["foo", "bar"].map(|x| x.to_string()));
29    ///
30    /// assert_eq!(vec[0].cloned(), "foo".to_string());
31    /// assert_eq!(vec[1].cloned(), "bar".to_string());
32    ///
33    /// vec[1].set("baz".to_string());
34    /// assert_eq!(vec[1].cloned(), "baz".to_string());
35    /// ```
36    #[inline(always)]
37    #[allow(clippy::missing_panics_doc)]
38    pub fn cloned(&self) -> T
39    where
40        T: Clone,
41    {
42        self.0.clone_into_option().expect(HAS_VALUE)
43    }
44
45    /// Returns a copy of value of the element.
46    ///
47    /// # Examples
48    ///
49    /// ```rust
50    /// use orx_concurrent_vec::*;
51    ///
52    /// let vec = ConcurrentVec::new();
53    /// vec.extend([42, 7]);
54    ///
55    /// assert_eq!(vec[0].copied(), 42);
56    /// assert_eq!(vec[1].copied(), 7);
57    ///
58    /// vec[1].set(0);
59    /// assert_eq!(vec[1].copied(), 0);
60    /// ```
61    #[inline(always)]
62    #[allow(clippy::missing_panics_doc)]
63    pub fn copied(&self) -> T
64    where
65        T: Copy,
66    {
67        self.0.clone_into_option().expect(HAS_VALUE)
68    }
69
70    /// Maps the value and returns the result of `f(&element)`.
71    ///
72    /// # Examples
73    ///
74    /// ```rust
75    /// use orx_concurrent_vec::*;
76    ///
77    /// let vec: ConcurrentVec<_> = [0, 1, 2, 3].into_iter().collect();
78    ///
79    /// let one = vec[1].map(|x| x.to_string());
80    /// assert_eq!(one, 1.to_string());
81    ///
82    /// let doubles: Vec<_> = vec.iter().map(|elem| elem.map(|x| x * 2)).collect();
83    /// assert_eq!(doubles, [0, 2, 4, 6]);
84    ///
85    /// let mut sum = 0;
86    /// for i in 0..vec.len() {
87    ///     vec[i].map(|x| {
88    ///         sum += x;
89    ///     });
90    /// }
91    /// assert_eq!(sum, 6);
92    /// ```
93    #[inline(always)]
94    #[allow(clippy::missing_panics_doc)]
95    pub fn map<F, U>(&self, f: F) -> U
96    where
97        F: FnOnce(&T) -> U,
98    {
99        self.0.map(f).expect(HAS_VALUE)
100    }
101
102    // mut
103
104    /// Replaces the current value of the element
105    /// with the given `value`, and returns the old value.
106    ///
107    /// See also [`set`] if the old value is to be omitted.
108    ///
109    /// [`set`]: crate::ConcurrentElement::set
110    ///
111    /// # Examples
112    ///
113    /// ```rust
114    /// use orx_concurrent_vec::*;
115    ///
116    /// let vec = ConcurrentVec::from_iter(['a', 'b', 'c', 'd']);
117    ///
118    /// let c = vec[2].replace('x');
119    ///
120    /// assert_eq!(c, 'c');
121    /// assert_eq!(&vec, &['a', 'b', 'x', 'd']);
122    /// ```
123    #[inline(always)]
124    #[allow(clippy::missing_panics_doc)]
125    pub fn replace(&self, value: T) -> T {
126        self.0.replace(value).expect(HAS_VALUE)
127    }
128
129    /// Sets (overwrites) value of the element with the given `value`.
130    ///
131    /// See also [`replace`] if the old value is required.
132    ///
133    /// [`replace`]: crate::ConcurrentElement::replace
134    ///
135    /// # Examples
136    ///
137    /// ```rust
138    /// use orx_concurrent_vec::*;
139    ///
140    /// let vec = ConcurrentVec::new();
141    /// vec.extend(['a', 'b', 'c', 'd']);
142    ///
143    /// vec[2].set('x');
144    /// assert_eq!(&vec, &['a', 'b', 'x', 'd']);
145    /// ```
146    #[inline(always)]
147    #[allow(clippy::missing_panics_doc)]
148    pub fn set(&self, value: T) {
149        assert!(self.0.set_some(value), "Failed to set the element");
150    }
151
152    /// Updates the current value of the element by calling the mutating
153    /// function `f(&mut element)`.
154    ///
155    /// # Examples
156    ///
157    /// ```rust
158    /// use orx_concurrent_vec::*;
159    ///
160    /// let vec = ConcurrentVec::from_iter([0, 1, 2, 3]);
161    ///
162    /// vec[1].update(|x| *x *= 2);
163    /// vec[2].update(|x| *x += 10);
164    /// vec[3].update(|x| *x = 7);
165    ///
166    /// assert_eq!(&vec, &[0, 2, 12, 7]);
167    /// ```
168    #[inline(always)]
169    #[allow(clippy::missing_panics_doc)]
170    pub fn update<F>(&self, f: F)
171    where
172        F: FnMut(&mut T),
173    {
174        assert!(self.0.update_if_some(f), "Failed to update the element");
175    }
176}
177
178// constants
179
180const HAS_VALUE: &str = "ConcurrentElement must always have a value";