]>
Commit | Line | Data |
---|---|---|
c34b1796 AL |
1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | //! Traits for conversions between types. | |
12 | //! | |
62682a34 SL |
13 | //! The traits in this module provide a general way to talk about conversions |
14 | //! from one type to another. They follow the standard Rust conventions of | |
15 | //! `as`/`into`/`from`. | |
9346a6ac | 16 | //! |
62682a34 SL |
17 | //! Like many traits, these are often used as bounds for generic functions, to |
18 | //! support arguments of multiple types. | |
9346a6ac | 19 | //! |
7453a54e SL |
20 | //! - Impl the `As*` traits for reference-to-reference conversions |
21 | //! - Impl the `Into` trait when you want to consume the value in the conversion | |
54a0048b | 22 | //! - The `From` trait is the most flexible, useful for value _and_ reference conversions |
a7813a04 XL |
23 | //! - The `TryFrom` and `TryInto` traits behave like `From` and `Into`, but allow for the |
24 | //! conversion to fail | |
7453a54e | 25 | //! |
a7813a04 XL |
26 | //! As a library author, you should prefer implementing `From<T>` or `TryFrom<T>` rather than |
27 | //! `Into<U>` or `TryInto<U>`, as `From` and `TryFrom` provide greater flexibility and offer | |
28 | //! equivalent `Into` or `TryInto` implementations for free, thanks to a blanket implementation | |
29 | //! in the standard library. | |
7453a54e SL |
30 | //! |
31 | //! # Generic impl | |
32 | //! | |
33 | //! - `AsRef` and `AsMut` auto-dereference if the inner type is a reference | |
34 | //! - `From<U> for T` implies `Into<T> for U` | |
a7813a04 | 35 | //! - `TryFrom<U> for T` implies `TryInto<T> for U` |
7453a54e SL |
36 | //! - `From` and `Into` are reflexive, which means that all types can `into()` |
37 | //! themselves and `from()` themselves | |
38 | //! | |
9346a6ac | 39 | //! See each trait for usage examples. |
c34b1796 AL |
40 | |
41 | #![stable(feature = "rust1", since = "1.0.0")] | |
42 | ||
43 | use marker::Sized; | |
a7813a04 | 44 | use result::Result; |
c34b1796 AL |
45 | |
46 | /// A cheap, reference-to-reference conversion. | |
9346a6ac | 47 | /// |
d9579d0f AL |
48 | /// `AsRef` is very similar to, but different than, `Borrow`. See |
49 | /// [the book][book] for more. | |
50 | /// | |
51 | /// [book]: ../../book/borrow-and-asref.html | |
52 | /// | |
7453a54e | 53 | /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which |
54a0048b | 54 | /// returns an `Option<T>` or a `Result<T, E>`. |
7453a54e | 55 | /// |
9346a6ac AL |
56 | /// # Examples |
57 | /// | |
58 | /// Both `String` and `&str` implement `AsRef<str>`: | |
59 | /// | |
60 | /// ``` | |
61 | /// fn is_hello<T: AsRef<str>>(s: T) { | |
62 | /// assert_eq!("hello", s.as_ref()); | |
63 | /// } | |
64 | /// | |
65 | /// let s = "hello"; | |
66 | /// is_hello(s); | |
67 | /// | |
68 | /// let s = "hello".to_string(); | |
69 | /// is_hello(s); | |
70 | /// ``` | |
7453a54e SL |
71 | /// |
72 | /// # Generic Impls | |
73 | /// | |
5bcae85e SL |
74 | /// - `AsRef` auto-dereferences if the inner type is a reference or a mutable |
75 | /// reference (e.g.: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`) | |
7453a54e | 76 | /// |
c34b1796 AL |
77 | #[stable(feature = "rust1", since = "1.0.0")] |
78 | pub trait AsRef<T: ?Sized> { | |
9346a6ac | 79 | /// Performs the conversion. |
c34b1796 AL |
80 | #[stable(feature = "rust1", since = "1.0.0")] |
81 | fn as_ref(&self) -> &T; | |
82 | } | |
83 | ||
84 | /// A cheap, mutable reference-to-mutable reference conversion. | |
7453a54e SL |
85 | /// |
86 | /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which | |
54a0048b | 87 | /// returns an `Option<T>` or a `Result<T, E>`. |
7453a54e SL |
88 | /// |
89 | /// # Generic Impls | |
90 | /// | |
5bcae85e SL |
91 | /// - `AsMut` auto-dereferences if the inner type is a reference or a mutable |
92 | /// reference (e.g.: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`) | |
7453a54e | 93 | /// |
c34b1796 AL |
94 | #[stable(feature = "rust1", since = "1.0.0")] |
95 | pub trait AsMut<T: ?Sized> { | |
9346a6ac | 96 | /// Performs the conversion. |
c34b1796 AL |
97 | #[stable(feature = "rust1", since = "1.0.0")] |
98 | fn as_mut(&mut self) -> &mut T; | |
99 | } | |
100 | ||
9346a6ac AL |
101 | /// A conversion that consumes `self`, which may or may not be expensive. |
102 | /// | |
a7813a04 XL |
103 | /// **Note: this trait must not fail**. If the conversion can fail, use `TryInto` or a dedicated |
104 | /// method which returns an `Option<T>` or a `Result<T, E>`. | |
7453a54e | 105 | /// |
54a0048b SL |
106 | /// Library authors should not directly implement this trait, but should prefer implementing |
107 | /// the `From` trait, which offers greater flexibility and provides an equivalent `Into` | |
7453a54e SL |
108 | /// implementation for free, thanks to a blanket implementation in the standard library. |
109 | /// | |
9346a6ac AL |
110 | /// # Examples |
111 | /// | |
112 | /// `String` implements `Into<Vec<u8>>`: | |
113 | /// | |
114 | /// ``` | |
115 | /// fn is_hello<T: Into<Vec<u8>>>(s: T) { | |
116 | /// let bytes = b"hello".to_vec(); | |
117 | /// assert_eq!(bytes, s.into()); | |
118 | /// } | |
119 | /// | |
120 | /// let s = "hello".to_string(); | |
121 | /// is_hello(s); | |
122 | /// ``` | |
7453a54e SL |
123 | /// |
124 | /// # Generic Impls | |
125 | /// | |
126 | /// - `From<T> for U` implies `Into<U> for T` | |
127 | /// - `into()` is reflexive, which means that `Into<T> for T` is implemented | |
128 | /// | |
c34b1796 AL |
129 | #[stable(feature = "rust1", since = "1.0.0")] |
130 | pub trait Into<T>: Sized { | |
9346a6ac | 131 | /// Performs the conversion. |
c34b1796 AL |
132 | #[stable(feature = "rust1", since = "1.0.0")] |
133 | fn into(self) -> T; | |
134 | } | |
135 | ||
136 | /// Construct `Self` via a conversion. | |
9346a6ac | 137 | /// |
a7813a04 XL |
138 | /// **Note: this trait must not fail**. If the conversion can fail, use `TryFrom` or a dedicated |
139 | /// method which returns an `Option<T>` or a `Result<T, E>`. | |
7453a54e | 140 | /// |
9346a6ac AL |
141 | /// # Examples |
142 | /// | |
143 | /// `String` implements `From<&str>`: | |
144 | /// | |
145 | /// ``` | |
9346a6ac | 146 | /// let string = "hello".to_string(); |
bd371182 | 147 | /// let other_string = String::from("hello"); |
9346a6ac AL |
148 | /// |
149 | /// assert_eq!(string, other_string); | |
150 | /// ``` | |
7453a54e SL |
151 | /// # Generic impls |
152 | /// | |
153 | /// - `From<T> for U` implies `Into<U> for T` | |
154 | /// - `from()` is reflexive, which means that `From<T> for T` is implemented | |
155 | /// | |
c34b1796 | 156 | #[stable(feature = "rust1", since = "1.0.0")] |
b039eaaf | 157 | pub trait From<T>: Sized { |
9346a6ac | 158 | /// Performs the conversion. |
c34b1796 AL |
159 | #[stable(feature = "rust1", since = "1.0.0")] |
160 | fn from(T) -> Self; | |
161 | } | |
162 | ||
a7813a04 XL |
163 | /// An attempted conversion that consumes `self`, which may or may not be expensive. |
164 | /// | |
165 | /// Library authors should not directly implement this trait, but should prefer implementing | |
166 | /// the `TryFrom` trait, which offers greater flexibility and provides an equivalent `TryInto` | |
167 | /// implementation for free, thanks to a blanket implementation in the standard library. | |
168 | #[unstable(feature = "try_from", issue = "33417")] | |
169 | pub trait TryInto<T>: Sized { | |
170 | /// The type returned in the event of a conversion error. | |
171 | type Err; | |
172 | ||
173 | /// Performs the conversion. | |
174 | fn try_into(self) -> Result<T, Self::Err>; | |
175 | } | |
176 | ||
177 | /// Attempt to construct `Self` via a conversion. | |
178 | #[unstable(feature = "try_from", issue = "33417")] | |
179 | pub trait TryFrom<T>: Sized { | |
180 | /// The type returned in the event of a conversion error. | |
181 | type Err; | |
182 | ||
183 | /// Performs the conversion. | |
184 | fn try_from(T) -> Result<Self, Self::Err>; | |
185 | } | |
186 | ||
c34b1796 AL |
187 | //////////////////////////////////////////////////////////////////////////////// |
188 | // GENERIC IMPLS | |
189 | //////////////////////////////////////////////////////////////////////////////// | |
190 | ||
191 | // As lifts over & | |
192 | #[stable(feature = "rust1", since = "1.0.0")] | |
193 | impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a T where T: AsRef<U> { | |
194 | fn as_ref(&self) -> &U { | |
195 | <T as AsRef<U>>::as_ref(*self) | |
196 | } | |
197 | } | |
198 | ||
199 | // As lifts over &mut | |
200 | #[stable(feature = "rust1", since = "1.0.0")] | |
201 | impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T where T: AsRef<U> { | |
202 | fn as_ref(&self) -> &U { | |
203 | <T as AsRef<U>>::as_ref(*self) | |
204 | } | |
205 | } | |
206 | ||
207 | // FIXME (#23442): replace the above impls for &/&mut with the following more general one: | |
208 | // // As lifts over Deref | |
209 | // impl<D: ?Sized + Deref, U: ?Sized> AsRef<U> for D where D::Target: AsRef<U> { | |
210 | // fn as_ref(&self) -> &U { | |
211 | // self.deref().as_ref() | |
212 | // } | |
213 | // } | |
214 | ||
215 | // AsMut lifts over &mut | |
216 | #[stable(feature = "rust1", since = "1.0.0")] | |
217 | impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T where T: AsMut<U> { | |
218 | fn as_mut(&mut self) -> &mut U { | |
219 | (*self).as_mut() | |
220 | } | |
221 | } | |
222 | ||
223 | // FIXME (#23442): replace the above impl for &mut with the following more general one: | |
224 | // // AsMut lifts over DerefMut | |
225 | // impl<D: ?Sized + Deref, U: ?Sized> AsMut<U> for D where D::Target: AsMut<U> { | |
226 | // fn as_mut(&mut self) -> &mut U { | |
227 | // self.deref_mut().as_mut() | |
228 | // } | |
229 | // } | |
230 | ||
231 | // From implies Into | |
232 | #[stable(feature = "rust1", since = "1.0.0")] | |
233 | impl<T, U> Into<U> for T where U: From<T> { | |
234 | fn into(self) -> U { | |
235 | U::from(self) | |
236 | } | |
237 | } | |
238 | ||
239 | // From (and thus Into) is reflexive | |
240 | #[stable(feature = "rust1", since = "1.0.0")] | |
241 | impl<T> From<T> for T { | |
242 | fn from(t: T) -> T { t } | |
243 | } | |
244 | ||
a7813a04 XL |
245 | |
246 | // TryFrom implies TryInto | |
247 | #[unstable(feature = "try_from", issue = "33417")] | |
248 | impl<T, U> TryInto<U> for T where U: TryFrom<T> { | |
249 | type Err = U::Err; | |
250 | ||
251 | fn try_into(self) -> Result<U, U::Err> { | |
252 | U::try_from(self) | |
253 | } | |
254 | } | |
255 | ||
c34b1796 AL |
256 | //////////////////////////////////////////////////////////////////////////////// |
257 | // CONCRETE IMPLS | |
258 | //////////////////////////////////////////////////////////////////////////////// | |
259 | ||
260 | #[stable(feature = "rust1", since = "1.0.0")] | |
261 | impl<T> AsRef<[T]> for [T] { | |
262 | fn as_ref(&self) -> &[T] { | |
263 | self | |
264 | } | |
265 | } | |
266 | ||
267 | #[stable(feature = "rust1", since = "1.0.0")] | |
268 | impl<T> AsMut<[T]> for [T] { | |
269 | fn as_mut(&mut self) -> &mut [T] { | |
270 | self | |
271 | } | |
272 | } | |
273 | ||
274 | #[stable(feature = "rust1", since = "1.0.0")] | |
275 | impl AsRef<str> for str { | |
d9579d0f | 276 | #[inline] |
c34b1796 AL |
277 | fn as_ref(&self) -> &str { |
278 | self | |
279 | } | |
280 | } |