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 {}