Skip to content

Commit 451aefe

Browse files
committed
implementation of JSON.dump
1 parent eeab48d commit 451aefe

File tree

1 file changed

+97
-4
lines changed

1 file changed

+97
-4
lines changed

lib/json.bash

Lines changed: 97 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,117 @@ JSON.load() {
2222
:
2323
}
2424

25+
26+
JSON.style() {
27+
case $1 in
28+
minimal)
29+
JSON_INDENT=""
30+
JSON_FIELD_SEP=","
31+
JSON_KEY_SEP=":"
32+
JSON_ARR_BEGIN="["
33+
JSON_ARR_END="]"
34+
JSON_OBJ_BEGIN="{"
35+
JSON_OBJ_END="}"
36+
;;
37+
normal)
38+
JSON_INDENT=""
39+
JSON_FIELD_SEP=", "
40+
JSON_KEY_SEP=": "
41+
JSON_ARR_BEGIN="["
42+
JSON_ARR_END="]"
43+
JSON_OBJ_BEGIN="{"
44+
JSON_OBJ_END="}"
45+
;;
46+
pretty)
47+
JSON_INDENT="${2:- }"
48+
JSON_FIELD_SEP=$',\n'
49+
JSON_KEY_SEP=": "
50+
JSON_ARR_BEGIN=$'[\n'
51+
JSON_ARR_END=$'\nINDENT]'
52+
JSON_OBJ_BEGIN=$'{\n'
53+
JSON_OBJ_END=$'\nINDENT}'
54+
;;
55+
*) JSON.die 'Usage: JSON.style [minimal|normal|pretty [<indent-string>]]' ;;
56+
esac
57+
}
58+
JSON.style normal
59+
2560
JSON.dump() {
26-
JSON.die 'JSON.dump not yet implemented.'
2761
set -o pipefail
2862
case $# in
2963
0)
30-
JSON.normalize | sort | JSON.emit-json
64+
JSON._dump
3165
;;
3266
1)
3367
if [[ $1 == '-' ]]; then
34-
echo "$JSON__cache" | JSON.dump-json
68+
echo "$JSON__cache" | JSON.dump
3569
else
36-
echo ${!1} | JSON.dump-json
70+
echo "${!1}" | JSON.dump
3771
fi
3872
;;
3973
*) JSON.die 'Usage: JSON.dump [<tree-var>]' ;;
4074
esac
4175
}
4276

77+
JSON._indent() {
78+
[ "$1" -le 0 ] || printf "$JSON_INDENT%.0s" $(seq 1 "$1")
79+
}
80+
81+
JSON._dump() {
82+
local stack=()
83+
local prev=("/")
84+
local first=""
85+
while IFS=$'/\t' read -r -a line; do
86+
[ ${#line[@]} -gt 0 ] || continue
87+
last=$((${#line[@]}-1))
88+
val="${line[$last]}"
89+
unset line[$last]
90+
((last--))
91+
for i in ${!line[@]}; do
92+
[ "${prev[$i]}" != "${line[$i]}" ] || continue
93+
while [ $i -lt ${#stack} ]; do
94+
local type="${stack:0:1}"
95+
stack="${stack:1}"
96+
if [ "$type" = "a" ]; then
97+
echo -n "${JSON_ARR_END//INDENT/$(JSON._indent ${#stack})}"
98+
else
99+
echo -n "${JSON_OBJ_END//INDENT/$(JSON._indent ${#stack})}"
100+
fi
101+
done
102+
if [ $i -gt 0 ]; then
103+
if [ -z "$first" ]; then
104+
echo -n "$JSON_FIELD_SEP"
105+
else
106+
first="";
107+
fi
108+
echo -n "$(JSON._indent ${#stack})"
109+
[ "${stack:0:1}" = "a" ] || echo -n "\"${line[$i]}\"$JSON_KEY_SEP"
110+
fi
111+
if [ $i -eq $last ]; then
112+
echo -n "$val"
113+
else
114+
if [[ "${line[((i+1))]}" =~ [0-9]+ ]]; then
115+
stack="a$stack";
116+
echo -n "$JSON_ARR_BEGIN"
117+
else
118+
stack="o$stack";
119+
echo -n "$JSON_OBJ_BEGIN"
120+
fi
121+
first="1"
122+
fi
123+
done
124+
prev=("${line[@]}")
125+
done < <(sort -k1,1V -u; )
126+
for (( i=0; i<${#stack}; i++ )); do
127+
if [ "${stack:$i:1}" = "a" ]; then
128+
echo -n "${JSON_ARR_END//INDENT/$(JSON._indent $i)}"
129+
else
130+
echo -n "${JSON_OBJ_END//INDENT/$(JSON._indent $i)}"
131+
fi
132+
done
133+
echo
134+
}
135+
43136
JSON.get() {
44137
local flag=""
45138
if [[ $# -gt 0 && $1 =~ ^-([asnbz])$ ]]; then

0 commit comments

Comments
 (0)