use std::io::Write;
use crate::cli::OutputFormat;
use crate::error::Result;
use crate::models::{Column, Row};
use super::csv::CsvFormatter;
use super::json::JsonFormatter;
use super::jsonl::JsonlFormatter;
use super::table::TableFormatter;
use super::tsv::TsvFormatter;
pub trait Formatter: Send + Sync {
fn write_header(&mut self, writer: &mut dyn Write, columns: &[Column]) -> Result<()>;
fn write_row(&mut self, writer: &mut dyn Write, row: &Row) -> Result<()>;
fn write_footer(&mut self, writer: &mut dyn Write) -> Result<()>;
fn supports_streaming(&self) -> bool;
}
pub fn create_formatter(format: OutputFormat) -> Box<dyn Formatter> {
match format {
OutputFormat::Table => Box::new(TableFormatter::new()),
OutputFormat::Json => Box::new(JsonFormatter::new()),
OutputFormat::Jsonl => Box::new(JsonlFormatter::new()),
OutputFormat::Csv => Box::new(CsvFormatter::new()),
OutputFormat::Tsv => Box::new(TsvFormatter::new()),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_formatter_table() {
let formatter = create_formatter(OutputFormat::Table);
assert!(!formatter.supports_streaming());
}
#[test]
fn test_create_formatter_json() {
let formatter = create_formatter(OutputFormat::Json);
assert!(formatter.supports_streaming());
}
#[test]
fn test_create_formatter_jsonl() {
let formatter = create_formatter(OutputFormat::Jsonl);
assert!(formatter.supports_streaming());
}
#[test]
fn test_create_formatter_csv() {
let formatter = create_formatter(OutputFormat::Csv);
assert!(formatter.supports_streaming());
}
#[test]
fn test_create_formatter_tsv() {
let formatter = create_formatter(OutputFormat::Tsv);
assert!(formatter.supports_streaming());
}
}