use crate::language::Language;
use crate::table::ColumnConfig;
use crate::{aperror, table};
use crate::{basetype, lint};
pub struct ColInt {
info: table::ColumnInfo,
values: Vec<i64>,
min: i64, max: i64, }
impl table::Column for ColInt {
fn info(&self) -> &table::ColumnInfo {
&self.info
}
fn emit_table_cell(&self, row: usize, _lang: &dyn Language) -> String {
let v = self.values[row];
v.to_string()
}
fn indexes(&self) -> Vec<usize> {
let values = &self.values;
let mut indexes = Vec::from_iter(0..values.len());
indexes.sort_by(|a, b| values[*a].cmp(&values[*b]));
indexes
}
fn lint(&self, linter: &lint::Linter) {
linter.err(
self.max <= self.info.interface_type.max() as i64,
&format!(
"value overflow {} for interface type {}",
self.max, self.info.interface_type
),
);
linter.err(
self.min >= self.info.interface_type.min() as i64,
&format!(
"value undeflow {} for interface type {}",
self.min, self.info.interface_type
),
);
}
}
impl ColInt {
pub fn parse(
config: ColumnConfig,
strvals: &[String],
interface_type: basetype::BaseType,
) -> aperror::Result<Box<dyn table::Column>> {
let values = table::parse_vec::<i64>(strvals)?;
let min = *values.iter().min().unwrap_or(&0); let max = *values.iter().max().unwrap_or(&0);
Ok(Box::new(ColInt {
info: table::ColumnInfo {
config,
len: values.len(),
interface_type,
table_type: basetype::int_type_for_range(min..=max),
},
values,
min, max, }))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn u8_no_oveflow() {
let c = ColInt::parse(
ColumnConfig::default(),
&vec!["123".to_string()],
basetype::BaseType::U8,
)
.expect("");
let linter = lint::test_linter();
c.lint(&linter);
assert!(linter.errors() == 0);
}
#[test]
fn u8_oveflow() {
let c = ColInt::parse(
ColumnConfig::default(),
&vec!["300".to_string()],
basetype::BaseType::U8,
)
.expect("");
let linter = lint::test_linter();
c.lint(&linter);
assert!(linter.errors() == 1);
}
#[test]
fn u8_underflow() {
let c = ColInt::parse(
ColumnConfig::default(),
&vec!["-1".to_string()],
basetype::BaseType::U8,
)
.expect("");
let linter = lint::test_linter();
c.lint(&linter);
assert!(linter.errors() == 1);
}
}