Skip to content

Instantly share code, notes, and snippets.

@bewest
Last active April 21, 2023 00:39
Show Gist options
  • Save bewest/b2b77025b0621d403d79238364a09663 to your computer and use it in GitHub Desktop.
Save bewest/b2b77025b0621d403d79238364a09663 to your computer and use it in GitHub Desktop.
// 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