megumax-template 0.1.0

Template library for Megumax project
Documentation
use crate::template::Template;
use crate::variant::Variant;

#[derive(Debug, Clone)]
pub struct Solver<'a> {
	inner: Variant<'a, String>,
	keys: Vec<String>,
}

impl<'a> Solver<'a> {
	pub fn new(list: Vec<&'a [String]>, keys: Vec<String>) -> Self {
		let inner = Variant::new(list);
		Self { inner, keys }
	}
}

impl<'a> Iterator for Solver<'a> {
	type Item = Template;

	fn next(&mut self) -> Option<Self::Item> {
		let keys = self.keys.iter().cloned();
		let variant = self.inner.next()?.into_iter().map(|s| s.to_string());
		let result = keys.zip(variant).collect();
		Some(result)
	}
}

#[cfg(test)]
mod tests {
	use super::*;
	use crate::template::Pool;

	fn prepare_pool() -> Pool {
		let mut pool = Pool::default_rule();
		pool.append("color", "red");
		pool.append("color", "blue");
		pool.append("shape", "circle");
		pool.append("shape", "square");

		pool
	}

	#[test]
	fn solve_color() {
		let pool = prepare_pool();

		let keys = &["color".into()];
		let list = pool.intersect(keys).unwrap();
		let solver = Solver::new(list, keys.to_vec());

		let result: Vec<Template> = solver.collect();
		let expect = vec![
			Template::default().insert("color".into(), "red".into()),
			Template::default().insert("color".into(), "blue".into()),
		];

		assert_eq!(result, expect);
	}

	#[test]
	fn solve_shape() {
		let pool = prepare_pool();
		let keys = &["shape".into()];
		let list = pool.intersect(keys).unwrap();
		let solver = Solver::new(list, keys.to_vec());

		let result: Vec<Template> = solver.collect();
		let expect = vec![
			Template::default().insert("shape".into(), "circle".into()),
			Template::default().insert("shape".into(), "square".into()),
		];

		assert_eq!(result, expect);
	}

	#[test]
	fn solve_both() {
		let pool = prepare_pool();
		let keys = &["color".into(), "shape".into()];
		let list = pool.intersect(keys).unwrap();
		let solver = Solver::new(list, keys.to_vec());

		let result: Vec<Template> = solver.collect();
		let expect = vec![
			Template::default()
				.insert("color".into(), "red".into())
				.insert("shape".into(), "circle".into()),
			Template::default()
				.insert("color".into(), "red".into())
				.insert("shape".into(), "square".into()),
			Template::default()
				.insert("color".into(), "blue".into())
				.insert("shape".into(), "circle".into()),
			Template::default()
				.insert("color".into(), "blue".into())
				.insert("shape".into(), "square".into()),
		];

		assert_eq!(result, expect);
	}

	#[test]
	fn empty_input() {
		let keys = vec![];
		let list = vec![];
		let solver = Solver::new(list, keys);

		let result: Vec<_> = solver.collect();
		let expect = vec![Template::default()];

		assert_eq!(result, expect);
	}
}