]> git.lizzy.rs Git - rust.git/blob - src/libcore/convert.rs
21f9b1f5513aaaf7f7c8d5184616c3f3552371b8
[rust.git] / 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.
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 //!
13 //! The traits in this module provide a general way to talk about
14 //! conversions from one type to another. They follow the standard
15 //! Rust conventions of `as`/`to`/`into`/`from`.
16
17 #![unstable(feature = "convert",
18             reason = "recently added, experimental traits")]
19
20 use marker::Sized;
21
22 /// A cheap, reference-to-reference conversion.
23 pub trait AsRef<T: ?Sized> {
24     /// Perform the conversion.
25     fn as_ref(&self) -> &T;
26 }
27
28 /// A cheap, mutable reference-to-mutable reference conversion.
29 pub trait AsMut<T: ?Sized> {
30     /// Perform the conversion.
31     fn as_mut(&mut self) -> &mut T;
32 }
33
34 /// A conversion that consumes `self`, which may or may not be
35 /// expensive.
36 pub trait Into<T>: Sized {
37     /// Perform the conversion.
38     fn into(self) -> T;
39 }
40
41 /// Construct `Self` via a conversion.
42 pub trait From<T> {
43     /// Perform the conversion.
44     fn from(T) -> Self;
45 }
46
47 ////////////////////////////////////////////////////////////////////////////////
48 // GENERIC IMPLS
49 ////////////////////////////////////////////////////////////////////////////////
50
51 // As implies Into
52 impl<'a, T: ?Sized, U: ?Sized> Into<&'a U> for &'a T where T: AsRef<U> {
53     fn into(self) -> &'a U {
54         self.as_ref()
55     }
56 }
57
58 // As lifts over &
59 impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a T where T: AsRef<U> {
60     fn as_ref(&self) -> &U {
61         <T as AsRef<U>>::as_ref(*self)
62     }
63 }
64
65 // As lifts over &mut
66 impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T where T: AsRef<U> {
67     fn as_ref(&self) -> &U {
68         <T as AsRef<U>>::as_ref(*self)
69     }
70 }
71
72 // FIXME (#23442): replace the above impls for &/&mut with the following more general one:
73 // // As lifts over Deref
74 // impl<D: ?Sized + Deref, U: ?Sized> AsRef<U> for D where D::Target: AsRef<U> {
75 //     fn as_ref(&self) -> &U {
76 //         self.deref().as_ref()
77 //     }
78 // }
79
80 // AsMut implies Into
81 impl<'a, T: ?Sized, U: ?Sized> Into<&'a mut U> for &'a mut T where T: AsMut<U> {
82     fn into(self) -> &'a mut U {
83         (*self).as_mut()
84     }
85 }
86
87 // AsMut lifts over &mut
88 impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T where T: AsMut<U> {
89     fn as_mut(&mut self) -> &mut U {
90         (*self).as_mut()
91     }
92 }
93
94 // FIXME (#23442): replace the above impl for &mut with the following more general one:
95 // // AsMut lifts over DerefMut
96 // impl<D: ?Sized + Deref, U: ?Sized> AsMut<U> for D where D::Target: AsMut<U> {
97 //     fn as_mut(&mut self) -> &mut U {
98 //         self.deref_mut().as_mut()
99 //     }
100 // }
101
102 // From implies Into
103 impl<T, U> Into<U> for T where U: From<T> {
104     fn into(self) -> U {
105         U::from(self)
106     }
107 }
108
109 ////////////////////////////////////////////////////////////////////////////////
110 // CONCRETE IMPLS
111 ////////////////////////////////////////////////////////////////////////////////
112
113 impl<T> AsRef<[T]> for [T] {
114     fn as_ref(&self) -> &[T] {
115         self
116     }
117 }
118
119 impl<T> AsMut<[T]> for [T] {
120     fn as_mut(&mut self) -> &mut [T] {
121         self
122     }
123 }
124
125 impl AsRef<str> for str {
126     fn as_ref(&self) -> &str {
127         self
128     }
129 }