// Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. //! Traits for conversions between types. //! //! The traits in this module provide a general way to talk about //! conversions from one type to another. They follow the standard //! Rust conventions of `as`/`to`/`into`/`from`. #![unstable(feature = "convert", reason = "recently added, experimental traits")] use marker::Sized; /// A cheap, reference-to-reference conversion. pub trait AsRef { /// Perform the conversion. fn as_ref(&self) -> &T; } /// A cheap, mutable reference-to-mutable reference conversion. pub trait AsMut { /// Perform the conversion. fn as_mut(&mut self) -> &mut T; } /// A conversion that consumes `self`, which may or may not be /// expensive. pub trait Into: Sized { /// Perform the conversion. fn into(self) -> T; } /// Construct `Self` via a conversion. pub trait From { /// Perform the conversion. fn from(T) -> Self; } //////////////////////////////////////////////////////////////////////////////// // GENERIC IMPLS //////////////////////////////////////////////////////////////////////////////// // As implies Into impl<'a, T: ?Sized, U: ?Sized> Into<&'a U> for &'a T where T: AsRef { fn into(self) -> &'a U { self.as_ref() } } // As lifts over & impl<'a, T: ?Sized, U: ?Sized> AsRef for &'a T where T: AsRef { fn as_ref(&self) -> &U { >::as_ref(*self) } } // As lifts over &mut impl<'a, T: ?Sized, U: ?Sized> AsRef for &'a mut T where T: AsRef { fn as_ref(&self) -> &U { >::as_ref(*self) } } // FIXME (#23442): replace the above impls for &/&mut with the following more general one: // // As lifts over Deref // impl AsRef for D where D::Target: AsRef { // fn as_ref(&self) -> &U { // self.deref().as_ref() // } // } // AsMut implies Into impl<'a, T: ?Sized, U: ?Sized> Into<&'a mut U> for &'a mut T where T: AsMut { fn into(self) -> &'a mut U { (*self).as_mut() } } // AsMut lifts over &mut impl<'a, T: ?Sized, U: ?Sized> AsMut for &'a mut T where T: AsMut { fn as_mut(&mut self) -> &mut U { (*self).as_mut() } } // FIXME (#23442): replace the above impl for &mut with the following more general one: // // AsMut lifts over DerefMut // impl AsMut for D where D::Target: AsMut { // fn as_mut(&mut self) -> &mut U { // self.deref_mut().as_mut() // } // } // From itself is always itself impl From for T { fn from(t: T) -> T { t } } // From implies Into impl Into for T where U: From { fn into(self) -> U { U::from(self) } } //////////////////////////////////////////////////////////////////////////////// // CONCRETE IMPLS //////////////////////////////////////////////////////////////////////////////// impl AsRef<[T]> for [T] { fn as_ref(&self) -> &[T] { self } } impl AsMut<[T]> for [T] { fn as_mut(&mut self) -> &mut [T] { self } } impl AsRef for str { fn as_ref(&self) -> &str { self } }