Last active
April 21, 2023 00:39
-
-
Save bewest/b2b77025b0621d403d79238364a09663 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This does practically the same thing that TryFrom<&str> does. | |
// Additionally, upon implementing FromStr, you can use the `parse` method | |
// on strings to generate an object of the implementor type. | |
// You can read more about it at https://doc.rust-lang.org/std/str/trait.FromStr.html | |
use std::str::FromStr; | |
#[derive(Debug)] | |
struct Person { | |
name: String, | |
age: usize, | |
} | |
// Steps: | |
// 1. If the length of the provided string is 0, then return an error | |
// 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 an error | |
// 5. Extract the other element from the split operation and parse it into a `usize` as the age | |
// with something like `"4".parse::<usize>()`. | |
// If while parsing the age, something goes wrong, then return an error | |
// Otherwise, then return a Result of a Person object | |
impl FromStr for Person { | |
type Err = String; | |
fn from_str(s: &str) -> Result<Person, Self::Err> { | |
let mut it = s.split(','); | |
let name = it | |
.next() | |
.filter(|string| string.len() > 0) | |
.map(|string| string.parse::<String>()); | |
let age = it.next().map(|string| string.parse::<usize>()); | |
match (name, age) { | |
(Some(Ok(name)), Some(Ok(age))) => Ok(Person { name, age }), | |
(_, _) => Err(format!("something else wrong")), | |
} | |
} | |
} | |
fn main() { | |
let p = "Mark,20".parse::<Person>().unwrap(); | |
println!("{:?}", p); | |
} | |
#[cfg(test)] | |
mod tests { | |
use super::*; | |
#[test] | |
fn empty_input() { | |
assert!("".parse::<Person>().is_err()); | |
} | |
#[test] | |
fn good_input() { | |
let p = "John,32".parse::<Person>(); | |
assert!(p.is_ok()); | |
let p = p.unwrap(); | |
assert_eq!(p.name, "John"); | |
assert_eq!(p.age, 32); | |
} | |
#[test] | |
#[should_panic] | |
fn missing_age() { | |
"John,".parse::<Person>().unwrap(); | |
} | |
#[test] | |
#[should_panic] | |
fn invalid_age() { | |
"John,twenty".parse::<Person>().unwrap(); | |
} | |
#[test] | |
#[should_panic] | |
fn missing_comma_and_age() { | |
"John".parse::<Person>().unwrap(); | |
} | |
#[test] | |
#[should_panic] | |
fn missing_name() { | |
",1".parse::<Person>().unwrap(); | |
} | |
#[test] | |
#[should_panic] | |
fn missing_name_and_age() { | |
",".parse::<Person>().unwrap(); | |
} | |
#[test] | |
#[should_panic] | |
fn missing_name_and_invalid_age() { | |
",one".parse::<Person>().unwrap(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment