use std::io::Error;
use data_alchemist::writer::{OutputSink, OutputWriter};
pub struct JsonWriter;
pub struct JsonProperties {}
impl<T> OutputWriter<T> for JsonWriter where T: serde::Serialize {
type Properties = JsonProperties;
fn write(data: T, sink: &dyn OutputSink, _: Self::Properties) -> Result<(), Error> {
let serialized = serde_json::to_vec(&data)?;
sink.write_data(&serialized)
}
}
#[cfg(test)]
mod test {
use mockall::mock;
use mockall::predicate::eq;
use serde::Serialize;
use super::*;
mock! {
pub OutputSink {}
impl OutputSink for OutputSink {
fn write_data(&self, data: &[u8]) -> Result<(), Error>;
}
}
#[derive(Serialize, Debug, PartialEq)]
struct TestStruct {
name: String,
age: u32,
}
#[test]
fn given_valid_struct_should_serialize_and_write() {
let test_data = TestStruct {
name: "Alice".to_string(),
age: 30,
};
let expected_json = serde_json::to_vec(&test_data).unwrap();
let mut mock_sink = MockOutputSink::new();
mock_sink.expect_write_data()
.with(eq(expected_json.clone())) .times(1)
.returning(|_| Ok(()));
let result = JsonWriter::write(test_data, &mut mock_sink, JsonProperties {});
assert!(result.is_ok());
}
#[test]
fn given_sink_write_error_should_return_error() {
let test_data = TestStruct {
name: "Bob".to_string(),
age: 42,
};
let mut mock_sink = MockOutputSink::new();
mock_sink.expect_write_data()
.times(1)
.returning(|_| Err(std::io::Error::from(std::io::ErrorKind::Other)));
let result = JsonWriter::write(test_data, &mut mock_sink, JsonProperties {});
assert!(result.is_err());
}
}