]> git.proxmox.com Git - rustc.git/blame - src/libcore/convert.rs
Imported Upstream version 1.2.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
AL
19//!
20//! See each trait for usage examples.
c34b1796
AL
21
22#![stable(feature = "rust1", since = "1.0.0")]
23
24use marker::Sized;
25
26/// A cheap, reference-to-reference conversion.
9346a6ac 27///
d9579d0f
AL
28/// `AsRef` is very similar to, but different than, `Borrow`. See
29/// [the book][book] for more.
30///
31/// [book]: ../../book/borrow-and-asref.html
32///
9346a6ac
AL
33/// # Examples
34///
35/// Both `String` and `&str` implement `AsRef<str>`:
36///
37/// ```
38/// fn is_hello<T: AsRef<str>>(s: T) {
39/// assert_eq!("hello", s.as_ref());
40/// }
41///
42/// let s = "hello";
43/// is_hello(s);
44///
45/// let s = "hello".to_string();
46/// is_hello(s);
47/// ```
c34b1796
AL
48#[stable(feature = "rust1", since = "1.0.0")]
49pub trait AsRef<T: ?Sized> {
9346a6ac 50 /// Performs the conversion.
c34b1796
AL
51 #[stable(feature = "rust1", since = "1.0.0")]
52 fn as_ref(&self) -> &T;
53}
54
55/// A cheap, mutable reference-to-mutable reference conversion.
56#[stable(feature = "rust1", since = "1.0.0")]
57pub trait AsMut<T: ?Sized> {
9346a6ac 58 /// Performs the conversion.
c34b1796
AL
59 #[stable(feature = "rust1", since = "1.0.0")]
60 fn as_mut(&mut self) -> &mut T;
61}
62
9346a6ac
AL
63/// A conversion that consumes `self`, which may or may not be expensive.
64///
65/// # Examples
66///
67/// `String` implements `Into<Vec<u8>>`:
68///
69/// ```
70/// fn is_hello<T: Into<Vec<u8>>>(s: T) {
71/// let bytes = b"hello".to_vec();
72/// assert_eq!(bytes, s.into());
73/// }
74///
75/// let s = "hello".to_string();
76/// is_hello(s);
77/// ```
c34b1796
AL
78#[stable(feature = "rust1", since = "1.0.0")]
79pub trait Into<T>: Sized {
9346a6ac 80 /// Performs the conversion.
c34b1796
AL
81 #[stable(feature = "rust1", since = "1.0.0")]
82 fn into(self) -> T;
83}
84
85/// Construct `Self` via a conversion.
9346a6ac
AL
86///
87/// # Examples
88///
89/// `String` implements `From<&str>`:
90///
91/// ```
9346a6ac 92/// let string = "hello".to_string();
bd371182 93/// let other_string = String::from("hello");
9346a6ac
AL
94///
95/// assert_eq!(string, other_string);
96/// ```
c34b1796
AL
97#[stable(feature = "rust1", since = "1.0.0")]
98pub trait From<T> {
9346a6ac 99 /// Performs the conversion.
c34b1796
AL
100 #[stable(feature = "rust1", since = "1.0.0")]
101 fn from(T) -> Self;
102}
103
104////////////////////////////////////////////////////////////////////////////////
105// GENERIC IMPLS
106////////////////////////////////////////////////////////////////////////////////
107
108// As lifts over &
109#[stable(feature = "rust1", since = "1.0.0")]
110impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a T where T: AsRef<U> {
111 fn as_ref(&self) -> &U {
112 <T as AsRef<U>>::as_ref(*self)
113 }
114}
115
116// As lifts over &mut
117#[stable(feature = "rust1", since = "1.0.0")]
118impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T where T: AsRef<U> {
119 fn as_ref(&self) -> &U {
120 <T as AsRef<U>>::as_ref(*self)
121 }
122}
123
124// FIXME (#23442): replace the above impls for &/&mut with the following more general one:
125// // As lifts over Deref
126// impl<D: ?Sized + Deref, U: ?Sized> AsRef<U> for D where D::Target: AsRef<U> {
127// fn as_ref(&self) -> &U {
128// self.deref().as_ref()
129// }
130// }
131
132// AsMut lifts over &mut
133#[stable(feature = "rust1", since = "1.0.0")]
134impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T where T: AsMut<U> {
135 fn as_mut(&mut self) -> &mut U {
136 (*self).as_mut()
137 }
138}
139
140// FIXME (#23442): replace the above impl for &mut with the following more general one:
141// // AsMut lifts over DerefMut
142// impl<D: ?Sized + Deref, U: ?Sized> AsMut<U> for D where D::Target: AsMut<U> {
143// fn as_mut(&mut self) -> &mut U {
144// self.deref_mut().as_mut()
145// }
146// }
147
148// From implies Into
149#[stable(feature = "rust1", since = "1.0.0")]
150impl<T, U> Into<U> for T where U: From<T> {
151 fn into(self) -> U {
152 U::from(self)
153 }
154}
155
156// From (and thus Into) is reflexive
157#[stable(feature = "rust1", since = "1.0.0")]
158impl<T> From<T> for T {
159 fn from(t: T) -> T { t }
160}
161
162////////////////////////////////////////////////////////////////////////////////
163// CONCRETE IMPLS
164////////////////////////////////////////////////////////////////////////////////
165
166#[stable(feature = "rust1", since = "1.0.0")]
167impl<T> AsRef<[T]> for [T] {
168 fn as_ref(&self) -> &[T] {
169 self
170 }
171}
172
173#[stable(feature = "rust1", since = "1.0.0")]
174impl<T> AsMut<[T]> for [T] {
175 fn as_mut(&mut self) -> &mut [T] {
176 self
177 }
178}
179
180#[stable(feature = "rust1", since = "1.0.0")]
181impl AsRef<str> for str {
d9579d0f 182 #[inline]
c34b1796
AL
183 fn as_ref(&self) -> &str {
184 self
185 }
186}