use std::{fs::File, io::Write, path::Path};
use serde::Serialize;
use crate::{Error, backend, types::DataFormat};
pub fn write_record_to_writer<T: Serialize>(
writer: impl Write,
record: &T,
data_format: DataFormat,
) -> Result<(), Error> {
match data_format {
DataFormat::Auto => Err(Error::AutoNotSupported),
DataFormat::Json => backend::json::write(writer, record),
#[cfg(feature = "yaml")]
DataFormat::Yaml => backend::yaml::write(writer, record),
#[cfg(feature = "messagepack")]
DataFormat::MessagePack => backend::messagepack::write(writer, record),
#[cfg(feature = "toml")]
DataFormat::Toml => backend::toml::write(writer, record),
_ => Err(Error::UnsupportedFormat(data_format)),
}
}
pub fn write_records_to_writer<'a, T: Serialize + 'a>(
writer: impl Write,
records: impl IntoIterator<Item = &'a T>,
data_format: DataFormat,
) -> Result<(), Error> {
match data_format {
DataFormat::Auto => Err(Error::AutoNotSupported),
DataFormat::Json => backend::json::write(writer, &records.into_iter().collect::<Vec<_>>()),
DataFormat::JsonLines => backend::jsonlines::write(writer, records),
#[cfg(feature = "csv")]
DataFormat::Csv => backend::csv::write(writer, records),
#[cfg(feature = "yaml")]
DataFormat::Yaml => backend::yaml::write(writer, &records.into_iter().collect::<Vec<_>>()),
#[cfg(feature = "messagepack")]
DataFormat::MessagePack => {
backend::messagepack::write(writer, &records.into_iter().collect::<Vec<_>>())
}
#[allow(unreachable_patterns)]
_ => Err(Error::UnsupportedFormat(data_format)),
}
}
pub fn write_record_to_file<T: Serialize>(
path: impl AsRef<Path>,
record: &T,
data_format: DataFormat,
) -> Result<(), Error> {
let path = path.as_ref();
let final_format = if data_format == DataFormat::Auto {
DataFormat::try_from(path)?
} else {
data_format
};
let file = File::create(path)?;
write_record_to_writer(file, record, final_format)
}
pub fn write_records_to_file<'a, T: Serialize + 'a, I: IntoIterator<Item = &'a T>>(
path: impl AsRef<Path>,
records: I,
data_format: DataFormat,
) -> Result<(), Error> {
let path = path.as_ref();
let final_format = if data_format == DataFormat::Auto {
DataFormat::try_from(path)?
} else {
data_format
};
let file = File::create(path)?;
write_records_to_writer(file, records, final_format)
}
#[cfg(test)]
mod tests {
use super::*;
use serde::Serialize;
#[derive(Serialize)]
struct TestRecord {
name: String,
value: i32,
}
#[test]
fn test_write_record_to_writer_auto_not_supported() {
let record = TestRecord {
name: "test".to_string(),
value: 42,
};
let mut buffer = Vec::new();
let result = write_record_to_writer(&mut buffer, &record, DataFormat::Auto);
assert!(matches!(result, Err(Error::AutoNotSupported)));
}
#[test]
fn test_write_records_to_writer_auto_not_supported() {
let records = vec![
TestRecord {
name: "test1".to_string(),
value: 1,
},
TestRecord {
name: "test2".to_string(),
value: 2,
},
];
let mut buffer = Vec::new();
let result = write_records_to_writer(&mut buffer, &records, DataFormat::Auto);
assert!(matches!(result, Err(Error::AutoNotSupported)));
}
}