pipe_trait/lib.rs
1#![doc = include_str!("doc.md")]
2#![no_std]
3use core::{
4 borrow::{Borrow, BorrowMut},
5 ops::{Deref, DerefMut},
6};
7
8/// All sized types implement this trait.
9pub trait Pipe {
10 /// Apply `f` to `self`.
11 ///
12 /// ```
13 /// # #[derive(Debug, PartialEq, Eq)]
14 /// # struct Foo(i32);
15 /// # fn double(x: i32) -> i32 { x * 2 }
16 /// # use pipe_trait::*;
17 /// assert_eq!(
18 /// 12.pipe(double).pipe(Foo),
19 /// Foo(double(12)),
20 /// )
21 /// ```
22 #[inline]
23 fn pipe<Return, Function>(self, f: Function) -> Return
24 where
25 Self: Sized,
26 Function: FnOnce(Self) -> Return,
27 {
28 f(self)
29 }
30
31 /// Apply `f` to `&self`.
32 ///
33 /// ```
34 /// # use pipe_trait::*;
35 /// #[derive(Debug, PartialEq, Eq)]
36 /// struct Foo(i32);
37 /// let a = Foo(12);
38 /// let b = a
39 /// .pipe_ref(|a| a.0) // a is not moved
40 /// .pipe(Foo);
41 /// assert_eq!(a, b); // a is used again
42 /// ```
43 #[inline]
44 fn pipe_ref<'a, Return, Function>(&'a self, f: Function) -> Return
45 where
46 Function: FnOnce(&'a Self) -> Return,
47 {
48 f(self)
49 }
50
51 /// Apply `f` to `&mut self`.
52 ///
53 /// ```
54 /// # use pipe_trait::*;
55 /// #[derive(Debug, PartialEq, Eq)]
56 /// struct Foo(i32, i32);
57 /// let mut a = Foo(0, 0);
58 /// a.pipe_mut(|a| a.0 = 12);
59 /// a.pipe_mut(|a| a.1 = 34);
60 /// assert_eq!(a, Foo(12, 34));
61 /// ```
62 #[inline]
63 fn pipe_mut<'a, Return, Function>(&'a mut self, f: Function) -> Return
64 where
65 Function: FnOnce(&'a mut Self) -> Return,
66 {
67 f(self)
68 }
69
70 /// Apply `f` to `&self` where `f` takes a single parameter of type `Param`
71 /// and `Self` implements trait [`AsRef<Param>`].
72 ///
73 /// ```
74 /// # use pipe_trait::*;
75 /// fn uppercase(x: &str) -> String {
76 /// x.to_uppercase()
77 /// }
78 /// let x: String = "abc".to_string();
79 /// let y: String = x.pipe_as_ref(uppercase);
80 /// assert_eq!(y, "ABC");
81 /// ```
82 #[inline]
83 fn pipe_as_ref<'a, Param, Return, Function>(&'a self, f: Function) -> Return
84 where
85 Self: AsRef<Param>,
86 Param: ?Sized + 'a,
87 Function: FnOnce(&'a Param) -> Return,
88 {
89 f(self.as_ref())
90 }
91
92 /// Apply `f` to `&mut self` where `f` takes a single parameter of type `Param`
93 /// and `Self` implements trait [`AsMut<Param>`].
94 ///
95 /// ```
96 /// # use pipe_trait::*;
97 /// fn modify(target: &mut [i32]) {
98 /// target[0] = 123;
99 /// }
100 /// let mut vec: Vec<i32> = vec![0, 1, 2, 3];
101 /// vec.pipe_as_mut(modify);
102 /// assert_eq!(vec, vec![123, 1, 2, 3]);
103 /// ```
104 #[inline]
105 fn pipe_as_mut<'a, Param, Return, Function>(&'a mut self, f: Function) -> Return
106 where
107 Self: AsMut<Param>,
108 Param: ?Sized + 'a,
109 Function: FnOnce(&'a mut Param) -> Return,
110 {
111 f(self.as_mut())
112 }
113
114 /// Apply `f` to `&self` where `f` takes a single parameter of type `Param`
115 /// and `Self` implements trait `Deref<Target = Param>`.
116 ///
117 /// ```
118 /// # use pipe_trait::*;
119 /// fn uppercase(x: &str) -> String {
120 /// x.to_uppercase()
121 /// }
122 /// let x: String = "abc".to_string();
123 /// let y: String = x.pipe_deref(uppercase);
124 /// assert_eq!(y, "ABC");
125 /// ```
126 #[inline]
127 fn pipe_deref<'a, Param, Return, Function>(&'a self, f: Function) -> Return
128 where
129 Self: Deref<Target = Param>,
130 Param: ?Sized + 'a,
131 Function: FnOnce(&'a Param) -> Return,
132 {
133 f(self)
134 }
135
136 /// Apply `f` to `&mut self` where `f` takes a single parameter of type `Param`
137 /// and `Self` implements trait [`DerefMut<Target = Param>`].
138 ///
139 /// ```
140 /// # use pipe_trait::*;
141 /// fn modify(target: &mut [i32]) {
142 /// target[0] = 123;
143 /// }
144 /// let mut vec: Vec<i32> = vec![0, 1, 2, 3];
145 /// vec.pipe_deref_mut(modify);
146 /// assert_eq!(vec, vec![123, 1, 2, 3]);
147 /// ```
148 #[inline]
149 fn pipe_deref_mut<'a, Param, Return, Function>(&'a mut self, f: Function) -> Return
150 where
151 Self: DerefMut<Target = Param>,
152 Param: ?Sized + 'a,
153 Function: FnOnce(&'a mut Param) -> Return,
154 {
155 f(self)
156 }
157
158 /// Apply `f` to `&self` where `f` takes a single parameter of type `Param`
159 /// and `Self` implements trait [`Borrow<Param>`].
160 ///
161 /// ```
162 /// # use pipe_trait::*;
163 /// fn uppercase(x: &str) -> String {
164 /// x.to_uppercase()
165 /// }
166 /// let x: String = "abc".to_string();
167 /// let y: String = x.pipe_borrow(uppercase);
168 /// assert_eq!(y, "ABC");
169 /// ```
170 #[inline]
171 fn pipe_borrow<'a, Param, Return, Function>(&'a self, f: Function) -> Return
172 where
173 Self: Borrow<Param>,
174 Param: ?Sized + 'a,
175 Function: FnOnce(&'a Param) -> Return,
176 {
177 f(self.borrow())
178 }
179
180 /// Apply `f` to `&mut self` where `f` takes a single parameter of type `Param`
181 /// and `Self` implements trait [`BorrowMut<Param>`].
182 ///
183 /// ```
184 /// # use pipe_trait::*;
185 /// fn modify(target: &mut [i32]) {
186 /// target[0] = 123;
187 /// }
188 /// let mut vec: Vec<i32> = vec![0, 1, 2, 3];
189 /// vec.pipe_borrow_mut(modify);
190 /// assert_eq!(vec, vec![123, 1, 2, 3]);
191 /// ```
192 #[inline]
193 fn pipe_borrow_mut<'a, Param, Return, Function>(&'a mut self, f: Function) -> Return
194 where
195 Self: BorrowMut<Param>,
196 Param: ?Sized + 'a,
197 Function: FnOnce(&'a mut Param) -> Return,
198 {
199 f(self.borrow_mut())
200 }
201}
202
203impl<X> Pipe for X {}
204
205#[cfg(test)]
206mod tests;