use reifydb_value::value::{Value, diff_type::DiffType, frame::frame::Frame};
use serde_json::{Error, to_string};
use crate::{
json::{
none_marker,
types::{ResponseColumn, ResponseFrame},
wire_type::WireValueType,
},
tag::peel_options,
};
pub fn convert_frames(frames: &[Frame]) -> Vec<ResponseFrame> {
let mut result = Vec::new();
for frame in frames {
let row_numbers: Vec<u64> = frame.row_numbers().iter().map(|rn| rn.value()).collect();
let created_at: Vec<String> = frame.created_at().iter().map(|dt| dt.to_string()).collect();
let updated_at: Vec<String> = frame.updated_at().iter().map(|dt| dt.to_string()).collect();
let time: Vec<String> = frame.time().iter().map(|dt| dt.to_string()).collect();
let mut columns = Vec::new();
for column in frame.iter() {
let column_type = column.data.get_type();
let column_depth = peel_options(&column_type).1;
let column_data: Vec<String> = column
.data
.iter()
.map(|value| match value {
Value::None {
inner,
} => none_marker(column_depth.saturating_sub(peel_options(&inner).1 + 1)),
Value::Blob(b) => b.to_hex(),
_ => value.to_string(),
})
.collect();
columns.push(ResponseColumn {
name: column.name.clone(),
r#type: WireValueType(column_type),
payload: column_data,
});
}
result.push(ResponseFrame {
op: frame.op.map(DiffType::as_u8),
row_numbers,
created_at,
updated_at,
time,
columns,
});
}
result
}
pub fn frames_to_json(frames: &[Frame]) -> Result<String, Error> {
let response_frames = convert_frames(frames);
to_string(&response_frames)
}