From 34b20b7786a8f6753bb449425772958e0285c385 Mon Sep 17 00:00:00 2001 From: Griffin Smith Date: Sun, 28 Jul 2019 22:31:07 -0400 Subject: Add functions for making sentences from lists This seems like something I keep having to write --- src/description.rs | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 1 + 2 files changed, 94 insertions(+) create mode 100644 src/description.rs (limited to 'src') 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 { + 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 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; -- cgit 1.4.1