From 34b20b7786a8f6753bb449425772958e0285c385 Mon Sep 17 00:00:00 2001 From: Griffin Smith Date: Sun, 28 Jul 2019 22:31:07 -0400 Subject: [PATCH] Add functions for making sentences from lists This seems like something I keep having to write --- proptest-regressions/description.txt | 7 +++ src/description.rs | 93 ++++++++++++++++++++++++++++ src/main.rs | 1 + 3 files changed, 101 insertions(+) create mode 100644 proptest-regressions/description.txt create mode 100644 src/description.rs diff --git a/proptest-regressions/description.txt b/proptest-regressions/description.txt new file mode 100644 index 000000000..3c4942315 --- /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 000000000..4c553c746 --- /dev/null +++ b/src/description.rs @@ -0,0 +1,93 @@ +use crate::entities::Describe; + +pub fn list_to_sentence(lst: &Vec) -> String { + let mut buf = String::with_capacity( + lst.iter() + .map(|e| e.len() + 2usize /* ", " */) + .sum::() + + 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(lst: &Vec) -> String { + list_to_sentence( + &lst.iter().map(|e| e.description()).collect::>(), + ) +} + +#[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 + ) { + 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 b322a969a..676d2173e 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;