core_extensions/
self_ops.rs

1//! Universal extension trait.Implemented for every type.
2
3
4/// Extension trait for every type.
5#[cfg_attr(feature = "docsrs", doc(cfg(feature = "self_ops")))]
6pub trait SelfOps {
7    /// Compares the address of `self` with the address of `other`.
8    ///
9    /// # Example
10    ///
11    /// ```
12    /// use core_extensions::SelfOps;
13    ///
14    /// let a = 5.to_string();
15    /// let b = 5.to_string();
16    ///
17    /// assert!(!a.eq_id(&b));
18    /// assert!(!b.eq_id(&a));
19    /// assert!( a.eq_id(&a));
20    /// assert!( b.eq_id(&b));
21    /// assert_eq!(a,b);
22    ///
23    /// ```
24    fn eq_id(&self, other: &Self) -> bool {
25        (self as *const Self) == (other as *const Self)
26    }
27
28    /// Emulates the pipeline operator, allowing method syntax in more places.
29    ///
30    /// Allows calling functions as part of a method chain.
31    ///
32    ///
33    /// # Example
34    ///
35    /// ```
36    /// use core_extensions::SelfOps;
37    ///
38    /// use std::sync::{Mutex, Arc};
39    ///
40    /// let hello = "hello"
41    ///     .to_string()
42    ///     .mutated(|s| s.push_str("_world"))
43    ///     .piped(Mutex::new)
44    ///     .piped(Arc::new);
45    ///
46    /// assert_eq!(hello.lock().unwrap().as_str(), "hello_world");
47    /// ```
48    ///
49    /// # Example,calling functions
50    /// ```
51    /// use core_extensions::SelfOps;
52    ///
53    /// # fn opposed<S:AsRef<str>>(s:S)->String{
54    /// #     let s=s.as_ref();
55    /// #     format!("{}{}",s,s.chars().rev().collect::<String>())
56    /// # }
57    /// 
58    /// "what"
59    ///     .piped(|x| opposed(x) + "-")
60    ///     .observe(|s| assert_eq!(s, "whattahw-"))
61    ///     .piped(opposed)
62    ///     .observe(|s| assert_eq!(s, "whattahw--whattahw"));
63    /// ```
64    ///
65    #[inline(always)]
66    fn piped<F, U>(self, f: F) -> U
67    where
68        F: FnOnce(Self) -> U,
69        Self: Sized,
70    {
71        f(self)
72    }
73
74    /// The same as `piped` except that the function takes `&Self`
75    /// Useful for functions that take `&Self` instead of `Self`.
76    ///
77    /// # Example
78    ///
79    /// ```
80    /// use core_extensions::SelfOps;
81    ///
82    /// let problem = "air".to_string();
83    /// let edited = problem.piped_ref(|s| format!("{} problems.", s));
84    ///
85    /// println!("{:?}", problem); // problem wasn't consumed by `.piped_ref`
86    /// assert_eq!(edited, "air problems.");
87    ///
88    /// ```
89    ///
90    #[inline(always)]
91    fn piped_ref<'a, F, U>(&'a self, f: F) -> U
92    where
93        F: FnOnce(&'a Self) -> U,
94    {
95        f(self)
96    }
97
98    /// The same as `piped`, except that the function takes `&mut Self`.
99    /// Useful for functions that take `&mut Self` instead of `Self`.
100    ///
101    #[inline(always)]
102    fn piped_mut<'a, F, U>(&'a mut self, f: F) -> U
103    where
104        F: FnOnce(&'a mut Self) -> U,
105    {
106        f(self)
107    }
108
109    /// Mutates self using a closure taking self by mutable reference,
110    /// passing it along the method chain.
111    ///
112    /// This is useful for initializing a variable and then freezing it.
113    ///
114    /// # Example of initialization
115    ///
116    /// ```
117    /// use core_extensions::SelfOps;
118    ///
119    /// let list = Vec::new().mutated(|v|{
120    ///     v.push("This");
121    ///     v.push("is");
122    ///     v.push("[redacted]");
123    /// });
124    ///
125    /// assert_eq!(list.join(" "), "This is [redacted]");
126    ///
127    /// ```
128    ///
129    /// # Example of mutating in a method chain
130    /// ```
131    /// use core_extensions::SelfOps;
132    ///
133    /// "what".to_string()
134    ///     .mutated(|v| v.push_str(" the") )
135    ///     .observe(|v| assert_eq!(v, "what the") );
136    ///
137    /// ```
138    ///  
139    #[inline(always)]
140    fn mutated<F>(mut self, f: F) -> Self
141    where
142        F: FnOnce(&mut Self),
143        Self: Sized,
144    {
145        f(&mut self);
146        self
147    }
148    /// Observes the value of self, passing it along unmodified.
149    /// Useful in long method chains.
150    ///
151    /// # Example
152    ///
153    /// ```
154    /// use core_extensions::SelfOps;
155    ///
156    /// let v = "1234"
157    ///     .parse()
158    ///     .observe(|d| assert_eq!(&Ok(1234), d))
159    ///     .unwrap();
160    ///
161    /// assert_eq!(v,1234);
162    /// ```
163    ///
164    #[inline(always)]
165    fn observe<F>(self, f: F) -> Self
166    where
167        F: FnOnce(&Self),
168        Self: Sized,
169    {
170        f(&self);
171        self
172    }
173
174    /// Performs a conversion with `Into`.
175    /// using the turbofish `.into_::<_>()` syntax.
176    ///
177    /// # Example
178    /// ```
179    /// use core_extensions::SelfOps;
180    /// use std::borrow::Cow;
181    ///
182    /// let word = "hello";
183    ///
184    /// assert_eq!(word, word.into_::<Cow<'_, _>>());
185    /// assert_eq!(word, word.into_::<Cow<'_, str>>());
186    /// assert_eq!(word, word.into_::<String>());
187    ///
188    /// let vec_=||vec![0,1,2,3];
189    /// assert_eq!(vec_().into_::<Cow<'_, _>>(), vec_());
190    /// assert_eq!(vec_().into_::<Cow<'_, _>>(), vec_());
191    /// assert_eq!(vec_().into_::<Vec<_>>()    , vec_());
192    /// assert_eq!(vec_().into_::<Vec<_>>()    , vec_());
193    ///
194    /// ```
195    #[inline(always)]
196    fn into_<T>(self) -> T
197    where
198        Self: Into<T>,
199    {
200        self.into()
201    }
202
203    /// Performs a reference to reference conversion with `AsRef`,
204    /// using the turbofish `.as_ref_::<_>()` syntax.
205    ///
206    /// # Example
207    /// ```
208    /// use core_extensions::SelfOps;
209    ///
210    /// let s = "the path";
211    ///
212    /// assert_eq!(s, s.as_ref_::<str>());
213    /// ```
214    #[inline(always)]
215    fn as_ref_<T: ?Sized>(&self) -> &T
216    where
217        Self: AsRef<T>,
218    {
219        self.as_ref()
220    }
221    /// Performs a mutable reference to mutable reference conversion with `AsMut`,
222    /// using the turbofish `.as_mut_::<_>()` syntax.
223    ///
224    /// # Example
225    /// ```
226    /// use core_extensions::SelfOps;
227    ///
228    /// let mut s_0 = vec![1, 2, 3, 4];
229    /// let mut s_1 = s_0.clone();
230    ///
231    /// assert_eq!(s_1, s_0.as_mut_::<[_]>());
232    /// ```
233    #[inline(always)]
234    fn as_mut_<T: ?Sized>(&mut self) -> &mut T
235    where
236        Self: AsMut<T>,
237    {
238        self.as_mut()
239    }
240    /// Drops `self` using method notation.
241    /// Alternative to `std::mem::drop`.
242    ///
243    /// # Example,ignore #\[must_use\] values.
244    /// ```
245    /// #![deny(unused_must_use)]
246    /// use std::fmt::Write;
247    ///
248    /// use core_extensions::SelfOps;
249    ///
250    /// let mut buff=String::new();
251    ///
252    /// buff.write_str("hello_").drop_();
253    /// buff.write_str("world").drop_();
254    ///
255    /// assert_eq!(buff, "hello_world");
256    ///
257    /// ```
258    #[inline(always)]
259    fn drop_(self)
260    where
261        Self: Sized,
262    {
263    }
264
265    #[doc(hidden)]
266    #[allow(dead_code)]
267    /// Prevents creating a trait object of this trait
268    fn _dummy_generic_method_preventing_trait_object<F>(self: &Self) {}
269}
270impl<T: ?Sized> SelfOps for T {}