use crate::JSON_SCHEMA_VERSION;
use crate::options::{DecodeOptions, ZonedEncodingFormat};
use copybook_core::Schema;
use serde_json::Value;
fn flatten_fields_into(
source: &serde_json::Map<String, Value>,
target: &mut serde_json::Map<String, Value>,
) {
for (key, value) in source {
if let Value::Object(nested) = value {
flatten_fields_into(nested, target);
} else {
target.insert(key.clone(), value.clone());
}
}
}
pub(super) fn build_json_envelope(
fields: serde_json::Map<String, Value>,
schema: &Schema,
options: &DecodeOptions,
record_index: u64,
record_length: usize,
raw_b64: Option<String>,
encoding_metadata: Vec<(String, ZonedEncodingFormat)>,
) -> Value {
let mut root = serde_json::Map::new();
root.insert(
String::from("schema"),
Value::String(JSON_SCHEMA_VERSION.into()),
);
root.insert(
String::from("record_index"),
Value::Number(serde_json::Number::from(record_index)),
);
let codepage = options.codepage.to_string();
root.insert(String::from("codepage"), Value::String(codepage));
flatten_fields_into(&fields, &mut root);
root.insert(String::from("fields"), Value::Object(fields));
if options.emit_meta {
if !schema.fingerprint.is_empty() {
root.insert(
String::from("schema_fingerprint"),
Value::String(schema.fingerprint.clone()),
);
root.insert(
String::from("__schema_id"),
Value::String(schema.fingerprint.clone()),
);
}
root.insert(
String::from("length"),
Value::Number(serde_json::Number::from(record_length)),
);
root.insert(
String::from("__record_index"),
Value::Number(serde_json::Number::from(record_index)),
);
root.insert(
String::from("__length"),
Value::Number(serde_json::Number::from(record_length)),
);
}
if let Some(raw) = raw_b64 {
root.insert(String::from("raw_b64"), Value::String(raw.clone()));
root.insert(String::from("__raw_b64"), Value::String(raw));
}
if options.preserve_zoned_encoding && !encoding_metadata.is_empty() {
let mut meta_map = serde_json::Map::new();
for (field_name, format) in encoding_metadata {
let format_text = format.to_string();
meta_map.insert(field_name, Value::String(format_text));
}
root.insert(String::from("_encoding_metadata"), Value::Object(meta_map));
}
Value::Object(root)
}