use std::fmt::Write;
use super::escape::Escape;
use crate::error::Result;
pub(super) const MAX_INT_BYTES: usize = 20;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Column {
I64(Vec<i64>),
U64(Vec<u64>),
Str(Vec<String>),
}
impl From<Vec<i64>> for Column {
fn from(values: Vec<i64>) -> Self {
Self::I64(values)
}
}
impl From<Vec<u64>> for Column {
fn from(values: Vec<u64>) -> Self {
Self::U64(values)
}
}
impl From<Vec<String>> for Column {
fn from(values: Vec<String>) -> Self {
Self::Str(values)
}
}
impl From<Vec<&str>> for Column {
fn from(values: Vec<&str>) -> Self {
Self::Str(values.into_iter().map(str::to_owned).collect())
}
}
impl Column {
pub(super) fn len(&self) -> usize {
match self {
Self::I64(values) => values.len(),
Self::U64(values) => values.len(),
Self::Str(values) => values.len(),
}
}
pub(super) fn max_bytes(&self, name: &str, escape: Escape) -> Result<usize> {
let Self::Str(values) = self else {
return Ok(MAX_INT_BYTES);
};
let mut longest = 0;
for (row, value) in values.iter().enumerate() {
if let Some(reason) = escape.refuse(value) {
return Err(format!("column {name:?}, item {row}: {value:?} {reason}").into());
}
longest = longest.max(escape.len(value));
}
Ok(longest)
}
pub(super) fn write(&self, row: usize, escape: Escape, out: &mut String) {
match self {
Self::I64(values) => _ = write!(out, "{}", values[row]),
Self::U64(values) => _ = write!(out, "{}", values[row]),
Self::Str(values) => escape.write(&values[row], out),
}
}
}