]>
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 |
7453a54e | 23 | //! |
54a0048b SL |
24 | //! As a library author, you should prefer implementing `From<T>` rather than |
25 | //! `Into<U>`, as `From` provides greater flexibility and offers an equivalent `Into` | |
7453a54e SL |
26 | //! implementation for free, thanks to a blanket implementation in the standard library. |
27 | //! | |
28 | //! **Note: these traits must not fail**. If the conversion can fail, you must use a dedicated | |
54a0048b | 29 | //! method which returns an `Option<T>` or a `Result<T, E>`. |
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` | |
35 | //! - `From` and `Into` are reflexive, which means that all types can `into()` | |
36 | //! themselves and `from()` themselves | |
37 | //! | |
9346a6ac | 38 | //! See each trait for usage examples. |
c34b1796 AL |
39 | |
40 | #![stable(feature = "rust1", since = "1.0.0")] | |
41 | ||
42 | use marker::Sized; | |
43 | ||
44 | /// A cheap, reference-to-reference conversion. | |
9346a6ac | 45 | /// |
d9579d0f AL |
46 | /// `AsRef` is very similar to, but different than, `Borrow`. See |
47 | /// [the book][book] for more. | |
48 | /// | |
49 | /// [book]: ../../book/borrow-and-asref.html | |
50 | /// | |
7453a54e | 51 | /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which |
54a0048b | 52 | /// returns an `Option<T>` or a `Result<T, E>`. |
7453a54e | 53 | /// |
9346a6ac AL |
54 | /// # Examples |
55 | /// | |
56 | /// Both `String` and `&str` implement `AsRef<str>`: | |
57 | /// | |
58 | /// ``` | |
59 | /// fn is_hello<T: AsRef<str>>(s: T) { | |
60 | /// assert_eq!("hello", s.as_ref()); | |
61 | /// } | |
62 | /// | |
63 | /// let s = "hello"; | |
64 | /// is_hello(s); | |
65 | /// | |
66 | /// let s = "hello".to_string(); | |
67 | /// is_hello(s); | |
68 | /// ``` | |
7453a54e SL |
69 | /// |
70 | /// # Generic Impls | |
71 | /// | |
72 | /// - `AsRef` auto-dereference if the inner type is a reference or a mutable | |
73 | /// reference (eg: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`) | |
74 | /// | |
c34b1796 AL |
75 | #[stable(feature = "rust1", since = "1.0.0")] |
76 | pub trait AsRef<T: ?Sized> { | |
9346a6ac | 77 | /// Performs the conversion. |
c34b1796 AL |
78 | #[stable(feature = "rust1", since = "1.0.0")] |
79 | fn as_ref(&self) -> &T; | |
80 | } | |
81 | ||
82 | /// A cheap, mutable reference-to-mutable reference conversion. | |
7453a54e SL |
83 | /// |
84 | /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which | |
54a0048b | 85 | /// returns an `Option<T>` or a `Result<T, E>`. |
7453a54e SL |
86 | /// |
87 | /// # Generic Impls | |
88 | /// | |
89 | /// - `AsMut` auto-dereference if the inner type is a reference or a mutable | |
90 | /// reference (eg: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`) | |
91 | /// | |
c34b1796 AL |
92 | #[stable(feature = "rust1", since = "1.0.0")] |
93 | pub trait AsMut<T: ?Sized> { | |
9346a6ac | 94 | /// Performs the conversion. |
c34b1796 AL |
95 | #[stable(feature = "rust1", since = "1.0.0")] |
96 | fn as_mut(&mut self) -> &mut T; | |
97 | } | |
98 | ||
9346a6ac AL |
99 | /// A conversion that consumes `self`, which may or may not be expensive. |
100 | /// | |
7453a54e | 101 | /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which |
54a0048b | 102 | /// returns an `Option<T>` or a `Result<T, E>`. |
7453a54e | 103 | /// |
54a0048b SL |
104 | /// Library authors should not directly implement this trait, but should prefer implementing |
105 | /// the `From` trait, which offers greater flexibility and provides an equivalent `Into` | |
7453a54e SL |
106 | /// implementation for free, thanks to a blanket implementation in the standard library. |
107 | /// | |
9346a6ac AL |
108 | /// # Examples |
109 | /// | |
110 | /// `String` implements `Into<Vec<u8>>`: | |
111 | /// | |
112 | /// ``` | |
113 | /// fn is_hello<T: Into<Vec<u8>>>(s: T) { | |
114 | /// let bytes = b"hello".to_vec(); | |
115 | /// assert_eq!(bytes, s.into()); | |
116 | /// } | |
117 | /// | |
118 | /// let s = "hello".to_string(); | |
119 | /// is_hello(s); | |
120 | /// ``` | |
7453a54e SL |
121 | /// |
122 | /// # Generic Impls | |
123 | /// | |
124 | /// - `From<T> for U` implies `Into<U> for T` | |
125 | /// - `into()` is reflexive, which means that `Into<T> for T` is implemented | |
126 | /// | |
c34b1796 AL |
127 | #[stable(feature = "rust1", since = "1.0.0")] |
128 | pub trait Into<T>: Sized { | |
9346a6ac | 129 | /// Performs the conversion. |
c34b1796 AL |
130 | #[stable(feature = "rust1", since = "1.0.0")] |
131 | fn into(self) -> T; | |
132 | } | |
133 | ||
134 | /// Construct `Self` via a conversion. | |
9346a6ac | 135 | /// |
7453a54e | 136 | /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which |
54a0048b | 137 | /// returns an `Option<T>` or a `Result<T, E>`. |
7453a54e | 138 | /// |
9346a6ac AL |
139 | /// # Examples |
140 | /// | |
141 | /// `String` implements `From<&str>`: | |
142 | /// | |
143 | /// ``` | |
9346a6ac | 144 | /// let string = "hello".to_string(); |
bd371182 | 145 | /// let other_string = String::from("hello"); |
9346a6ac AL |
146 | /// |
147 | /// assert_eq!(string, other_string); | |
148 | /// ``` | |
7453a54e SL |
149 | /// # Generic impls |
150 | /// | |
151 | /// - `From<T> for U` implies `Into<U> for T` | |
152 | /// - `from()` is reflexive, which means that `From<T> for T` is implemented | |
153 | /// | |
c34b1796 | 154 | #[stable(feature = "rust1", since = "1.0.0")] |
b039eaaf | 155 | pub trait From<T>: Sized { |
9346a6ac | 156 | /// Performs the conversion. |
c34b1796 AL |
157 | #[stable(feature = "rust1", since = "1.0.0")] |
158 | fn from(T) -> Self; | |
159 | } | |
160 | ||
161 | //////////////////////////////////////////////////////////////////////////////// | |
162 | // GENERIC IMPLS | |
163 | //////////////////////////////////////////////////////////////////////////////// | |
164 | ||
165 | // As lifts over & | |
166 | #[stable(feature = "rust1", since = "1.0.0")] | |
167 | impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a T where T: AsRef<U> { | |
168 | fn as_ref(&self) -> &U { | |
169 | <T as AsRef<U>>::as_ref(*self) | |
170 | } | |
171 | } | |
172 | ||
173 | // As lifts over &mut | |
174 | #[stable(feature = "rust1", since = "1.0.0")] | |
175 | impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T where T: AsRef<U> { | |
176 | fn as_ref(&self) -> &U { | |
177 | <T as AsRef<U>>::as_ref(*self) | |
178 | } | |
179 | } | |
180 | ||
181 | // FIXME (#23442): replace the above impls for &/&mut with the following more general one: | |
182 | // // As lifts over Deref | |
183 | // impl<D: ?Sized + Deref, U: ?Sized> AsRef<U> for D where D::Target: AsRef<U> { | |
184 | // fn as_ref(&self) -> &U { | |
185 | // self.deref().as_ref() | |
186 | // } | |
187 | // } | |
188 | ||
189 | // AsMut lifts over &mut | |
190 | #[stable(feature = "rust1", since = "1.0.0")] | |
191 | impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T where T: AsMut<U> { | |
192 | fn as_mut(&mut self) -> &mut U { | |
193 | (*self).as_mut() | |
194 | } | |
195 | } | |
196 | ||
197 | // FIXME (#23442): replace the above impl for &mut with the following more general one: | |
198 | // // AsMut lifts over DerefMut | |
199 | // impl<D: ?Sized + Deref, U: ?Sized> AsMut<U> for D where D::Target: AsMut<U> { | |
200 | // fn as_mut(&mut self) -> &mut U { | |
201 | // self.deref_mut().as_mut() | |
202 | // } | |
203 | // } | |
204 | ||
205 | // From implies Into | |
206 | #[stable(feature = "rust1", since = "1.0.0")] | |
207 | impl<T, U> Into<U> for T where U: From<T> { | |
208 | fn into(self) -> U { | |
209 | U::from(self) | |
210 | } | |
211 | } | |
212 | ||
213 | // From (and thus Into) is reflexive | |
214 | #[stable(feature = "rust1", since = "1.0.0")] | |
215 | impl<T> From<T> for T { | |
216 | fn from(t: T) -> T { t } | |
217 | } | |
218 | ||
219 | //////////////////////////////////////////////////////////////////////////////// | |
220 | // CONCRETE IMPLS | |
221 | //////////////////////////////////////////////////////////////////////////////// | |
222 | ||
223 | #[stable(feature = "rust1", since = "1.0.0")] | |
224 | impl<T> AsRef<[T]> for [T] { | |
225 | fn as_ref(&self) -> &[T] { | |
226 | self | |
227 | } | |
228 | } | |
229 | ||
230 | #[stable(feature = "rust1", since = "1.0.0")] | |
231 | impl<T> AsMut<[T]> for [T] { | |
232 | fn as_mut(&mut self) -> &mut [T] { | |
233 | self | |
234 | } | |
235 | } | |
236 | ||
237 | #[stable(feature = "rust1", since = "1.0.0")] | |
238 | impl AsRef<str> for str { | |
d9579d0f | 239 | #[inline] |
c34b1796 AL |
240 | fn as_ref(&self) -> &str { |
241 | self | |
242 | } | |
243 | } |