summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--exercises/advanced_errors/advanced_errs1.rs98
-rw-r--r--exercises/advanced_errors/advanced_errs2.rs202
-rw-r--r--info.toml52
3 files changed, 0 insertions, 352 deletions
diff --git a/exercises/advanced_errors/advanced_errs1.rs b/exercises/advanced_errors/advanced_errs1.rs
deleted file mode 100644
index 4bc7b63..0000000
--- a/exercises/advanced_errors/advanced_errs1.rs
+++ /dev/null
@@ -1,98 +0,0 @@
-// advanced_errs1.rs
-
-// Remember back in errors6, we had multiple mapping functions so that we
-// could translate lower-level errors into our custom error type using
-// `map_err()`? What if we could use the `?` operator directly instead?
-
-// Make this code compile! Execute `rustlings hint advanced_errs1` for
-// hints :)
-
-// I AM NOT DONE
-
-use std::num::ParseIntError;
-use std::str::FromStr;
-
-// This is a custom error type that we will be using in the `FromStr`
-// implementation.
-#[derive(PartialEq, Debug)]
-enum ParsePosNonzeroError {
- Creation(CreationError),
- ParseInt(ParseIntError),
-}
-
-impl From<CreationError> for ParsePosNonzeroError {
- fn from(e: CreationError) -> Self {
- // TODO: complete this implementation so that the `?` operator will
- // work for `CreationError`
- }
-}
-
-// TODO: implement another instance of the `From` trait here so that the
-// `?` operator will work in the other place in the `FromStr`
-// implementation below.
-
-// Don't change anything below this line.
-
-impl FromStr for PositiveNonzeroInteger {
- type Err = ParsePosNonzeroError;
- fn from_str(s: &str) -> Result<PositiveNonzeroInteger, Self::Err> {
- let x: i64 = s.parse()?;
- Ok(PositiveNonzeroInteger::new(x)?)
- }
-}
-
-#[derive(PartialEq, Debug)]
-struct PositiveNonzeroInteger(u64);
-
-#[derive(PartialEq, Debug)]
-enum CreationError {
- Negative,
- Zero,
-}
-
-impl PositiveNonzeroInteger {
- fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
- match value {
- x if x < 0 => Err(CreationError::Negative),
- x if x == 0 => Err(CreationError::Zero),
- x => Ok(PositiveNonzeroInteger(x as u64)),
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
-
- #[test]
- fn test_parse_error() {
- // We can't construct a ParseIntError, so we have to pattern match.
- assert!(matches!(
- PositiveNonzeroInteger::from_str("not a number"),
- Err(ParsePosNonzeroError::ParseInt(_))
- ));
- }
-
- #[test]
- fn test_negative() {
- assert_eq!(
- PositiveNonzeroInteger::from_str("-555"),
- Err(ParsePosNonzeroError::Creation(CreationError::Negative))
- );
- }
-
- #[test]
- fn test_zero() {
- assert_eq!(
- PositiveNonzeroInteger::from_str("0"),
- Err(ParsePosNonzeroError::Creation(CreationError::Zero))
- );
- }
-
- #[test]
- fn test_positive() {
- let x = PositiveNonzeroInteger::new(42);
- assert!(x.is_ok());
- assert_eq!(PositiveNonzeroInteger::from_str("42"), Ok(x.unwrap()));
- }
-}
diff --git a/exercises/advanced_errors/advanced_errs2.rs b/exercises/advanced_errors/advanced_errs2.rs
deleted file mode 100644
index 54e669f..0000000
--- a/exercises/advanced_errors/advanced_errs2.rs
+++ /dev/null
@@ -1,202 +0,0 @@
-// advanced_errs2.rs
-
-// This exercise demonstrates a few traits that are useful for custom error
-// types to implement, especially so that other code can consume the custom
-// error type more usefully.
-
-// Make this compile, and make the tests pass!
-// Execute `rustlings hint advanced_errs2` for hints.
-
-// Steps:
-// 1. Implement a missing trait so that `main()` will compile.
-// 2. Complete the partial implementation of `From` for
-// `ParseClimateError`.
-// 3. Handle the missing error cases in the `FromStr` implementation for
-// `Climate`.
-// 4. Complete the partial implementation of `Display` for
-// `ParseClimateError`.
-
-// I AM NOT DONE
-
-use std::error::Error;
-use std::fmt::{self, Display, Formatter};
-use std::num::{ParseFloatError, ParseIntError};
-use std::str::FromStr;
-
-// This is the custom error type that we will be using for the parser for
-// `Climate`.
-#[derive(Debug, PartialEq)]
-enum ParseClimateError {
- Empty,
- BadLen,
- NoCity,
- ParseInt(ParseIntError),
- ParseFloat(ParseFloatError),
-}
-
-// This `From` implementation allows the `?` operator to work on
-// `ParseIntError` values.
-impl From<ParseIntError> for ParseClimateError {
- fn from(e: ParseIntError) -> Self {
- Self::ParseInt(e)
- }
-}
-
-// This `From` implementation allows the `?` operator to work on
-// `ParseFloatError` values.
-impl From<ParseFloatError> for ParseClimateError {
- fn from(e: ParseFloatError) -> Self {
- // TODO: Complete this function
- }
-}
-
-// TODO: Implement a missing trait so that `main()` below will compile. It
-// is not necessary to implement any methods inside the missing trait.
-
-// The `Display` trait allows for other code to obtain the error formatted
-// as a user-visible string.
-impl Display for ParseClimateError {
- // TODO: Complete this function so that it produces the correct strings
- // for each error variant.
- fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
- // Imports the variants to make the following code more compact.
- use ParseClimateError::*;
- match self {
- NoCity => write!(f, "no city name"),
- ParseFloat(e) => write!(f, "error parsing temperature: {}", e),
- }
- }
-}
-
-#[derive(Debug, PartialEq)]
-struct Climate {
- city: String,
- year: u32,
- temp: f32,
-}
-
-// Parser for `Climate`.
-// 1. Split the input string into 3 fields: city, year, temp.
-// 2. Return an error if the string is empty or has the wrong number of
-// fields.
-// 3. Return an error if the city name is empty.
-// 4. Parse the year as a `u32` and return an error if that fails.
-// 5. Parse the temp as a `f32` and return an error if that fails.
-// 6. Return an `Ok` value containing the completed `Climate` value.
-impl FromStr for Climate {
- type Err = ParseClimateError;
- // TODO: Complete this function by making it handle the missing error
- // cases.
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- let v: Vec<_> = s.split(',').collect();
- let (city, year, temp) = match &v[..] {
- [city, year, temp] => (city.to_string(), year, temp),
- _ => return Err(ParseClimateError::BadLen),
- };
- let year: u32 = year.parse()?;
- let temp: f32 = temp.parse()?;
- Ok(Climate { city, year, temp })
- }
-}
-
-// Don't change anything below this line (other than to enable ignored
-// tests).
-
-fn main() -> Result<(), Box<dyn Error>> {
- println!("{:?}", "Hong Kong,1999,25.7".parse::<Climate>()?);
- println!("{:?}", "".parse::<Climate>()?);
- Ok(())
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- #[test]
- fn test_empty() {
- let res = "".parse::<Climate>();
- assert_eq!(res, Err(ParseClimateError::Empty));
- assert_eq!(res.unwrap_err().to_string(), "empty input");
- }
- #[test]
- fn test_short() {
- let res = "Boston,1991".parse::<Climate>();
- assert_eq!(res, Err(ParseClimateError::BadLen));
- assert_eq!(res.unwrap_err().to_string(), "incorrect number of fields");
- }
- #[test]
- fn test_long() {
- let res = "Paris,1920,17.2,extra".parse::<Climate>();
- assert_eq!(res, Err(ParseClimateError::BadLen));
- assert_eq!(res.unwrap_err().to_string(), "incorrect number of fields");
- }
- #[test]
- fn test_no_city() {
- let res = ",1997,20.5".parse::<Climate>();
- assert_eq!(res, Err(ParseClimateError::NoCity));
- assert_eq!(res.unwrap_err().to_string(), "no city name");
- }
- #[test]
- fn test_parse_int_neg() {
- let res = "Barcelona,-25,22.3".parse::<Climate>();
- assert!(matches!(res, Err(ParseClimateError::ParseInt(_))));
- let err = res.unwrap_err();
- if let ParseClimateError::ParseInt(ref inner) = err {
- assert_eq!(
- err.to_string(),
- format!("error parsing year: {}", inner.to_string())
- );
- } else {
- unreachable!();
- };
- }
- #[test]
- fn test_parse_int_bad() {
- let res = "Beijing,foo,15.0".parse::<Climate>();
- assert!(matches!(res, Err(ParseClimateError::ParseInt(_))));
- let err = res.unwrap_err();
- if let ParseClimateError::ParseInt(ref inner) = err {
- assert_eq!(
- err.to_string(),
- format!("error parsing year: {}", inner.to_string())
- );
- } else {
- unreachable!();
- };
- }
- #[test]
- fn test_parse_float() {
- let res = "Manila,2001,bar".parse::<Climate>();
- assert!(matches!(res, Err(ParseClimateError::ParseFloat(_))));
- let err = res.unwrap_err();
- if let ParseClimateError::ParseFloat(ref inner) = err {
- assert_eq!(
- err.to_string(),
- format!("error parsing temperature: {}", inner.to_string())
- );
- } else {
- unreachable!();
- };
- }
- #[test]
- fn test_parse_good() {
- let res = "Munich,2015,23.1".parse::<Climate>();
- assert_eq!(
- res,
- Ok(Climate {
- city: "Munich".to_string(),
- year: 2015,
- temp: 23.1,
- })
- );
- }
- #[test]
- #[ignore]
- fn test_downcast() {
- let res = "São Paulo,-21,28.5".parse::<Climate>();
- assert!(matches!(res, Err(ParseClimateError::ParseInt(_))));
- let err = res.unwrap_err();
- let inner: Option<&(dyn Error + 'static)> = err.source();
- assert!(inner.is_some());
- assert!(inner.unwrap().is::<ParseIntError>());
- }
-}
diff --git a/info.toml b/info.toml
index 3c37f95..c239121 100644
--- a/info.toml
+++ b/info.toml
@@ -1061,55 +1061,3 @@ path = "exercises/conversions/as_ref_mut.rs"
mode = "test"
hint = """
Add AsRef<str> as a trait bound to the functions."""
-
-# ADVANCED ERRORS
-
-[[exercises]]
-name = "advanced_errs1"
-path = "exercises/advanced_errors/advanced_errs1.rs"
-mode = "test"
-hint = """
-This exercise uses an updated version of the code in errors6. The parsing
-code is now in an implementation of the `FromStr` trait. Note that the
-parsing code uses `?` directly, without any calls to `map_err()`. There is
-one partial implementation of the `From` trait example that you should
-complete.
-
-Details: The `?` operator calls `From::from()` on the error type to convert
-it to the error type of the return type of the surrounding function.
-
-Hint: You will need to write another implementation of `From` that has a
-different input type.
-"""
-
-[[exercises]]
-name = "advanced_errs2"
-path = "exercises/advanced_errors/advanced_errs2.rs"
-mode = "test"
-hint = """
-This exercise demonstrates a few traits that are useful for custom error
-types to implement. These traits make it easier for other code to consume
-the custom error type.
-
-Follow the steps in the comment near the top of the file. You will have to
-supply a missing trait implementation, and complete a few incomplete ones.
-
-You may find these pages to be helpful references:
-https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/define_error_type.html
-https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/boxing_errors.html
-https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/wrap_error.html
-
-Hint: What trait must our error type have for `main()` to return the return
-type that it returns?
-
-Another hint: It's not necessary to implement any methods inside the missing
-trait. (Some methods have default implementations that are supplied by the
-trait.)
-
-Another hint: Consult the tests to determine which error variants (and which
-error message text) to produce for certain error conditions.
-
-Challenge: There is one test that is marked `#[ignore]`. Can you supply the
-missing code that will make it pass? You may want to consult the standard
-library documentation for a certain trait for more hints.
-"""