laminar_connectors/schema/json/encoder/
mod.rs1use std::io::Write as _;
4use std::sync::Arc;
5
6use arrow_array::cast::AsArray;
7use arrow_array::{Array, RecordBatch};
8use arrow_json::writer::{
9 Encoder, EncoderFactory, EncoderOptions, LineDelimited, NullableEncoder, WriterBuilder,
10};
11use arrow_schema::{ArrowError, DataType, FieldRef, SchemaRef};
12
13use crate::schema::error::{SchemaError, SchemaResult};
14use crate::schema::traits::FormatEncoder;
15
16#[derive(Debug)]
20pub struct JsonEncoder {
21 schema: SchemaRef,
22}
23
24impl JsonEncoder {
25 #[must_use]
27 pub fn new(schema: SchemaRef) -> Self {
28 Self { schema }
29 }
30}
31
32impl FormatEncoder for JsonEncoder {
33 fn input_schema(&self) -> SchemaRef {
34 self.schema.clone()
35 }
36
37 fn encode_batch(&self, batch: &RecordBatch) -> SchemaResult<Vec<Vec<u8>>> {
38 if batch.num_rows() == 0 {
39 return Ok(Vec::new());
40 }
41
42 let mut buf = Vec::new();
43 {
44 let mut writer = WriterBuilder::new()
45 .with_explicit_nulls(true)
46 .with_encoder_factory(Arc::new(JsonbPassthroughFactory))
47 .build::<_, LineDelimited>(&mut buf);
48 writer
49 .write(batch)
50 .map_err(|e| SchemaError::DecodeError(format!("JSON encode error: {e}")))?;
51 writer
52 .finish()
53 .map_err(|e| SchemaError::DecodeError(format!("JSON finish error: {e}")))?;
54 }
55
56 let output: Vec<Vec<u8>> = buf
57 .split(|&b| b == b'\n')
58 .filter(|line| !line.is_empty())
59 .map(<[u8]>::to_vec)
60 .collect();
61
62 Ok(output)
63 }
64
65 fn format_name(&self) -> &'static str {
66 "json"
67 }
68}
69
70#[derive(Debug)]
72struct JsonbPassthroughFactory;
73
74impl EncoderFactory for JsonbPassthroughFactory {
75 fn make_default_encoder<'a>(
76 &self,
77 _field: &'a FieldRef,
78 array: &'a dyn Array,
79 _options: &'a EncoderOptions,
80 ) -> Result<Option<NullableEncoder<'a>>, ArrowError> {
81 if *array.data_type() != DataType::LargeBinary {
82 return Ok(None);
83 }
84 let binary_array = array.as_binary::<i64>();
85 let nulls = binary_array.nulls().cloned();
86 let encoder = LargeBinaryJsonbEncoder {
87 array: binary_array,
88 };
89 Ok(Some(NullableEncoder::new(Box::new(encoder), nulls)))
90 }
91}
92
93struct LargeBinaryJsonbEncoder<'a> {
94 array: &'a arrow_array::LargeBinaryArray,
95}
96
97impl Encoder for LargeBinaryJsonbEncoder<'_> {
98 fn encode(&mut self, idx: usize, out: &mut Vec<u8>) {
99 let bytes = self.array.value(idx);
100 if serde_json::from_slice::<serde_json::Value>(bytes).is_ok() {
101 out.extend_from_slice(bytes);
102 } else {
103 write!(out, "\"<binary:{} bytes>\"", bytes.len()).unwrap();
104 }
105 }
106}
107
108#[cfg(test)]
109mod tests;