use crate::errors::{CsvlensError, CsvlensResult};
#[derive(Debug)]
pub enum Delimiter {
Default,
Comma,
Tab,
Character(u8),
Auto,
}
impl Delimiter {
pub fn from_arg(
delimiter_arg: &Option<String>,
tab_separation: bool,
comma_separation: bool,
) -> CsvlensResult<Self> {
if comma_separation {
return Ok(Delimiter::Comma);
}
if tab_separation {
return Ok(Delimiter::Tab);
}
if let Some(s) = delimiter_arg {
if s == "auto" {
return Ok(Delimiter::Auto);
}
if s == r"\t" {
return Ok(Delimiter::Tab);
}
let mut chars = s.chars();
let c = chars.next().ok_or_else(|| CsvlensError::DelimiterEmpty)?;
if !c.is_ascii() {
return Err(CsvlensError::DelimiterNotAscii(c));
}
if chars.next().is_some() {
return Err(CsvlensError::DelimiterMultipleCharacters(s.clone()));
}
if c == 't' {
return Ok(Delimiter::Tab);
}
Ok(Delimiter::Character(c.try_into()?))
} else {
Ok(Delimiter::Default)
}
}
}
pub fn sniff_delimiter(filename: &str) -> Option<u8> {
let mut sniffer = qsv_sniffer::Sniffer::new();
sniffer.sample_size(qsv_sniffer::SampleSize::Records(200));
if let Ok(metadata) = sniffer.sniff_path(filename) {
return Some(metadata.dialect.delimiter);
}
None
}