1use crate::cli::json_stream::json_stream_from_events;
2use crate::cli::json_stringify::json_stringify_lines;
3use crate::decode::decoders as decoder_impl;
4use crate::decode::event_builder::{build_node_from_events, node_to_json};
5use crate::decode::expand::expand_paths_safe;
6use crate::error::{Result, ToonError};
7use crate::options::{
8 DecodeOptions, DecodeStreamOptions, EncodeOptions, ExpandPathsMode, resolve_decode_options,
9};
10use crate::{JsonValue, StringOrNumberOrBoolOrNull};
11
12pub fn encode_to_toon_lines(
18 input_json: &str,
19 options: Option<EncodeOptions>,
20) -> Result<Vec<String>> {
21 let value: serde_json::Value =
22 serde_json::from_str(input_json).map_err(|err| ToonError::json_parse(&err))?;
23 let converted = JsonValue::from(value);
24 Ok(crate::encode::encode_lines(converted, options))
25}
26
27pub fn decode_to_json_chunks(input: &str, options: Option<DecodeOptions>) -> Result<Vec<String>> {
33 let resolved = resolve_decode_options(options);
34
35 if resolved.expand_paths == ExpandPathsMode::Safe {
36 let value = decode_to_value(input, &resolved)?;
37 return Ok(json_stringify_lines(&value, resolved.indent));
38 }
39
40 let events = decode_events(input, resolved.indent, resolved.strict)?;
41 json_stream_from_events(events, resolved.indent)
42}
43
44fn decode_events(input: &str, indent: usize, strict: bool) -> Result<Vec<crate::JsonStreamEvent>> {
45 let lines = input
46 .split('\n')
47 .map(std::string::ToString::to_string)
48 .collect::<Vec<_>>();
49
50 decoder_impl::decode_stream_sync(
51 lines,
52 Some(DecodeStreamOptions {
53 indent: Some(indent),
54 strict: Some(strict),
55 }),
56 )
57}
58
59fn decode_to_value(
60 input: &str,
61 options: &crate::options::ResolvedDecodeOptions,
62) -> Result<JsonValue> {
63 let events = decode_events(input, options.indent, options.strict)?;
64 let mut node = build_node_from_events(events)?;
65
66 if options.expand_paths == ExpandPathsMode::Safe {
67 node = expand_paths_safe(node, options.strict)?;
68 }
69
70 Ok(node_to_json(node))
71}
72
73#[must_use]
74pub fn json_stringify_null(indent: usize) -> Vec<String> {
75 json_stringify_lines(
76 &JsonValue::Primitive(StringOrNumberOrBoolOrNull::Null),
77 indent,
78 )
79}