]>
git.proxmox.com Git - rustc.git/blob - 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.
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.
11 //! Traits for conversions between types.
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`.
17 //! Like many traits, these are often used as bounds for generic functions, to
18 //! support arguments of multiple types.
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
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.
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>`.
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
38 //! See each trait for usage examples.
40 #![stable(feature = "rust1", since = "1.0.0")]
44 /// A cheap, reference-to-reference conversion.
46 /// `AsRef` is very similar to, but different than, `Borrow`. See
47 /// [the book][book] for more.
49 /// [book]: ../../book/borrow-and-asref.html
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>`.
56 /// Both `String` and `&str` implement `AsRef<str>`:
59 /// fn is_hello<T: AsRef<str>>(s: T) {
60 /// assert_eq!("hello", s.as_ref());
66 /// let s = "hello".to_string();
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`)
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
;
82 /// A cheap, mutable reference-to-mutable reference conversion.
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>`.
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`)
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
;
99 /// A conversion that consumes `self`, which may or may not be expensive.
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>`.
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.
110 /// `String` implements `Into<Vec<u8>>`:
113 /// fn is_hello<T: Into<Vec<u8>>>(s: T) {
114 /// let bytes = b"hello".to_vec();
115 /// assert_eq!(bytes, s.into());
118 /// let s = "hello".to_string();
124 /// - `From<T> for U` implies `Into<U> for T`
125 /// - `into()` is reflexive, which means that `Into<T> for T` is implemented
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")]
134 /// Construct `Self` via a conversion.
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>`.
141 /// `String` implements `From<&str>`:
144 /// let string = "hello".to_string();
145 /// let other_string = String::from("hello");
147 /// assert_eq!(string, other_string);
151 /// - `From<T> for U` implies `Into<U> for T`
152 /// - `from()` is reflexive, which means that `From<T> for T` is implemented
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")]
161 ////////////////////////////////////////////////////////////////////////////////
163 ////////////////////////////////////////////////////////////////////////////////
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)
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)
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()
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
{
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()
206 #[stable(feature = "rust1", since = "1.0.0")]
207 impl<T
, U
> Into
<U
> for T
where U
: From
<T
> {
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 }
219 ////////////////////////////////////////////////////////////////////////////////
221 ////////////////////////////////////////////////////////////////////////////////
223 #[stable(feature = "rust1", since = "1.0.0")]
224 impl<T
> AsRef
<[T
]> for [T
] {
225 fn as_ref(&self) -> &[T
] {
230 #[stable(feature = "rust1", since = "1.0.0")]
231 impl<T
> AsMut
<[T
]> for [T
] {
232 fn as_mut(&mut self) -> &mut [T
] {
237 #[stable(feature = "rust1", since = "1.0.0")]
238 impl AsRef
<str> for str {
240 fn as_ref(&self) -> &str {