]> git.proxmox.com Git - rustc.git/blame - src/libcore/convert.rs
New upstream version 1.13.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
c34b1796 43/// A cheap, reference-to-reference conversion.
9346a6ac 44///
9e0c209e 45/// `AsRef` is very similar to, but different than, [`Borrow`]. See
d9579d0f
AL
46/// [the book][book] for more.
47///
48/// [book]: ../../book/borrow-and-asref.html
9e0c209e 49/// [`Borrow`]: ../../std/borrow/trait.Borrow.html
d9579d0f 50///
7453a54e 51/// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which
9e0c209e
SL
52/// returns an [`Option<T>`] or a [`Result<T, E>`].
53///
54/// [`Option<T>`]: ../../std/option/enum.Option.html
55/// [`Result<T, E>`]: ../../std/result/enum.Result.html
7453a54e 56///
9346a6ac
AL
57/// # Examples
58///
9e0c209e
SL
59/// Both [`String`] and `&str` implement `AsRef<str>`:
60///
61/// [`String`]: ../../std/string/struct.String.html
9346a6ac
AL
62///
63/// ```
64/// fn is_hello<T: AsRef<str>>(s: T) {
65/// assert_eq!("hello", s.as_ref());
66/// }
67///
68/// let s = "hello";
69/// is_hello(s);
70///
71/// let s = "hello".to_string();
72/// is_hello(s);
73/// ```
7453a54e
SL
74///
75/// # Generic Impls
76///
5bcae85e
SL
77/// - `AsRef` auto-dereferences if the inner type is a reference or a mutable
78/// reference (e.g.: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`)
7453a54e 79///
c34b1796
AL
80#[stable(feature = "rust1", since = "1.0.0")]
81pub trait AsRef<T: ?Sized> {
9346a6ac 82 /// Performs the conversion.
c34b1796
AL
83 #[stable(feature = "rust1", since = "1.0.0")]
84 fn as_ref(&self) -> &T;
85}
86
87/// A cheap, mutable reference-to-mutable reference conversion.
7453a54e
SL
88///
89/// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which
9e0c209e
SL
90/// returns an [`Option<T>`] or a [`Result<T, E>`].
91///
92/// [`Option<T>`]: ../../std/option/enum.Option.html
93/// [`Result<T, E>`]: ../../std/result/enum.Result.html
94///
95/// # Examples
96///
97/// [`Box<T>`] implements `AsMut<T>`:
98///
99/// [`Box<T>`]: ../../std/boxed/struct.Box.html
100///
101/// ```
102/// fn add_one<T: AsMut<u64>>(num: &mut T) {
103/// *num.as_mut() += 1;
104/// }
105///
106/// let mut boxed_num = Box::new(0);
107/// add_one(&mut boxed_num);
108/// assert_eq!(*boxed_num, 1);
109/// ```
7453a54e
SL
110///
111/// # Generic Impls
112///
5bcae85e
SL
113/// - `AsMut` auto-dereferences if the inner type is a reference or a mutable
114/// reference (e.g.: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`)
7453a54e 115///
c34b1796
AL
116#[stable(feature = "rust1", since = "1.0.0")]
117pub trait AsMut<T: ?Sized> {
9346a6ac 118 /// Performs the conversion.
c34b1796
AL
119 #[stable(feature = "rust1", since = "1.0.0")]
120 fn as_mut(&mut self) -> &mut T;
121}
122
9346a6ac
AL
123/// A conversion that consumes `self`, which may or may not be expensive.
124///
9e0c209e
SL
125/// **Note: this trait must not fail**. If the conversion can fail, use [`TryInto`] or a dedicated
126/// method which returns an [`Option<T>`] or a [`Result<T, E>`].
7453a54e 127///
54a0048b 128/// Library authors should not directly implement this trait, but should prefer implementing
9e0c209e 129/// the [`From`][From] trait, which offers greater flexibility and provides an equivalent `Into`
7453a54e
SL
130/// implementation for free, thanks to a blanket implementation in the standard library.
131///
9346a6ac
AL
132/// # Examples
133///
9e0c209e 134/// [`String`] implements `Into<Vec<u8>>`:
9346a6ac
AL
135///
136/// ```
137/// fn is_hello<T: Into<Vec<u8>>>(s: T) {
138/// let bytes = b"hello".to_vec();
139/// assert_eq!(bytes, s.into());
140/// }
141///
142/// let s = "hello".to_string();
143/// is_hello(s);
144/// ```
7453a54e
SL
145///
146/// # Generic Impls
147///
9e0c209e
SL
148/// - `[From<T>][From] for U` implies `Into<U> for T`
149/// - [`into()`] is reflexive, which means that `Into<T> for T` is implemented
7453a54e 150///
9e0c209e
SL
151/// [`TryInto`]: trait.TryInto.html
152/// [`Option<T>`]: ../../std/option/enum.Option.html
153/// [`Result<T, E>`]: ../../std/result/enum.Result.html
154/// [`String`]: ../../std/string/struct.String.html
155/// [From]: trait.From.html
156/// [`into()`]: trait.Into.html#tymethod.into
c34b1796
AL
157#[stable(feature = "rust1", since = "1.0.0")]
158pub trait Into<T>: Sized {
9346a6ac 159 /// Performs the conversion.
c34b1796
AL
160 #[stable(feature = "rust1", since = "1.0.0")]
161 fn into(self) -> T;
162}
163
164/// Construct `Self` via a conversion.
9346a6ac 165///
9e0c209e
SL
166/// **Note: this trait must not fail**. If the conversion can fail, use [`TryFrom`] or a dedicated
167/// method which returns an [`Option<T>`] or a [`Result<T, E>`].
7453a54e 168///
9346a6ac
AL
169/// # Examples
170///
9e0c209e 171/// [`String`] implements `From<&str>`:
9346a6ac
AL
172///
173/// ```
9346a6ac 174/// let string = "hello".to_string();
bd371182 175/// let other_string = String::from("hello");
9346a6ac
AL
176///
177/// assert_eq!(string, other_string);
178/// ```
7453a54e
SL
179/// # Generic impls
180///
9e0c209e
SL
181/// - `From<T> for U` implies `[Into<U>] for T`
182/// - [`from()`] is reflexive, which means that `From<T> for T` is implemented
7453a54e 183///
9e0c209e
SL
184/// [`TryFrom`]: trait.TryFrom.html
185/// [`Option<T>`]: ../../std/option/enum.Option.html
186/// [`Result<T, E>`]: ../../std/result/enum.Result.html
187/// [`String`]: ../../std/string/struct.String.html
188/// [Into<U>]: trait.Into.html
189/// [`from()`]: trait.From.html#tymethod.from
c34b1796 190#[stable(feature = "rust1", since = "1.0.0")]
b039eaaf 191pub trait From<T>: Sized {
9346a6ac 192 /// Performs the conversion.
c34b1796
AL
193 #[stable(feature = "rust1", since = "1.0.0")]
194 fn from(T) -> Self;
195}
196
a7813a04
XL
197/// An attempted conversion that consumes `self`, which may or may not be expensive.
198///
199/// Library authors should not directly implement this trait, but should prefer implementing
9e0c209e 200/// the [`TryFrom`] trait, which offers greater flexibility and provides an equivalent `TryInto`
a7813a04 201/// implementation for free, thanks to a blanket implementation in the standard library.
9e0c209e
SL
202///
203/// [`TryFrom`]: trait.TryFrom.html
a7813a04
XL
204#[unstable(feature = "try_from", issue = "33417")]
205pub trait TryInto<T>: Sized {
206 /// The type returned in the event of a conversion error.
207 type Err;
208
209 /// Performs the conversion.
210 fn try_into(self) -> Result<T, Self::Err>;
211}
212
213/// Attempt to construct `Self` via a conversion.
214#[unstable(feature = "try_from", issue = "33417")]
215pub trait TryFrom<T>: Sized {
216 /// The type returned in the event of a conversion error.
217 type Err;
218
219 /// Performs the conversion.
220 fn try_from(T) -> Result<Self, Self::Err>;
221}
222
c34b1796
AL
223////////////////////////////////////////////////////////////////////////////////
224// GENERIC IMPLS
225////////////////////////////////////////////////////////////////////////////////
226
227// As lifts over &
228#[stable(feature = "rust1", since = "1.0.0")]
229impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a T where T: AsRef<U> {
230 fn as_ref(&self) -> &U {
231 <T as AsRef<U>>::as_ref(*self)
232 }
233}
234
235// As lifts over &mut
236#[stable(feature = "rust1", since = "1.0.0")]
237impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T where T: AsRef<U> {
238 fn as_ref(&self) -> &U {
239 <T as AsRef<U>>::as_ref(*self)
240 }
241}
242
243// FIXME (#23442): replace the above impls for &/&mut with the following more general one:
244// // As lifts over Deref
245// impl<D: ?Sized + Deref, U: ?Sized> AsRef<U> for D where D::Target: AsRef<U> {
246// fn as_ref(&self) -> &U {
247// self.deref().as_ref()
248// }
249// }
250
251// AsMut lifts over &mut
252#[stable(feature = "rust1", since = "1.0.0")]
253impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T where T: AsMut<U> {
254 fn as_mut(&mut self) -> &mut U {
255 (*self).as_mut()
256 }
257}
258
259// FIXME (#23442): replace the above impl for &mut with the following more general one:
260// // AsMut lifts over DerefMut
261// impl<D: ?Sized + Deref, U: ?Sized> AsMut<U> for D where D::Target: AsMut<U> {
262// fn as_mut(&mut self) -> &mut U {
263// self.deref_mut().as_mut()
264// }
265// }
266
267// From implies Into
268#[stable(feature = "rust1", since = "1.0.0")]
269impl<T, U> Into<U> for T where U: From<T> {
270 fn into(self) -> U {
271 U::from(self)
272 }
273}
274
275// From (and thus Into) is reflexive
276#[stable(feature = "rust1", since = "1.0.0")]
277impl<T> From<T> for T {
278 fn from(t: T) -> T { t }
279}
280
a7813a04
XL
281
282// TryFrom implies TryInto
283#[unstable(feature = "try_from", issue = "33417")]
284impl<T, U> TryInto<U> for T where U: TryFrom<T> {
285 type Err = U::Err;
286
287 fn try_into(self) -> Result<U, U::Err> {
288 U::try_from(self)
289 }
290}
291
c34b1796
AL
292////////////////////////////////////////////////////////////////////////////////
293// CONCRETE IMPLS
294////////////////////////////////////////////////////////////////////////////////
295
296#[stable(feature = "rust1", since = "1.0.0")]
297impl<T> AsRef<[T]> for [T] {
298 fn as_ref(&self) -> &[T] {
299 self
300 }
301}
302
303#[stable(feature = "rust1", since = "1.0.0")]
304impl<T> AsMut<[T]> for [T] {
305 fn as_mut(&mut self) -> &mut [T] {
306 self
307 }
308}
309
310#[stable(feature = "rust1", since = "1.0.0")]
311impl AsRef<str> for str {
d9579d0f 312 #[inline]
c34b1796
AL
313 fn as_ref(&self) -> &str {
314 self
315 }
316}