diff options
author | Griffin Smith <root@gws.fyi> | 2019-07-29T02·31-0400 |
---|---|---|
committer | Griffin Smith <root@gws.fyi> | 2019-07-29T02·31-0400 |
commit | 34b20b7786a8f6753bb449425772958e0285c385 (patch) | |
tree | e8781db1c3bed3f8897f40fb201c40b6f1d28bac | |
parent | ba7bec9a3e36eaf2af65677b02884172241d1b24 (diff) |
Add functions for making sentences from lists
This seems like something I keep having to write
-rw-r--r-- | proptest-regressions/description.txt | 7 | ||||
-rw-r--r-- | src/description.rs | 93 | ||||
-rw-r--r-- | src/main.rs | 1 |
3 files changed, 101 insertions, 0 deletions
diff --git a/proptest-regressions/description.txt b/proptest-regressions/description.txt new file mode 100644 index 000000000000..3c4942315b45 --- /dev/null +++ b/proptest-regressions/description.txt @@ -0,0 +1,7 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc 92b51b5444b913aaa6cb89d7e7175ab6a6af5b5231ba047d123bb55d43d7d272 # shrinks to descriptions = [] diff --git a/src/description.rs b/src/description.rs new file mode 100644 index 000000000000..4c553c746d91 --- /dev/null +++ b/src/description.rs @@ -0,0 +1,93 @@ +use crate::entities::Describe; + +pub fn list_to_sentence(lst: &Vec<String>) -> String { + let mut buf = String::with_capacity( + lst.iter() + .map(|e| e.len() + 2usize /* ", " */) + .sum::<usize>() + + if lst.len() >= 3 { + 3usize /* "and" */ + } else { + 0usize + }, + ); + + match lst.len() { + 0 => {} + 1 => buf.push_str(&lst[0]), + 2 => { + buf.push_str(&lst[0]); + buf.push_str(" and "); + buf.push_str(&lst[1]); + } + _ => { + for desc in &lst[..lst.len() - 1] { + buf.push_str(desc); + buf.push_str(", "); + } + buf.push_str("and "); + buf.push_str(&lst[lst.len() - 1]); + } + } + + buf +} + +pub fn describe_list<A: Describe>(lst: &Vec<A>) -> String { + list_to_sentence( + &lst.iter().map(|e| e.description()).collect::<Vec<String>>(), + ) +} + +#[cfg(test)] +mod tests { + use super::*; + use proptest::prelude::*; + use proptest_derive::Arbitrary; + + #[derive(Debug, Arbitrary)] + struct Description(String); + + impl Describe for Description { + fn description(&self) -> String { + self.0.clone() + } + } + + proptest! { + #[test] + fn test_describe_list_includes_all_descriptions( + descriptions: Vec<Description> + ) { + let res = describe_list(&descriptions); + for Description(desc) in descriptions { + assert!(res.contains(&desc)); + } + } + } + + #[test] + fn test_describe_list() { + assert_eq!( + describe_list(&vec![Description("one".to_string())]), + "one".to_string() + ); + + assert_eq!( + describe_list(&vec![ + Description("one".to_string()), + Description("two".to_string()) + ]), + "one and two".to_string() + ); + + assert_eq!( + describe_list(&vec![ + Description("one".to_string()), + Description("two".to_string()), + Description("three".to_string()) + ]), + "one, two, and three".to_string() + ); + } +} diff --git a/src/main.rs b/src/main.rs index b322a969a1be..676d2173e857 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,6 +34,7 @@ mod util; mod types; #[macro_use] mod entities; +mod description; mod display; mod game; mod level_gen; |