]> git.proxmox.com Git - rustc.git/blame - src/libcore/convert.rs
Imported Upstream version 1.9.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
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
42use 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")]
76pub 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")]
93pub 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")]
128pub 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 155pub 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")]
167impl<'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")]
175impl<'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")]
191impl<'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")]
207impl<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")]
215impl<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")]
224impl<T> AsRef<[T]> for [T] {
225 fn as_ref(&self) -> &[T] {
226 self
227 }
228}
229
230#[stable(feature = "rust1", since = "1.0.0")]
231impl<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")]
238impl AsRef<str> for str {
d9579d0f 239 #[inline]
c34b1796
AL
240 fn as_ref(&self) -> &str {
241 self
242 }
243}