use core::borrow::Borrow;
use crate::{config::TriadsConfig, triad::{Fault, Frame, Means, Need, Triad}};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Personality
{
pub frame: Frame,
pub strategy: Means,
pub fault: Fault,
pub need: Need
}
impl Personality
{
pub fn affirmation(&self, f: &mut core::fmt::Formatter, config: &dyn Borrow<TriadsConfig>) -> core::fmt::Result
{
let frame = self.frame.config(config);
let frame = frame.affirmation.as_ref();
let fault = self.fault.config(config);
let fault = fault.affirmation.as_ref();
let strategy = self.strategy.config(config);
let strategy = strategy.affirmation.as_ref();
write!(f, "i will {frame}, {fault}, and {strategy}.")
}
pub fn from_triads(triads: [&dyn Triad; 4]) -> Self
{
let (frame, strategy, fault, need) = triads.into_iter()
.map(|triad| {
let any = triad.as_any();
any.downcast_ref()
.map(|frame| (Some(frame), None, None, None))
.or_else(|| any.downcast_ref()
.map(|strategy| (None, Some(strategy), None, None))
).or_else(|| any.downcast_ref()
.map(|fault| (None, None, Some(fault), None))
).or_else(|| any.downcast_ref()
.map(|need| (None, None, None, Some(need)))
).expect("The triad type is not r{ecognized. Something must have gone horribly wrong!")
}).reduce(|lhs, rhs| (
lhs.0.map(Some).xor(rhs.0.map(Some)).map(|inner| inner.expect("Unsound personality. Conflicting personality frame")),
lhs.1.map(Some).xor(rhs.1.map(Some)).map(|inner| inner.expect("Unsound personality. Conflicting personality strategy")),
lhs.2.map(Some).xor(rhs.2.map(Some)).map(|inner| inner.expect("Unsound personality. Conflicting personality fault")),
lhs.3.map(Some).xor(rhs.3.map(Some)).map(|inner| inner.expect("Unsound personality. Conflicting personality need")),
)).expect("Unsound personality, No triads given. Impossible!");
Personality {
frame: *frame.expect("Unsound personality. Undefined personality frame"),
strategy: *strategy.expect("Unsound personality. Undefined personality strategy"),
fault: *fault.expect("Unsound personality. Undefined personality fault"),
need: *need.expect("Unsound personality. Undefined personality need")
}
}
}