]> git.proxmox.com Git - rustc.git/blob - src/libcore/convert.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / libcore / convert.rs
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 //!
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`.
16 //!
17 //! Like many traits, these are often used as bounds for generic functions, to
18 //! support arguments of multiple types.
19 //!
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
22 //! - The `From` trait is the most flexible, useful for value _and_ reference conversions
23 //!
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`
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
29 //! method which returns an `Option<T>` or a `Result<T, E>`.
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 //!
38 //! See each trait for usage examples.
39
40 #![stable(feature = "rust1", since = "1.0.0")]
41
42 use marker::Sized;
43
44 /// A cheap, reference-to-reference conversion.
45 ///
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 ///
51 /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which
52 /// returns an `Option<T>` or a `Result<T, E>`.
53 ///
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 /// ```
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 ///
75 #[stable(feature = "rust1", since = "1.0.0")]
76 pub trait AsRef<T: ?Sized> {
77 /// Performs the conversion.
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.
83 ///
84 /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which
85 /// returns an `Option<T>` or a `Result<T, E>`.
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 ///
92 #[stable(feature = "rust1", since = "1.0.0")]
93 pub trait AsMut<T: ?Sized> {
94 /// Performs the conversion.
95 #[stable(feature = "rust1", since = "1.0.0")]
96 fn as_mut(&mut self) -> &mut T;
97 }
98
99 /// A conversion that consumes `self`, which may or may not be expensive.
100 ///
101 /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which
102 /// returns an `Option<T>` or a `Result<T, E>`.
103 ///
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`
106 /// implementation for free, thanks to a blanket implementation in the standard library.
107 ///
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 /// ```
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 ///
127 #[stable(feature = "rust1", since = "1.0.0")]
128 pub trait Into<T>: Sized {
129 /// Performs the conversion.
130 #[stable(feature = "rust1", since = "1.0.0")]
131 fn into(self) -> T;
132 }
133
134 /// Construct `Self` via a conversion.
135 ///
136 /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which
137 /// returns an `Option<T>` or a `Result<T, E>`.
138 ///
139 /// # Examples
140 ///
141 /// `String` implements `From<&str>`:
142 ///
143 /// ```
144 /// let string = "hello".to_string();
145 /// let other_string = String::from("hello");
146 ///
147 /// assert_eq!(string, other_string);
148 /// ```
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 ///
154 #[stable(feature = "rust1", since = "1.0.0")]
155 pub trait From<T>: Sized {
156 /// Performs the conversion.
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 {
239 #[inline]
240 fn as_ref(&self) -> &str {
241 self
242 }
243 }