diff options
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/convert.rs | 113 | ||||
| -rw-r--r-- | src/libcore/lib.rs | 1 | ||||
| -rw-r--r-- | src/libcore/option.rs | 17 | ||||
| -rw-r--r-- | src/libcore/prelude.rs | 1 | ||||
| -rw-r--r-- | src/libcore/result.rs | 21 | ||||
| -rw-r--r-- | src/libcore/slice.rs | 5 | ||||
| -rw-r--r-- | src/libcore/str/mod.rs | 4 |
7 files changed, 161 insertions, 1 deletions
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs new file mode 100644 index 00000000000..65a226d37cb --- /dev/null +++ b/src/libcore/convert.rs @@ -0,0 +1,113 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<T: ?Sized> { + /// Perform the conversion. + fn as_ref(&self) -> &T; +} + +/// A cheap, mutable reference-to-mutable reference conversion. +pub trait AsMut<T: ?Sized> { + /// 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<T>: Sized { + /// Perform the conversion. + fn into(self) -> T; +} + +/// Construct `Self` via a conversion. +pub trait From<T> { + /// 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<U> { + fn into(self) -> &'a U { + self.as_ref() + } +} + +// As lifts over & +impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a T where T: AsRef<U> { + fn as_ref(&self) -> &U { + <T as AsRef<U>>::as_ref(*self) + } +} + +// As lifts over &mut +impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T where T: AsRef<U> { + fn as_ref(&self) -> &U { + <T as AsRef<U>>::as_ref(*self) + } +} + +// AsMut implies Into +impl<'a, T: ?Sized, U: ?Sized> Into<&'a mut U> for &'a mut T where T: AsMut<U> { + fn into(self) -> &'a mut U { + (*self).as_mut() + } +} + +// AsMut lifts over &mut +impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T where T: AsMut<U> { + fn as_mut(&mut self) -> &mut U { + (*self).as_mut() + } +} + +// From implies Into +impl<T, U> Into<U> for T where U: From<T> { + fn into(self) -> U { + U::from(self) + } +} + +//////////////////////////////////////////////////////////////////////////////// +// CONCRETE IMPLS +//////////////////////////////////////////////////////////////////////////////// + +impl<T> AsRef<[T]> for [T] { + fn as_ref(&self) -> &[T] { + self + } +} + +impl<T> AsMut<[T]> for [T] { + fn as_mut(&mut self) -> &mut [T] { + self + } +} + +impl AsRef<str> for str { + fn as_ref(&self) -> &str { + self + } +} diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 29cc11d5a60..e31542c183a 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -125,6 +125,7 @@ pub mod ops; pub mod cmp; pub mod clone; pub mod default; +pub mod convert; /* Core types and methods on primitives */ diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 455c68d4319..4a1e24c1f40 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -154,6 +154,7 @@ use mem; use ops::{Deref, FnOnce}; use result::Result::{Ok, Err}; use result::Result; +#[allow(deprecated)] use slice::AsSlice; use slice; @@ -701,6 +702,19 @@ impl<T> Option<T> { pub fn take(&mut self) -> Option<T> { mem::replace(self, None) } + + /// Convert from `Option<T>` to `&[T]` (without copying) + #[inline] + #[unstable(feature = "as_slice", since = "unsure of the utility here")] + pub fn as_slice<'a>(&'a self) -> &'a [T] { + match *self { + Some(ref x) => slice::ref_slice(x), + None => { + let result: &[_] = &[]; + result + } + } + } } impl<'a, T: Clone, D: Deref<Target=T>> Option<D> { @@ -752,6 +766,9 @@ impl<T: Default> Option<T> { #[unstable(feature = "core", reason = "waiting on the stability of the trait itself")] +#[deprecated(since = "1.0.0", + reason = "use the inherent method instead")] +#[allow(deprecated)] impl<T> AsSlice<T> for Option<T> { /// Convert from `Option<T>` to `&[T]` (without copying) #[inline] diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 4bf7f85284c..424829939b9 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -36,6 +36,7 @@ pub use mem::drop; pub use char::CharExt; pub use clone::Clone; pub use cmp::{PartialEq, PartialOrd, Eq, Ord}; +pub use convert::{AsRef, AsMut, Into, From}; pub use iter::{Extend, IteratorExt}; pub use iter::{Iterator, DoubleEndedIterator}; pub use iter::{ExactSizeIterator}; diff --git a/src/libcore/result.rs b/src/libcore/result.rs index bc8d53e2a57..4b3cda46c1d 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -240,6 +240,7 @@ use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator, IntoIterator}; use ops::{FnMut, FnOnce}; use option::Option::{self, None, Some}; +#[allow(deprecated)] use slice::AsSlice; use slice; @@ -408,6 +409,20 @@ impl<T, E> Result<T, E> { } } + /// Convert from `Result<T, E>` to `&[T]` (without copying) + #[inline] + #[unstable(feature = "as_slice", since = "unsure of the utility here")] + pub fn as_slice(&self) -> &[T] { + match *self { + Ok(ref x) => slice::ref_slice(x), + Err(_) => { + // work around lack of implicit coercion from fixed-size array to slice + let emp: &[_] = &[]; + emp + } + } + } + /// Convert from `Result<T, E>` to `&mut [T]` (without copying) /// /// ``` @@ -788,10 +803,14 @@ impl<T: fmt::Debug, E> Result<T, E> { // Trait implementations ///////////////////////////////////////////////////////////////////////////// +#[unstable(feature = "core", + reason = "waiting on the stability of the trait itself")] +#[deprecated(since = "1.0.0", + reason = "use inherent method instead")] +#[allow(deprecated)] impl<T, E> AsSlice<T> for Result<T, E> { /// Convert from `Result<T, E>` to `&[T]` (without copying) #[inline] - #[stable(feature = "rust1", since = "1.0.0")] fn as_slice<'a>(&'a self) -> &'a [T] { match *self { Ok(ref x) => slice::ref_slice(x), diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 907b2eba80c..e7535ae1d17 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -596,24 +596,29 @@ impl<T> ops::IndexMut<RangeFull> for [T] { /// Data that is viewable as a slice. #[unstable(feature = "core", reason = "will be replaced by slice syntax")] +#[deprecated(since = "1.0.0", + reason = "use std::convert::AsRef<[T]> instead")] pub trait AsSlice<T> { /// Work with `self` as a slice. fn as_slice<'a>(&'a self) -> &'a [T]; } #[unstable(feature = "core", reason = "trait is experimental")] +#[allow(deprecated)] impl<T> AsSlice<T> for [T] { #[inline(always)] fn as_slice<'a>(&'a self) -> &'a [T] { self } } #[unstable(feature = "core", reason = "trait is experimental")] +#[allow(deprecated)] impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a U { #[inline(always)] fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) } } #[unstable(feature = "core", reason = "trait is experimental")] +#[allow(deprecated)] impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a mut U { #[inline(always)] fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) } diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 4734e9b7a9f..fe75b76dc11 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1364,16 +1364,20 @@ mod traits { reason = "Instead of taking this bound generically, this trait will be \ replaced with one of slicing syntax (&foo[..]), deref coercions, or \ a more generic conversion trait")] +#[deprecated(since = "1.0.0", + reason = "use std::convert::AsRef<str> instead")] pub trait Str { /// Work with `self` as a slice. fn as_slice<'a>(&'a self) -> &'a str; } +#[allow(deprecated)] impl Str for str { #[inline] fn as_slice<'a>(&'a self) -> &'a str { self } } +#[allow(deprecated)] impl<'a, S: ?Sized> Str for &'a S where S: Str { #[inline] fn as_slice(&self) -> &str { Str::as_slice(*self) } |
