]> git.proxmox.com Git - rustc.git/blame - src/libcore/convert.rs
New upstream version 1.12.0+dfsg1
[rustc.git] / src / libcore / convert.rs
CommitLineData
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
43use marker::Sized;
a7813a04 44use 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")]
78pub 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")]
95pub 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")]
130pub 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 157pub 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")]
169pub 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")]
179pub 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")]
193impl<'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")]
201impl<'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")]
217impl<'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")]
233impl<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")]
241impl<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")]
248impl<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")]
261impl<T> AsRef<[T]> for [T] {
262 fn as_ref(&self) -> &[T] {
263 self
264 }
265}
266
267#[stable(feature = "rust1", since = "1.0.0")]
268impl<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")]
275impl AsRef<str> for str {
d9579d0f 276 #[inline]
c34b1796
AL
277 fn as_ref(&self) -> &str {
278 self
279 }
280}