//! 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")] /// An identity function. /// /// Two things are important to note about this function: /// /// - It is not always equivalent to a closure like `|x| x` since the /// closure may coerce `x` into a different type. /// /// - It moves the input `x` passed to the function. /// /// While it might seem strange to have a function that just returns back the /// input, there are some interesting uses. /// /// # Examples /// /// Using `identity` to do nothing among other interesting functions: /// /// ```rust /// use std::convert::identity; /// /// fn manipulation(x: u32) -> u32 { /// // Let's assume that this function does something interesting. /// x + 1 /// } /// /// let _arr = &[identity, manipulation]; /// ``` /// /// Using `identity` to get a function that changes nothing in a conditional: /// /// ```rust /// use std::convert::identity; /// /// # let condition = true; /// /// # fn manipulation(x: u32) -> u32 { x + 1 } /// /// let do_stuff = if condition { manipulation } else { identity }; /// /// // do more interesting stuff.. /// /// let _results = do_stuff(42); /// ``` /// /// Using `identity` to keep the `Some` variants of an iterator of `Option`: /// /// ```rust /// use std::convert::identity; /// /// let iter = vec![Some(1), None, Some(3)].into_iter(); /// let filtered = iter.filter_map(identity).collect::>(); /// assert_eq!(vec![1, 3], filtered); /// ``` #[stable(feature = "convert_id", since = "1.33.0")] #[inline] pub const fn identity(x: T) -> T { x } /// 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 the goal is to simply convert into a reference /// - Use `Borrow` when the goal is related to writing code that is agnostic to /// the type of borrow and whether it is a reference or value /// /// See [the book][book] for a more detailed comparison. /// /// [book]: ../../book/first-edition/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 /// /// 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 between 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 mutable reference /// (e.g.: `foo.as_mut()` will work the same if `foo` has type `&mut Foo` /// or `&mut &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); /// ``` /// /// #[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 /// /// # Implementing `Into` /// /// There is one exception to implementing `Into`, and it's kind of esoteric. /// If the destination type is not part of the current crate, and it uses a /// generic variable, then you can't implement `From` directly. For example, /// take this crate: /// /// ```compile_fail /// struct Wrapper(Vec); /// impl From> for Vec { /// fn from(w: Wrapper) -> Vec { /// w.0 /// } /// } /// ``` /// /// To fix this, you can implement `Into` directly: /// /// ``` /// struct Wrapper(Vec); /// impl Into> for Wrapper { /// fn into(self) -> Vec { /// self.0 /// } /// } /// ``` /// /// This won't always allow the conversion: for example, `try!` and `?` /// always use `From`. However, in most cases, people use `Into` to do the /// conversions, and this will allow that. /// /// In almost all cases, you should try to implement `From`, then fall back /// to `Into` if `From` can't be 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: /// /// ``` /// use std::fs; /// use std::io; /// use std::num; /// /// enum CliError { /// IoError(io::Error), /// ParseError(num::ParseIntError), /// } /// /// impl From for CliError { /// fn from(error: io::Error) -> Self { /// CliError::IoError(error) /// } /// } /// /// impl From for CliError { /// fn from(error: num::ParseIntError) -> Self { /// CliError::ParseError(error) /// } /// } /// /// fn open_and_parse_file(file_name: &str) -> Result { /// let mut contents = fs::read_to_string(&file_name)?; /// let num: i32 = contents.trim().parse()?; /// Ok(num) /// } /// ``` /// /// [`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/first-edition/error-handling.html #[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. For more information on this, /// see the documentation for [`Into`]. /// /// [`TryFrom`]: trait.TryFrom.html /// [`Into`]: trait.Into.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 AsRef for &T where T: AsRef { fn as_ref(&self) -> &U { >::as_ref(*self) } } // As lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] impl AsRef for &mut T where T: AsRef { fn as_ref(&self) -> &U { >::as_ref(*self) } } // FIXME (#45742): 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 AsMut for &mut T where T: AsMut { fn as_mut(&mut self) -> &mut U { (*self).as_mut() } } // FIXME (#45742): 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) } } // Infallible conversions are semantically equivalent to fallible conversions // with an uninhabited error type. #[unstable(feature = "try_from", issue = "33417")] impl TryFrom for T where U: Into { type Error = !; fn try_from(value: U) -> Result { Ok(U::into(value)) } } //////////////////////////////////////////////////////////////////////////////// // 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 } }