Skip to content

Commit

Permalink
rollup merge of rust-lang#21718: alexcrichton/stabilize-from-str
Browse files Browse the repository at this point in the history
This commits adds an associated type to the `FromStr` trait representing an
error payload for parses which do not succeed. The previous return value,
`Option<Self>` did not allow for this form of payload. After the associated type
was added, the following attributes were applied:

* `FromStr` is now stable
* `FromStr::Err` is now stable
* `FromStr::from_str` is now stable
* `StrExt::parse` is now stable
* `FromStr for bool` is now stable
* `FromStr for $float` is now stable
* `FromStr for $integral` is now stable
* Errors returned from stable `FromStr` implementations are stable
* Errors implement `Display` and `Error` (both impl blocks being `#[stable]`)

Closes rust-lang#15138
  • Loading branch information
alexcrichton committed Jan 30, 2015
2 parents 0ba812f + 0cdde6e commit ac1a03d
Show file tree
Hide file tree
Showing 39 changed files with 392 additions and 263 deletions.
21 changes: 11 additions & 10 deletions src/compiletest/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,18 @@ pub enum Mode {
}

impl FromStr for Mode {
fn from_str(s: &str) -> Option<Mode> {
type Err = ();
fn from_str(s: &str) -> Result<Mode, ()> {
match s {
"compile-fail" => Some(CompileFail),
"run-fail" => Some(RunFail),
"run-pass" => Some(RunPass),
"run-pass-valgrind" => Some(RunPassValgrind),
"pretty" => Some(Pretty),
"debuginfo-lldb" => Some(DebugInfoLldb),
"debuginfo-gdb" => Some(DebugInfoGdb),
"codegen" => Some(Codegen),
_ => None,
"compile-fail" => Ok(CompileFail),
"run-fail" => Ok(RunFail),
"run-pass" => Ok(RunPass),
"run-pass-valgrind" => Ok(RunPassValgrind),
"pretty" => Ok(Pretty),
"debuginfo-lldb" => Ok(DebugInfoLldb),
"debuginfo-gdb" => Ok(DebugInfoGdb),
"codegen" => Ok(Codegen),
_ => Err(()),
}
}
}
Expand Down
5 changes: 1 addition & 4 deletions src/compiletest/compiletest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ extern crate log;
use std::os;
use std::old_io;
use std::old_io::fs;
use std::str::FromStr;
use std::thunk::Thunk;
use getopts::{optopt, optflag, reqopt};
use common::Config;
Expand Down Expand Up @@ -140,9 +139,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
build_base: opt_path(matches, "build-base"),
aux_base: opt_path(matches, "aux-base"),
stage_id: matches.opt_str("stage-id").unwrap(),
mode: FromStr::from_str(matches.opt_str("mode")
.unwrap()
.as_slice()).expect("invalid mode"),
mode: matches.opt_str("mode").unwrap().parse().ok().expect("invalid mode"),
run_ignored: matches.opt_present("ignored"),
filter: filter,
logfile: matches.opt_str("logfile").map(|s| Path::new(s)),
Expand Down
6 changes: 3 additions & 3 deletions src/compiletest/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,8 @@ pub fn gdb_version_to_int(version_string: &str) -> int {
panic!("{}", error_string);
}

let major: int = components[0].parse().expect(error_string);
let minor: int = components[1].parse().expect(error_string);
let major: int = components[0].parse().ok().expect(error_string);
let minor: int = components[1].parse().ok().expect(error_string);

return major * 1000 + minor;
}
Expand All @@ -363,6 +363,6 @@ pub fn lldb_version_to_int(version_string: &str) -> int {
"Encountered LLDB version string with unexpected format: {}",
version_string);
let error_string = error_string.as_slice();
let major: int = version_string.parse().expect(error_string);
let major: int = version_string.parse().ok().expect(error_string);
return major;
}
2 changes: 1 addition & 1 deletion src/doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2994,7 +2994,7 @@ Some examples of call expressions:
# fn add(x: i32, y: i32) -> i32 { 0 }
let x: i32 = add(1i32, 2i32);
let pi: Option<f32> = "3.14".parse();
let pi: Option<f32> = "3.14".parse().ok();
```

### Lambda expressions
Expand Down
24 changes: 13 additions & 11 deletions src/doc/trpl/guessing-game.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ a function for that:
let input = old_io::stdin().read_line()
.ok()
.expect("Failed to read line");
let input_num: Option<u32> = input.parse();
let input_num: Option<u32> = input.parse().ok();
```
The `parse` function takes in a `&str` value and converts it into something.
Expand All @@ -422,11 +422,13 @@ In this case, we say `x` is a `u32` explicitly, so Rust is able to properly
tell `random()` what to generate. In a similar fashion, both of these work:
```{rust,ignore}
let input_num = "5".parse::<u32>(); // input_num: Option<u32>
let input_num: Option<u32> = "5".parse(); // input_num: Option<u32>
let input_num = "5".parse::<u32>().ok(); // input_num: Option<u32>
let input_num: Option<u32> = "5".parse().ok(); // input_num: Option<u32>
```
Anyway, with us now converting our input to a number, our code looks like this:
Here we're converting the `Result` returned by `parse` to an `Option` by using
the `ok` method as well. Anyway, with us now converting our input to a number,
our code looks like this:
```{rust,ignore}
use std::old_io;
Expand All @@ -445,7 +447,7 @@ fn main() {
let input = old_io::stdin().read_line()
.ok()
.expect("Failed to read line");
let input_num: Option<u32> = input.parse();
let input_num: Option<u32> = input.parse().ok();
println!("You guessed: {}", input_num);
Expand Down Expand Up @@ -495,7 +497,7 @@ fn main() {
let input = old_io::stdin().read_line()
.ok()
.expect("Failed to read line");
let input_num: Option<u32> = input.parse();
let input_num: Option<u32> = input.parse().ok();

let num = match input_num {
Some(num) => num,
Expand Down Expand Up @@ -562,7 +564,7 @@ fn main() {
let input = old_io::stdin().read_line()
.ok()
.expect("Failed to read line");
let input_num: Option<u32> = input.trim().parse();
let input_num: Option<u32> = input.trim().parse().ok();

let num = match input_num {
Some(num) => num,
Expand Down Expand Up @@ -638,7 +640,7 @@ fn main() {
let input = old_io::stdin().read_line()
.ok()
.expect("Failed to read line");
let input_num: Option<u32> = input.trim().parse();
let input_num: Option<u32> = input.trim().parse().ok();
let num = match input_num {
Some(num) => num,
Expand Down Expand Up @@ -714,7 +716,7 @@ fn main() {
let input = old_io::stdin().read_line()
.ok()
.expect("Failed to read line");
let input_num: Option<u32> = input.trim().parse();
let input_num: Option<u32> = input.trim().parse().ok();

let num = match input_num {
Some(num) => num,
Expand Down Expand Up @@ -770,7 +772,7 @@ fn main() {
let input = old_io::stdin().read_line()
.ok()
.expect("Failed to read line");
let input_num: Option<u32> = input.trim().parse();
let input_num: Option<u32> = input.trim().parse().ok();

let num = match input_num {
Some(num) => num,
Expand Down Expand Up @@ -847,7 +849,7 @@ fn main() {
let input = old_io::stdin().read_line()
.ok()
.expect("Failed to read line");
let input_num: Option<u32> = input.trim().parse();
let input_num: Option<u32> = input.trim().parse().ok();

let num = match input_num {
Some(num) => num,
Expand Down
10 changes: 5 additions & 5 deletions src/libcollections/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ use core::ops::FullRange;
#[cfg(not(stage0))]
use core::ops::RangeFull;
use core::option::Option::{self, Some, None};
use core::result::Result;
use core::slice::AsSlice;
use core::str as core_str;
use unicode::str::{UnicodeStr, Utf16Encoder};
Expand Down Expand Up @@ -1231,13 +1232,12 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// # Example
///
/// ```
/// assert_eq!("4".parse::<u32>(), Some(4));
/// assert_eq!("j".parse::<u32>(), None);
/// assert_eq!("4".parse::<u32>(), Ok(4));
/// assert!("j".parse::<u32>().is_err());
/// ```
#[inline]
#[unstable(feature = "collections",
reason = "this method was just created")]
fn parse<F: FromStr>(&self) -> Option<F> {
#[stable(feature = "rust1", since = "1.0.0")]
fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
core_str::StrExt::parse(&self[])
}

Expand Down
8 changes: 5 additions & 3 deletions src/libcollections/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -940,10 +940,12 @@ pub fn as_string<'a>(x: &'a str) -> DerefString<'a> {
DerefString { x: as_vec(x.as_bytes()) }
}

#[unstable(feature = "collections", reason = "associated error type may change")]
impl FromStr for String {
type Err = ();
#[inline]
fn from_str(s: &str) -> Option<String> {
Some(String::from_str(s))
fn from_str(s: &str) -> Result<String, ()> {
Ok(String::from_str(s))
}
}

Expand Down Expand Up @@ -1016,7 +1018,7 @@ mod tests {

#[test]
fn test_from_str() {
let owned: Option<::std::string::String> = "string".parse();
let owned: Option<::std::string::String> = "string".parse().ok();
assert_eq!(owned.as_ref().map(|s| s.as_slice()), Some("string"));
}

Expand Down
Loading

0 comments on commit ac1a03d

Please sign in to comment.