]>
Commit | Line | Data |
---|---|---|
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 | ||
24 | use 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")] |
49 | pub 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")] | |
57 | pub 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")] |
79 | pub 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")] |
98 | pub 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")] | |
110 | impl<'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")] | |
118 | impl<'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")] | |
134 | impl<'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")] | |
150 | impl<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")] | |
158 | impl<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")] | |
167 | impl<T> AsRef<[T]> for [T] { | |
168 | fn as_ref(&self) -> &[T] { | |
169 | self | |
170 | } | |
171 | } | |
172 | ||
173 | #[stable(feature = "rust1", since = "1.0.0")] | |
174 | impl<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")] | |
181 | impl AsRef<str> for str { | |
d9579d0f | 182 | #[inline] |
c34b1796 AL |
183 | fn as_ref(&self) -> &str { |
184 | self | |
185 | } | |
186 | } |