summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-05-06 21:25:36 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-05-07 08:17:32 -0700
commit0d8f5fa618da00653897be2050980c800389be82 (patch)
treed88105c495c8df50a0226e06ea1179bac1126896 /src/libstd
parent4a974413dcce8a5a9f1df3d58503c63b8f5b556a (diff)
downloadrust-0d8f5fa618da00653897be2050980c800389be82.tar.gz
rust-0d8f5fa618da00653897be2050980c800389be82.zip
core: Move Option::expect to libstd from libcore
See #14008 for more details
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/io/timer.rs1
-rw-r--r--src/libstd/lib.rs3
-rw-r--r--src/libstd/option.rs167
-rw-r--r--src/libstd/prelude.rs1
-rw-r--r--src/libstd/rt/env.rs2
-rw-r--r--src/libstd/vec.rs2
6 files changed, 172 insertions, 4 deletions
diff --git a/src/libstd/io/timer.rs b/src/libstd/io/timer.rs
index 96c4083e7ed..5565918ef85 100644
--- a/src/libstd/io/timer.rs
+++ b/src/libstd/io/timer.rs
@@ -21,6 +21,7 @@ use comm::Receiver;
 use io::IoResult;
 use kinds::Send;
 use owned::Box;
+use option::Expect;
 use rt::rtio::{IoFactory, LocalIo, RtioTimer};
 
 /// A synchronous timer object
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 4a555035a08..abcc1f099b4 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -149,7 +149,6 @@ pub use core::default;
 pub use core::intrinsics;
 pub use core::iter;
 pub use core::mem;
-pub use core::option;
 pub use core::ptr;
 pub use core::raw;
 pub use core::tuple;
@@ -221,7 +220,7 @@ pub mod hash;
 /* Common data structures */
 
 pub mod result;
-
+pub mod option;
 
 /* Tasks and communication */
 
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
new file mode 100644
index 00000000000..17249f567e5
--- /dev/null
+++ b/src/libstd/option.rs
@@ -0,0 +1,167 @@
+// 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.
+
+//! Optional values
+//!
+//! Type `Option` represents an optional value: every `Option`
+//! is either `Some` and contains a value, or `None`, and
+//! does not. `Option` types are very common in Rust code, as
+//! they have a number of uses:
+//!
+//! * Initial values
+//! * Return values for functions that are not defined
+//!   over their entire input range (partial functions)
+//! * Return value for otherwise reporting simple errors, where `None` is
+//!   returned on error
+//! * Optional struct fields
+//! * Struct fields that can be loaned or "taken"
+//! * Optional function arguments
+//! * Nullable pointers
+//! * Swapping things out of difficult situations
+//!
+//! Options are commonly paired with pattern matching to query the presence
+//! of a value and take action, always accounting for the `None` case.
+//!
+//! ```
+//! # // FIXME This is not the greatest first example
+//! // cow_says contains the word "moo"
+//! let cow_says = Some("moo");
+//! // dog_says does not contain a value
+//! let dog_says: Option<&str> = None;
+//!
+//! // Pattern match to retrieve the value
+//! match (cow_says, dog_says) {
+//!     (Some(cow_words), Some(dog_words)) => {
+//!         println!("Cow says {} and dog says {}!", cow_words, dog_words);
+//!     }
+//!     (Some(cow_words), None) => println!("Cow says {}", cow_words),
+//!     (None, Some(dog_words)) => println!("Dog says {}", dog_words),
+//!     (None, None) => println!("Cow and dog are suspiciously silent")
+//! }
+//! ```
+//!
+//
+// FIXME: Show how `Option` is used in practice, with lots of methods
+//
+//! # Options and pointers ("nullable" pointers)
+//!
+//! Rust's pointer types must always point to a valid location; there are
+//! no "null" pointers. Instead, Rust has *optional* pointers, like
+//! the optional owned box, `Option<~T>`.
+//!
+//! The following example uses `Option` to create an optional box of
+//! `int`. Notice that in order to use the inner `int` value first the
+//! `check_optional` function needs to use pattern matching to
+//! determine whether the box has a value (i.e. it is `Some(...)`) or
+//! not (`None`).
+//!
+//! ```
+//! let optional: Option<~int> = None;
+//! check_optional(&optional);
+//!
+//! let optional: Option<~int> = Some(~9000);
+//! check_optional(&optional);
+//!
+//! fn check_optional(optional: &Option<~int>) {
+//!     match *optional {
+//!         Some(ref p) => println!("have value {}", p),
+//!         None => println!("have no value")
+//!     }
+//! }
+//! ```
+//!
+//! This usage of `Option` to create safe nullable pointers is so
+//! common that Rust does special optimizations to make the
+//! representation of `Option<~T>` a single pointer. Optional pointers
+//! in Rust are stored as efficiently as any other pointer type.
+//!
+//! # Examples
+//!
+//! Basic pattern matching on `Option`:
+//!
+//! ```
+//! let msg = Some("howdy");
+//!
+//! // Take a reference to the contained string
+//! match msg {
+//!     Some(ref m) => println!("{}", *m),
+//!     None => ()
+//! }
+//!
+//! // Remove the contained string, destroying the Option
+//! let unwrapped_msg = match msg {
+//!     Some(m) => m,
+//!     None => "default message"
+//! };
+//! ```
+//!
+//! Initialize a result to `None` before a loop:
+//!
+//! ```
+//! enum Kingdom { Plant(uint, &'static str), Animal(uint, &'static str) }
+//!
+//! // A list of data to search through.
+//! let all_the_big_things = [
+//!     Plant(250, "redwood"),
+//!     Plant(230, "noble fir"),
+//!     Plant(229, "sugar pine"),
+//!     Animal(25, "blue whale"),
+//!     Animal(19, "fin whale"),
+//!     Animal(15, "north pacific right whale"),
+//! ];
+//!
+//! // We're going to search for the name of the biggest animal,
+//! // but to start with we've just got `None`.
+//! let mut name_of_biggest_animal = None;
+//! let mut size_of_biggest_animal = 0;
+//! for big_thing in all_the_big_things.iter() {
+//!     match *big_thing {
+//!         Animal(size, name) if size > size_of_biggest_animal => {
+//!             // Now we've found the name of some big animal
+//!             size_of_biggest_animal = size;
+//!             name_of_biggest_animal = Some(name);
+//!         }
+//!         Animal(..) | Plant(..) => ()
+//!     }
+//! }
+//!
+//! match name_of_biggest_animal {
+//!     Some(name) => println!("the biggest animal is {}", name),
+//!     None => println!("there are no animals :(")
+//! }
+//! ```
+
+use any::Any;
+use kinds::Send;
+
+pub use core::option::{Option, Some, None, Item, collect};
+
+/// Extension trait for the `Option` type to add an `expect` method
+
+// FIXME(#14008) should this trait even exist?
+pub trait Expect<T> {
+    /// Unwraps an option, yielding the content of a `Some`
+    ///
+    /// # Failure
+    ///
+    /// Fails if the value is a `None` with a custom failure message provided by
+    /// `msg`.
+    fn expect<M: Any + Send>(self, m: M) -> T;
+}
+
+impl<T> Expect<T> for Option<T> {
+    #[inline]
+    fn expect<M: Any + Send>(self, msg: M) -> T {
+        match self {
+            Some(val) => val,
+            None => fail!(msg),
+        }
+    }
+}
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index 75eb56ffa52..6cd9e96496f 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -65,6 +65,7 @@ pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize};
 pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
 pub use num::{Signed, Unsigned};
 pub use num::{Primitive, Int, Float, ToPrimitive, FromPrimitive};
+pub use option::Expect;
 pub use owned::Box;
 pub use path::{GenericPath, Path, PosixPath, WindowsPath};
 pub use ptr::RawPtr;
diff --git a/src/libstd/rt/env.rs b/src/libstd/rt/env.rs
index 94f56d42613..708c42030ab 100644
--- a/src/libstd/rt/env.rs
+++ b/src/libstd/rt/env.rs
@@ -11,7 +11,7 @@
 //! Runtime environment settings
 
 use from_str::from_str;
-use option::{Some, None};
+use option::{Some, None, Expect};
 use os;
 
 // Note that these are all accessed without any synchronization.
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 35eb5359311..af146b96e50 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -23,7 +23,7 @@ use mem;
 use num;
 use num::{CheckedMul, CheckedAdd};
 use ops::Drop;
-use option::{None, Option, Some};
+use option::{None, Option, Some, Expect};
 use ptr::RawPtr;
 use ptr;
 use rt::global_heap::{malloc_raw, realloc_raw};