use crate::data::stars::StarKey;
use crate::data::types::Mutagen;
use crate::models::palace::PalaceData;
pub struct SurroundedPalaces<'a> {
pub target: &'a PalaceData,
pub opposite: &'a PalaceData,
pub wealth: &'a PalaceData,
pub career: &'a PalaceData,
}
impl<'a> SurroundedPalaces<'a> {
pub fn have(&self, stars: &[StarKey]) -> bool {
let all_keys = self.all_star_keys();
stars.iter().all(|s| all_keys.contains(s))
}
pub fn not_have(&self, stars: &[StarKey]) -> bool {
let all_keys = self.all_star_keys();
stars.iter().all(|s| !all_keys.contains(s))
}
pub fn have_one_of(&self, stars: &[StarKey]) -> bool {
let all_keys = self.all_star_keys();
stars.iter().any(|s| all_keys.contains(s))
}
pub fn have_mutagen(&self, mutagen: Mutagen) -> bool {
self.target.has_mutagen(mutagen)
|| self.opposite.has_mutagen(mutagen)
|| self.wealth.has_mutagen(mutagen)
|| self.career.has_mutagen(mutagen)
}
pub fn not_have_mutagen(&self, mutagen: Mutagen) -> bool {
!self.have_mutagen(mutagen)
}
fn all_star_keys(&self) -> Vec<StarKey> {
let palaces = [self.target, self.opposite, self.wealth, self.career];
let mut keys = Vec::new();
for p in &palaces {
for s in &p.major_stars {
keys.push(s.key);
}
for s in &p.minor_stars {
keys.push(s.key);
}
for s in &p.adjective_stars {
keys.push(s.key);
}
}
keys
}
}
#[cfg(test)]
mod tests {
use crate::astro::builder::by_solar;
use crate::data::stars::StarKey;
use crate::data::types::*;
fn make_astrolabe() -> crate::models::astrolabe::Astrolabe {
by_solar(
"2000-8-16",
2,
Gender::Female,
true,
Language::ZhCN,
Config::default(),
)
.unwrap()
}
#[test]
fn test_surrounded_palaces_structure() {
let a = make_astrolabe();
let sp = a.surrounded_palaces(0).unwrap();
assert_eq!(sp.target.index, 0);
assert_eq!(sp.opposite.index, 6);
assert_eq!(sp.career.index, 4);
assert_eq!(sp.wealth.index, 8);
}
#[test]
fn test_surrounded_palaces_wrapping() {
let a = make_astrolabe();
let sp = a.surrounded_palaces(10).unwrap();
assert_eq!(sp.target.index, 10);
assert_eq!(sp.opposite.index, 4);
assert_eq!(sp.career.index, 2);
assert_eq!(sp.wealth.index, 6);
}
#[test]
fn test_surrounded_palaces_have() {
let a = make_astrolabe();
let sp = a.surrounded_palaces(0).unwrap();
assert!(sp.have_one_of(&[
StarKey::ZiweiMaj,
StarKey::TianjiMaj,
StarKey::TaiyangMaj,
StarKey::TianfuMaj,
]));
}
#[test]
fn test_surrounded_palaces_not_have() {
let a = make_astrolabe();
let sp = a.surrounded_palaces(0).unwrap();
let all_majors = [
StarKey::ZiweiMaj,
StarKey::TianjiMaj,
StarKey::TaiyangMaj,
StarKey::WuquMaj,
StarKey::TiantongMaj,
StarKey::LianzhenMaj,
StarKey::TianfuMaj,
StarKey::TaiyinMaj,
StarKey::TanlangMaj,
StarKey::JumenMaj,
StarKey::TianxiangMaj,
StarKey::TianliangMaj,
StarKey::QishaMaj,
StarKey::PojunMaj,
];
let missing: Vec<StarKey> = all_majors
.iter()
.filter(|k| !sp.have(&[**k]))
.copied()
.collect();
if !missing.is_empty() {
assert!(sp.not_have(&missing));
}
}
#[test]
fn test_surrounded_palaces_mutagen() {
let a = make_astrolabe();
let any_has_lu =
(0..12).any(|i| a.surrounded_palaces(i).unwrap().have_mutagen(Mutagen::Lu));
assert!(any_has_lu);
let any_has_ji =
(0..12).any(|i| a.surrounded_palaces(i).unwrap().have_mutagen(Mutagen::Ji));
assert!(any_has_ji);
}
#[test]
fn test_surrounded_palaces_not_have_mutagen() {
let a = make_astrolabe();
let sp = a.surrounded_palaces(0).unwrap();
for m in &[Mutagen::Lu, Mutagen::Quan, Mutagen::Ke, Mutagen::Ji] {
assert_eq!(sp.not_have_mutagen(*m), !sp.have_mutagen(*m));
}
}
}