pub mod xcsp3_core {
use crate::errors::xcsp3error::xcsp3_core::Xcsp3Error;
use crate::utils::utils_functions::xcsp3_utils::{
get_all_variables_between_lower_and_upper, size_to_string, sizes_to_double_vec,
sizes_to_vec,
};
use crate::variables::xdomain::xcsp3_core::XDomainInteger;
use std::fmt::{Display, Formatter};
#[derive(Clone)]
pub struct XVariableArray {
pub(crate) id: String,
sizes: Vec<usize>,
domain: XDomainInteger,
}
impl Display for XVariableArray {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut ret: String = String::default();
for e in self.sizes.iter() {
ret.push('[');
ret.push_str(e.to_string().as_str());
ret.push(']');
}
write!(
f,
"XVariableArray: id = {}, size = {} domain = {}",
self.id,
ret,
self.domain.to_string().as_str()
)
}
}
impl XVariableArray {
pub fn find_variable(
&self,
id: &str,
) -> Result<Vec<(String, &XDomainInteger)>, Xcsp3Error> {
let mut ret: Vec<(String, &XDomainInteger)> = vec![];
match id.find('[') {
None => {
return Err(Xcsp3Error::get_variable_size_invalid_error(
"find_variable in XVariableArray error",
));
}
Some(v) => match sizes_to_double_vec(&id[v..]) {
Ok((mut lower, mut upper)) => {
for i in 0..lower.len() {
if lower[i] == usize::MAX && upper[i] == usize::MAX {
lower[i] = 0;
upper[i] = self.sizes[i] - 1;
}
if lower[i] > upper[i] || upper[i] >= self.sizes[i] {
return Err(Xcsp3Error::get_variable_size_invalid_error(
"find_variable in XVariableArray error",
));
}
}
let all_variable = get_all_variables_between_lower_and_upper(lower, upper);
for size_vec in all_variable.iter() {
ret.push((size_to_string(&id[..v], size_vec), &self.domain));
}
}
Err(e) => {
return Err(e);
}
},
}
Ok(ret)
}
pub fn new(id: &str, sizes: &str, domain: XDomainInteger) -> Result<Self, Xcsp3Error> {
match sizes_to_vec(sizes) {
Ok((size_vec, _)) => Ok(XVariableArray {
id: id.to_string(),
sizes: size_vec,
domain,
}),
Err(e) => Err(e),
}
}
}
}