use crate::core::{Transformation, Function, StabilityRelation, Domain};
use crate::error::Fallible;
use crate::dist::{SymmetricDistance};
use crate::dom::{VectorDomain, SizedDomain};
use std::cmp::Ordering;
use crate::traits::CheckNull;
pub fn make_resize_constant<DA>(
size: usize, atom_domain: DA,
constant: DA::Carrier
) -> Fallible<Transformation<VectorDomain<DA>, SizedDomain<VectorDomain<DA>>, SymmetricDistance, SymmetricDistance>>
where DA: 'static + Clone + Domain,
DA::Carrier: 'static + Clone + CheckNull {
if !atom_domain.member(&constant)? { return fallible!(MakeTransformation, "constant must be a member of DA")}
if size == 0 { return fallible!(MakeTransformation, "row size must be greater than zero") }
Ok(Transformation::new(
VectorDomain::new(atom_domain.clone()),
SizedDomain::new(VectorDomain::new(atom_domain), size),
Function::new(move |arg: &Vec<DA::Carrier>| match arg.len().cmp(&size) {
Ordering::Less => arg.iter().chain(vec![&constant; size - arg.len()]).cloned().collect(),
Ordering::Equal => arg.clone(),
Ordering::Greater => arg[..size].to_vec()
}),
SymmetricDistance::default(),
SymmetricDistance::default(),
StabilityRelation::new_from_constant(2)
))
}
#[cfg(test)]
mod test {
use super::*;
use crate::dom::AllDomain;
#[test]
fn test() -> Fallible<()> {
let trans = make_resize_constant(3, AllDomain::new(), "x")?;
assert_eq!(trans.invoke(&vec!["A"; 2])?, vec!["A", "A", "x"]);
assert_eq!(trans.invoke(&vec!["A"; 3])?, vec!["A"; 3]);
assert_eq!(trans.invoke(&vec!["A"; 4])?, vec!["A", "A", "A"]);
assert!(trans.check(&1, &2)?);
assert!(!trans.check(&1, &1)?);
Ok(())
}
}