// 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. //! //! - Implement the `As*` traits for reference-to-reference conversions //! - Implement the [`Into`] trait when you want to consume the value in the conversion //! - The [`From`] trait is the most flexible, useful for value _and_ reference conversions //! - The [`TryFrom`] and [`TryInto`] traits behave like [`From`] and [`Into`], but allow for the //! conversion to fail //! //! As a library author, you should prefer implementing [`From`][`From`] or //! [`TryFrom`][`TryFrom`] rather than [`Into`][`Into`] or [`TryInto`][`TryInto`], //! as [`From`] and [`TryFrom`] provide greater flexibility and offer //! equivalent [`Into`] or [`TryInto`] implementations for free, thanks to a blanket implementation //! in the standard library. //! //! # Generic Implementations //! //! - [`AsRef`] and [`AsMut`] auto-dereference if the inner type is a reference //! - [`From`]` for T` implies [`Into`]` for U` //! - [`TryFrom`]` for T` implies [`TryInto`]` for U` //! - [`From`] and [`Into`] are reflexive, which means that all types can `into()` //! themselves and `from()` themselves //! //! See each trait for usage examples. //! //! [`Into`]: trait.Into.html //! [`From`]: trait.From.html //! [`TryFrom`]: trait.TryFrom.html //! [`TryInto`]: trait.TryInto.html //! [`AsRef`]: trait.AsRef.html //! [`AsMut`]: trait.AsMut.html #![stable(feature = "rust1", since = "1.0.0")] use str::FromStr; /// A cheap reference-to-reference conversion. Used to convert a value to a reference value /// within generic code. /// /// `AsRef` is very similar to, but serves a slightly different purpose than, [`Borrow`]. /// /// `AsRef` is to be used when wishing to convert to a reference of another type. /// `Borrow` is more related to the notion of taking the reference. It is useful when wishing to abstract /// over the type of reference (`&T`, `&mut T`) or allow both the referenced and owned type to be treated in the same manner. /// The key difference between the two traits is the intention: /// /// - Use `AsRef` when goal is to simply convert into a reference /// - Use `Borrow` when goal is related to writing code that is agnostic to the type of borrow and if is reference or value /// /// See [the book][book] for a more detailed comparison. /// /// [book]: ../../book/borrow-and-asref.html /// [`Borrow`]: ../../std/borrow/trait.Borrow.html /// /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which /// returns an [`Option`] or a [`Result`]. /// /// [`Option`]: ../../std/option/enum.Option.html /// [`Result`]: ../../std/result/enum.Result.html /// /// # Generic Implementations /// /// - `AsRef` auto-dereferences if the inner type is a reference or a mutable /// reference (e.g.: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`) /// /// # Examples /// An example implementation of the trait is [`Path`]. /// /// [`Path`]: ../../std/struct.Path.html /// /// ``` /// impl AsRef for str { /// fn as_ref(&self) -> &Path { /// Path::new(self) /// } /// } /// ``` /// /// Both [`String`] and `&str` implement `AsRef`: /// /// [`String`]: ../../std/string/struct.String.html /// /// ``` /// 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. /// /// This trait is similar to `AsRef` but used for converting mutable references. /// /// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which /// returns an [`Option`] or a [`Result`]. /// /// [`Option`]: ../../std/option/enum.Option.html /// [`Result`]: ../../std/result/enum.Result.html /// /// # Generic Implementations /// /// - `AsMut` auto-dereferences if the inner type is a reference or a mutable /// reference (e.g.: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`) /// /// # Examples /// /// [`Box`] implements `AsMut`: /// /// [`Box`]: ../../std/boxed/struct.Box.html /// /// ``` /// fn add_one>(num: &mut T) { /// *num.as_mut() += 1; /// } /// /// let mut boxed_num = Box::new(0); /// add_one(&mut boxed_num); /// assert_eq!(*boxed_num, 1); /// ``` /// /// Implementing `AsMut`: /// /// ``` /// impl Type { /// let a = 1; /// } /// ``` /// #[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. The reciprocal of [`From`][From]. /// /// **Note: this trait must not fail**. If the conversion can fail, use [`TryInto`] or a dedicated /// method which returns an [`Option`] or a [`Result`]. /// /// Library authors should not directly implement this trait, but should prefer implementing /// the [`From`][From] trait, which offers greater flexibility and provides an equivalent `Into` /// implementation for free, thanks to a blanket implementation in the standard library. /// /// # Generic Implementations /// /// - [`From`][From]` for U` implies `Into for T` /// - [`into`] is reflexive, which means that `Into for T` is implemented /// /// # 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); /// ``` /// /// [`TryInto`]: trait.TryInto.html /// [`Option`]: ../../std/option/enum.Option.html /// [`Result`]: ../../std/result/enum.Result.html /// [`String`]: ../../std/string/struct.String.html /// [From]: trait.From.html /// [`into`]: trait.Into.html#tymethod.into #[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; } /// Simple and safe type conversions in to `Self`. It is the reciprocal of `Into`. /// /// This trait is useful when performing error handling as described by [the book][book] and is closely related to the `?` operator. /// /// When constructing a function that is capable of failing the return type will generally be of the form `Result`. /// The `From` trait allows for simplification of error handling by providing a means of returning a single error type that encapsulates /// numerous possible erroneous situations. /// This trait is not limited to error handling, rather the general case for this trait would be in any type conversions to have an /// explicit definition of how they are performed. /// /// **Note: this trait must not fail**. If the conversion can fail, use [`TryFrom`] or a dedicated /// method which returns an [`Option`] or a [`Result`]. /// /// # Generic Implementations /// /// - `From for U` implies [`Into`]` for T` /// - [`from`] is reflexive, which means that `From for T` is implemented /// /// # Examples /// /// [`String`] implements `From<&str>`: /// /// ``` /// let string = "hello".to_string(); /// let other_string = String::from("hello"); /// /// assert_eq!(string, other_string); /// ``` /// /// An example usage for error handling: /// /// ``` /// enum CliError { /// IoError(io::Error), /// ParseError(num::ParseIntError), /// } /// /// impl From for MyError { /// fn from(error: io::Error) -> Self { /// CliError::IoError(error) /// } /// } /// /// impl From for MyError { /// fn from(error: io::Error) -> Self { /// CliError::ParseError(error) /// } /// } /// /// fn open_and_parse_file(file_name: &str) -> Result { /// let file = std::fs::File::open("test")?; /// let mut contents = String::new(); /// file.read_to_string(&mut contents)?; /// let num: i32 = contents.trim().parse()?; /// } /// ``` /// /// [`TryFrom`]: trait.TryFrom.html /// [`Option`]: ../../std/option/enum.Option.html /// [`Result`]: ../../std/result/enum.Result.html /// [`String`]: ../../std/string/struct.String.html /// [`Into`]: trait.Into.html /// [`from`]: trait.From.html#tymethod.from /// [book]: ../../book/error-handling.html#the-from-trait #[stable(feature = "rust1", since = "1.0.0")] pub trait From: Sized { /// Performs the conversion. #[stable(feature = "rust1", since = "1.0.0")] fn from(T) -> Self; } /// An attempted conversion that consumes `self`, which may or may not be expensive. /// /// Library authors should not directly implement this trait, but should prefer implementing /// the [`TryFrom`] trait, which offers greater flexibility and provides an equivalent `TryInto` /// implementation for free, thanks to a blanket implementation in the standard library. /// /// [`TryFrom`]: trait.TryFrom.html #[unstable(feature = "try_from", issue = "33417")] pub trait TryInto: Sized { /// The type returned in the event of a conversion error. type Error; /// Performs the conversion. fn try_into(self) -> Result; } /// Attempt to construct `Self` via a conversion. #[unstable(feature = "try_from", issue = "33417")] pub trait TryFrom: Sized { /// The type returned in the event of a conversion error. type Error; /// Performs the conversion. fn try_from(value: T) -> Result; } //////////////////////////////////////////////////////////////////////////////// // 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 } } // TryFrom implies TryInto #[unstable(feature = "try_from", issue = "33417")] impl TryInto for T where U: TryFrom { type Error = U::Error; fn try_into(self) -> Result { U::try_from(self) } } //////////////////////////////////////////////////////////////////////////////// // 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 { #[inline] fn as_ref(&self) -> &str { self } } // FromStr implies TryFrom<&str> #[unstable(feature = "try_from", issue = "33417")] impl<'a, T> TryFrom<&'a str> for T where T: FromStr { type Error = ::Err; fn try_from(s: &'a str) -> Result { FromStr::from_str(s) } }