1pub mod encoders;
2pub mod folding;
3pub mod normalize;
4pub mod primitives;
5pub mod replacer;
6
7#[cfg(feature = "async-stream")]
8pub mod async_encode;
9
10#[cfg(feature = "async-stream")]
11pub use async_encode::{
12 AsyncEncodeEventStream, AsyncEncodeStream, encode_async, encode_events_async,
13 encode_lines_async,
14};
15
16use crate::encode::normalize::normalize_json_value;
17use crate::encode::replacer::apply_replacer;
18use crate::options::{EncodeOptions, resolve_encode_options};
19use crate::shared::validation::is_valid_unquoted_key;
20use crate::{JsonStreamEvent, JsonValue};
21
22pub fn encode(input: impl Into<JsonValue>, options: Option<EncodeOptions>) -> String {
23 let lines = encode_lines(input, options);
24 lines.join("\n")
25}
26
27pub fn encode_lines(input: impl Into<JsonValue>, options: Option<EncodeOptions>) -> Vec<String> {
28 let resolved = resolve_encode_options(options);
29 let normalized = normalize_json_value(input.into());
30 let replaced = if let Some(replacer) = &resolved.replacer {
31 apply_replacer(&normalized, replacer)
32 } else {
33 normalized
34 };
35 encoders::encode_json_value(&replaced, &resolved)
36}
37
38#[must_use]
43pub fn encode_stream_events(
44 input: impl Into<JsonValue>,
45 options: Option<EncodeOptions>,
46) -> Vec<JsonStreamEvent> {
47 let resolved = resolve_encode_options(options);
48 let normalized = normalize_json_value(input.into());
49 let replaced = if let Some(replacer) = &resolved.replacer {
50 apply_replacer(&normalized, replacer)
51 } else {
52 normalized
53 };
54
55 let mut events = Vec::new();
56 emit_events(&replaced, &mut events);
57 events
58}
59
60fn emit_events(value: &JsonValue, events: &mut Vec<JsonStreamEvent>) {
61 match value {
62 JsonValue::Primitive(p) => {
63 events.push(JsonStreamEvent::Primitive { value: p.clone() });
64 }
65 JsonValue::Array(arr) => {
66 events.push(JsonStreamEvent::StartArray { length: arr.len() });
67 for item in arr {
68 emit_events(item, events);
69 }
70 events.push(JsonStreamEvent::EndArray);
71 }
72 JsonValue::Object(obj) => {
73 events.push(JsonStreamEvent::StartObject);
74 for (key, val) in obj {
75 events.push(JsonStreamEvent::Key {
76 key: key.clone(),
77 was_quoted: !is_valid_unquoted_key(key),
78 });
79 emit_events(val, events);
80 }
81 events.push(JsonStreamEvent::EndObject);
82 }
83 }
84}