//! Your task is to implement the `From` trait for `Person` to make creating //! Persons easier. //! //! The From trait is used for value-to-value conversions. When From is //! implemented for a source type, the Into trait is automatically implemented //! for the target type. You can read more about it at //! https://doc.rust-lang.org/std/convert/trait.From.html //! //! As a side note, ignore the fact that it makes absolutely no sense that a //! person has "default values". (This exercise is taken from Rustlings) #[derive(Debug, PartialEq)] struct Person { name: String, age: usize, } // We implement the `Default` trait to use it as a fallback when the provided // string is not convertible into a Person object. Note that this is not good // practice, one should use a `Result` rather. impl Default for Person { fn default() -> Person { Person { name: String::from("John"), age: 30, } } } // Steps: // 1. If the length of the provided string is 0, then return the default of // Person // 2. Split the given string on the commas present in it // 3. Extract the first element from the split operation and use it as the name // 4. If the name is empty, then return the default of Person // 5. Extract the other element from the split operation and parse it into a // `usize` as the age If while parsing the age, something goes wrong, then // return the default of Person Otherwise, then return an instantiated Person // object with the results impl From<&str> for Person { // TODO } // Do not edit anything below #[test] fn main() { // Use the `from` associated function let p1 = Person::from("Mark,20"); // Use the `into` method let p2: Person = "Gerald,70".into(); println!("{:?}", p1); println!("{:?}", p2); } #[cfg(test)] mod tests { use super::*; #[test] fn default() { // Test that the default person is 30 year old John let dp = Person::default(); assert_eq!(dp.name, "John"); assert_eq!(dp.age, 30); } #[test] fn empty_convert() { // Test that John is returned when an empty string is provided let p = Person::from(""); assert_eq!(p, Person::default()); } #[test] fn good_convert() { // Test that "Mark,20" works let p = Person::from("Mark,20"); assert_eq!(p.name, "Mark"); assert_eq!(p.age, 20); } #[test] fn bad_age() { // Test that "Mark,twenty" will return the default person due to an // error in parsing age let p = Person::from("Mark,twenty"); assert_eq!(p, Person::default()); } #[test] fn missing_comma_and_age() { let p = Person::from("Mark"); assert_eq!(p, Person::default()); } #[test] fn missing_age() { let p = Person::from("Mark,"); assert_eq!(p, Person::default()); } #[test] fn missing_name() { let p = Person::from(",1"); assert_eq!(p, Person::default()); } #[test] fn missing_name_and_age() { let p = Person::from(","); assert_eq!(p, Person::default()); } #[test] fn missing_name_and_invalid_age() { let p = Person::from(",one"); assert_eq!(p, Person::default()); } #[test] fn trailing_comma() { let p = Person::from("Mike,32,"); assert_eq!(p, Person::default()); } #[test] fn trailing_comma_and_some_string() { let p = Person::from("Mike,32,man"); assert_eq!(p, Person::default()); } }