// 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`/`into`/`from`. //! //! Like many traits, these are often used as bounds for generic functions, to support arguments of //! multiple types. //! //! See each trait for usage examples. #![stable(feature = "rust1", since = "1.0.0")] use marker::Sized; /// A cheap, reference-to-reference conversion. /// /// # Examples /// /// Both `String` and `&str` implement `AsRef`: /// /// ``` /// fn is_hello>(s: T) { /// assert_eq!("hello", s.as_ref()); /// } /// /// let s = "hello"; /// is_hello(s); /// /// let s = "hello".to_string(); /// is_hello(s); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait AsRef { /// Performs the conversion. #[stable(feature = "rust1", since = "1.0.0")] fn as_ref(&self) -> &T; } /// A cheap, mutable reference-to-mutable reference conversion. #[stable(feature = "rust1", since = "1.0.0")] pub trait AsMut { /// Performs the conversion. #[stable(feature = "rust1", since = "1.0.0")] fn as_mut(&mut self) -> &mut T; } /// A conversion that consumes `self`, which may or may not be expensive. /// /// # Examples /// /// `String` implements `Into>`: /// /// ``` /// fn is_hello>>(s: T) { /// let bytes = b"hello".to_vec(); /// assert_eq!(bytes, s.into()); /// } /// /// let s = "hello".to_string(); /// is_hello(s); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait Into: Sized { /// Performs the conversion. #[stable(feature = "rust1", since = "1.0.0")] fn into(self) -> T; } /// Construct `Self` via a conversion. /// /// # Examples /// /// `String` implements `From<&str>`: /// /// ``` /// let string = "hello".to_string(); /// let other_string = String::from("hello"); /// /// assert_eq!(string, other_string); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait From { /// Performs the conversion. #[stable(feature = "rust1", since = "1.0.0")] fn from(T) -> Self; } //////////////////////////////////////////////////////////////////////////////// // GENERIC IMPLS //////////////////////////////////////////////////////////////////////////////// // As lifts over & #[stable(feature = "rust1", since = "1.0.0")] 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 #[stable(feature = "rust1", since = "1.0.0")] 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 lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] 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 implies Into #[stable(feature = "rust1", since = "1.0.0")] impl Into for T where U: From { fn into(self) -> U { U::from(self) } } // From (and thus Into) is reflexive #[stable(feature = "rust1", since = "1.0.0")] impl From for T { fn from(t: T) -> T { t } } //////////////////////////////////////////////////////////////////////////////// // CONCRETE IMPLS //////////////////////////////////////////////////////////////////////////////// #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<[T]> for [T] { fn as_ref(&self) -> &[T] { self } } #[stable(feature = "rust1", since = "1.0.0")] impl AsMut<[T]> for [T] { fn as_mut(&mut self) -> &mut [T] { self } } #[stable(feature = "rust1", since = "1.0.0")] impl AsRef for str { fn as_ref(&self) -> &str { self } }