use std::fmt;
#[derive(Clone, PartialEq, Eq, Hash)]
pub enum MatrixCellValue {
Tag(String),
String(String),
Int(i64),
Unsigned(u64),
Bool(bool),
}
impl fmt::Display for MatrixCellValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
MatrixCellValue::Tag(s) => write!(f, "{}", s), MatrixCellValue::String(s) => write!(f, "\"{}\"", s), MatrixCellValue::Int(i) => write!(f, "{}", i),
MatrixCellValue::Unsigned(u) => write!(f, "{}", u),
MatrixCellValue::Bool(b) => write!(f, "{}", b),
}
}
}
impl fmt::Debug for MatrixCellValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
MatrixCellValue::Tag(s) => write!(f, "Tag({})", s),
MatrixCellValue::String(s) => write!(f, "String(\"{}\")", s),
MatrixCellValue::Int(i) => write!(f, "Int({})", i),
MatrixCellValue::Unsigned(u) => write!(f, "Unsigned({})", u),
MatrixCellValue::Bool(b) => write!(f, "Bool({})", b),
}
}
}
impl From<&'static str> for MatrixCellValue {
fn from(s: &'static str) -> Self {
MatrixCellValue::Tag(s.to_string()) }
}
impl From<String> for MatrixCellValue {
fn from(s: String) -> Self {
MatrixCellValue::String(s)
}
}
impl From<i64> for MatrixCellValue {
fn from(i: i64) -> Self {
MatrixCellValue::Int(i)
}
}
impl From<i32> for MatrixCellValue {
fn from(i: i32) -> Self {
MatrixCellValue::Int(i as i64)
}
}
impl From<u64> for MatrixCellValue {
fn from(u: u64) -> Self {
MatrixCellValue::Unsigned(u)
}
}
impl From<u32> for MatrixCellValue {
fn from(u: u32) -> Self {
MatrixCellValue::Unsigned(u as u64)
}
}
impl From<bool> for MatrixCellValue {
fn from(b: bool) -> Self {
MatrixCellValue::Bool(b)
}
}
#[derive(Debug, Clone)]
pub struct AbstractCombination {
pub cells: Vec<MatrixCellValue>,
}
impl AbstractCombination {
pub fn id_suffix(&self) -> String {
let parts: Vec<String> = self
.cells
.iter()
.map(|cell| match cell {
MatrixCellValue::Tag(s) => s.clone(),
MatrixCellValue::String(s) => s.replace(|c: char| !c.is_alphanumeric(), "_"),
MatrixCellValue::Int(i) => format!("Int{}", i),
MatrixCellValue::Unsigned(u) => format!("Uint{}", u),
MatrixCellValue::Bool(b) => format!("Bool{}", b),
})
.collect();
if parts.is_empty() {
return "_".to_string();
}
format!("_{}", parts.join("_"))
}
pub fn id_suffix_with_names(&self, param_names: &[String]) -> String {
if self.cells.is_empty() {
return "_".to_string();
}
if param_names.len() != self.cells.len() {
eprintln!("[BenchMatrix::AbstractCombination] [WARN] Mismatch between param_names length ({}) and cell count ({}). Falling back to default ID suffix.", param_names.len(), self.cells.len());
return self.id_suffix();
}
let parts: Vec<String> = self
.cells
.iter()
.zip(param_names.iter())
.map(|(cell, name)| {
let value_str = match cell {
MatrixCellValue::Tag(s) => s.clone(),
MatrixCellValue::String(s) => s.replace(|c: char| !c.is_alphanumeric(), "_"),
MatrixCellValue::Int(i) => i.to_string(),
MatrixCellValue::Unsigned(u) => u.to_string(),
MatrixCellValue::Bool(b) => b.to_string(),
};
let sanitized_name = name.replace(|c: char| !c.is_alphanumeric(), "");
format!("{}-{}", sanitized_name, value_str)
})
.collect();
format!("_{}", parts.join("_"))
}
pub fn get_tag(&self, index: usize) -> Result<&str, String> {
match self.cells.get(index) {
Some(MatrixCellValue::Tag(s)) => Ok(s.as_str()),
Some(other) => Err(format!("Expected Tag at index {}, found {:?}", index, other)),
None => Err(format!("No cell at index {}", index)),
}
}
pub fn get_string(&self, index: usize) -> Result<&str, String> {
match self.cells.get(index) {
Some(MatrixCellValue::String(s)) => Ok(s.as_str()),
Some(other) => Err(format!("Expected String at index {}, found {:?}", index, other)),
None => Err(format!("No cell at index {}", index)),
}
}
pub fn get_i64(&self, index: usize) -> Result<i64, String> {
match self.cells.get(index) {
Some(MatrixCellValue::Int(i)) => Ok(*i),
Some(other) => Err(format!("Expected Int at index {}, found {:?}", index, other)),
None => Err(format!("No cell at index {}", index)),
}
}
pub fn get_u64(&self, index: usize) -> Result<u64, String> {
match self.cells.get(index) {
Some(MatrixCellValue::Unsigned(u)) => Ok(*u),
Some(other) => Err(format!("Expected Unsigned at index {}, found {:?}", index, other)),
None => Err(format!("No cell at index {}", index)),
}
}
pub fn get_bool(&self, index: usize) -> Result<bool, String> {
match self.cells.get(index) {
Some(MatrixCellValue::Bool(b)) => Ok(*b),
Some(other) => Err(format!("Expected Bool at index {}, found {:?}", index, other)),
None => Err(format!("No cell at index {}", index)),
}
}
}