1use crate::serde::byte_keys_as_strings;
7use crate::serde::bytes_as_string;
8use crate::value::Value;
9use crate::value::error::Error;
10use crate::value::list::List;
11use crate::value::map::Map;
12use indexmap::IndexMap;
13use serde::Serialize;
14
15pub fn json(value: Value) -> Result<Vec<u8>, Error> {
16 serde_json::to_vec(&Strategy::new(value)).map_err(|e| Error::Format(e.to_string()))
17}
18
19pub fn json_pretty(value: Value) -> Result<Vec<u8>, Error> {
20 serde_json::to_vec_pretty(&Strategy::new(value)).map_err(|e| Error::Format(e.to_string()))
21}
22
23pub fn json_string(value: Value) -> Result<String, Error> {
24 serde_json::to_string(&Strategy::new(value)).map_err(|e| Error::Format(e.to_string()))
25}
26
27pub fn json_string_pretty(value: Value) -> Result<String, Error> {
28 serde_json::to_string_pretty(&Strategy::new(value)).map_err(|e| Error::Format(e.to_string()))
29}
30
31pub fn yaml(value: Value) -> Result<String, Error> {
32 serde_yaml::to_string(&Strategy::new(value)).map_err(|e| Error::Format(e.to_string()))
33}
34
35#[derive(Serialize)]
36#[serde(untagged)]
37enum Strategy {
38 Default(Box<Value>),
39 Simple(Simple),
40}
41
42impl Strategy {
43 fn new(value: Value) -> Strategy {
44 match value.meta().get(b"internal-serialize") == Some(b"simple") {
45 true => Strategy::Simple(Simple::new(value)),
46 false => Strategy::Default(Box::new(value)),
47 }
48 }
49}
50
51#[derive(Serialize)]
52#[serde(untagged)]
53enum Simple {
54 Bytes(SimpleBytes),
55 List(SimpleList),
56 Map(SimpleMap),
57}
58
59impl Simple {
60 fn new(value: Value) -> Self {
61 match value {
62 Value::List(v) if should_concat(&value) => Simple::Bytes(SimpleBytes(v.join())),
63 Value::Map(v) if should_concat(&value) => Simple::Bytes(SimpleBytes(v.join())),
64 Value::Bytes(v) => Simple::Bytes(SimpleBytes(v.join())),
65 Value::List(v) => Simple::List(SimpleList::new(v)),
66 Value::Map(v) => Simple::Map(SimpleMap::new(v)),
67 }
68 }
69}
70
71#[derive(Serialize)]
72struct SimpleBytes(#[serde(with = "bytes_as_string")] Vec<u8>);
73
74#[derive(Serialize)]
75struct SimpleList(Vec<Simple>);
76
77impl SimpleList {
78 fn new(value: List) -> Self {
79 SimpleList(value.data.into_iter().map(Simple::new).collect())
80 }
81}
82
83#[derive(Serialize)]
84pub(crate) struct SimpleMap(
85 #[serde(with = "byte_keys_as_strings")] IndexMap<Vec<u8>, Simple, ahash::RandomState>,
86);
87
88impl SimpleMap {
89 fn new(value: Map) -> Self {
90 SimpleMap(
91 value
92 .data
93 .into_iter()
94 .map(|(k, v)| (k, Simple::new(v)))
95 .collect(),
96 )
97 }
98}
99
100fn should_concat(value: &Value) -> bool {
101 value.meta().get(b"internal-format") == Some(b"concat")
102}