rustlings

solving rustlings ft. dracuxan
git clone [email protected]:dracuxan/rustlings.git
Log | Files | Refs

from_str.rs (3090B)


      1 // This is similar to the previous `from_into` exercise. But this time, we'll
      2 // implement `FromStr` and return errors instead of falling back to a default
      3 // value. Additionally, upon implementing `FromStr`, you can use the `parse`
      4 // method on strings to generate an object of the implementor type. You can read
      5 // more about it in the documentation:
      6 // https://doc.rust-lang.org/std/str/trait.FromStr.html
      7 
      8 use std::num::ParseIntError;
      9 use std::str::FromStr;
     10 
     11 #[derive(Debug, PartialEq)]
     12 struct Person {
     13     name: String,
     14     age: u8,
     15 }
     16 
     17 // We will use this error type for the `FromStr` implementation.
     18 #[derive(Debug, PartialEq)]
     19 enum ParsePersonError {
     20     // Incorrect number of fields
     21     BadLen,
     22     // Empty name field
     23     NoName,
     24     // Wrapped error from parse::<u8>()
     25     ParseInt(ParseIntError),
     26 }
     27 
     28 // TODO: Complete this `FromStr` implementation to be able to parse a `Person`
     29 // out of a string in the form of "Mark,20".
     30 // Note that you'll need to parse the age component into a `u8` with something
     31 // like `"4".parse::<u8>()`.
     32 //
     33 // Steps:
     34 // 1. Split the given string on the commas present in it.
     35 // 2. If the split operation returns less or more than 2 elements, return the
     36 //    error `ParsePersonError::BadLen`.
     37 // 3. Use the first element from the split operation as the name.
     38 // 4. If the name is empty, return the error `ParsePersonError::NoName`.
     39 // 5. Parse the second element from the split operation into a `u8` as the age.
     40 // 6. If parsing the age fails, return the error `ParsePersonError::ParseInt`.
     41 impl FromStr for Person {
     42     type Err = ParsePersonError;
     43 
     44     fn from_str(s: &str) -> Result<Self, Self::Err> {}
     45 }
     46 
     47 fn main() {
     48     let p = "Mark,20".parse::<Person>();
     49     println!("{p:?}");
     50 }
     51 
     52 #[cfg(test)]
     53 mod tests {
     54     use super::*;
     55     use ParsePersonError::*;
     56 
     57     #[test]
     58     fn empty_input() {
     59         assert_eq!("".parse::<Person>(), Err(BadLen));
     60     }
     61 
     62     #[test]
     63     fn good_input() {
     64         let p = "John,32".parse::<Person>();
     65         assert!(p.is_ok());
     66         let p = p.unwrap();
     67         assert_eq!(p.name, "John");
     68         assert_eq!(p.age, 32);
     69     }
     70 
     71     #[test]
     72     fn missing_age() {
     73         assert!(matches!("John,".parse::<Person>(), Err(ParseInt(_))));
     74     }
     75 
     76     #[test]
     77     fn invalid_age() {
     78         assert!(matches!("John,twenty".parse::<Person>(), Err(ParseInt(_))));
     79     }
     80 
     81     #[test]
     82     fn missing_comma_and_age() {
     83         assert_eq!("John".parse::<Person>(), Err(BadLen));
     84     }
     85 
     86     #[test]
     87     fn missing_name() {
     88         assert_eq!(",1".parse::<Person>(), Err(NoName));
     89     }
     90 
     91     #[test]
     92     fn missing_name_and_age() {
     93         assert!(matches!(",".parse::<Person>(), Err(NoName | ParseInt(_))));
     94     }
     95 
     96     #[test]
     97     fn missing_name_and_invalid_age() {
     98         assert!(matches!(
     99             ",one".parse::<Person>(),
    100             Err(NoName | ParseInt(_)),
    101         ));
    102     }
    103 
    104     #[test]
    105     fn trailing_comma() {
    106         assert_eq!("John,32,".parse::<Person>(), Err(BadLen));
    107     }
    108 
    109     #[test]
    110     fn trailing_comma_and_some_string() {
    111         assert_eq!("John,32,man".parse::<Person>(), Err(BadLen));
    112     }
    113 }