use crate::options::RecordFormat;
use copybook_error::{Error, ErrorCode, Result};
use std::io::{Read, Write};
pub use copybook_fixed::{FixedRecordReader, FixedRecordWriter};
pub use copybook_rdw::{
BDW_HEADER_LEN, BDW_MAX_BLOCK_LEN, BdwHeader, RDW_HEADER_LEN, RDWRecord, RDWRecordReader,
RDWRecordWriter, VB_MAX_RECORD_LEN, VbBlockReader, VbBlockWriter, VbRecord,
};
#[inline]
#[must_use = "Handle the Result or propagate the error"]
pub fn read_record(
input: &mut impl Read,
format: RecordFormat,
lrecl: Option<u32>,
) -> Result<Option<Vec<u8>>> {
match format {
RecordFormat::Fixed => read_fixed_record(input, lrecl),
RecordFormat::RDW => {
read_rdw_record(input, false).map(|record| record.map(|record| record.payload))
}
RecordFormat::Vb => {
let mut reader = VbBlockReader::new(input, false);
reader
.read_record()
.map(|record| record.map(|record| record.payload))
}
}
}
#[inline]
fn read_fixed_record(input: &mut impl Read, lrecl: Option<u32>) -> Result<Option<Vec<u8>>> {
let mut reader = FixedRecordReader::new(input, lrecl)?;
reader.read_record()
}
#[inline]
#[must_use = "Handle the Result or propagate the error"]
pub fn read_rdw_record(input: &mut impl Read, strict_mode: bool) -> Result<Option<RDWRecord>> {
let mut reader = RDWRecordReader::new(input, strict_mode);
reader.read_record()
}
#[inline]
#[must_use = "Handle the Result or propagate the error"]
pub fn write_record(output: &mut impl Write, data: &[u8], format: RecordFormat) -> Result<()> {
match format {
RecordFormat::Fixed => {
output.write_all(data).map_err(|e| {
Error::new(
ErrorCode::CBKR101_FIXED_RECORD_ERROR,
format!("Write error: {e}"),
)
})?;
Ok(())
}
RecordFormat::RDW => {
let mut writer = RDWRecordWriter::new(output);
writer.write_record_from_payload(data, None)
}
RecordFormat::Vb => {
let mut writer = VbBlockWriter::new(output);
writer.write_record_from_payload(data, 0)?;
writer.finish()
}
}
}