Skip to content

Commit 20b13c8

Browse files
committed
refactor: Move parsing virtual object to own function
1 parent f86bb78 commit 20b13c8

File tree

3 files changed

+90
-64
lines changed

3 files changed

+90
-64
lines changed

pkg/lib/parse.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,43 @@ bash_object.parse_filter() {
170170
return 2
171171
fi
172172
}
173+
174+
# @description Parse a virtual object into its components
175+
bash_object.parse_virtual_object() {
176+
REPLY1=; REPLY2=
177+
local virtual_object="$1"
178+
179+
local virtual_metadatas="${virtual_object%%&*}" # type=string;attr=smthn;
180+
local virtual_object_name="${virtual_object#*&}" # __bash_object_383028
181+
182+
if [ -n "${TRACE_BASH_OBJECT_TRAVERSE+x}" ]; then
183+
stdtrace.log 2 "virtual_object: '$virtual_object'"
184+
stdtrace.log 2 "virtual_metadatas: '$virtual_metadatas'"
185+
stdtrace.log 2 "virtual_object_name: '$virtual_object_name'"
186+
fi
187+
188+
# Parse info about the virtual object
189+
local vmd_dtype=
190+
while IFS= read -rd \; vmd; do
191+
if [ -z "$vmd" ]; then
192+
continue
193+
fi
194+
195+
vmd="${vmd%;}"
196+
vmd_key="${vmd%%=*}"
197+
vmd_value="${vmd#*=}"
198+
199+
if [ -n "${TRACE_BASH_OBJECT_TRAVERSE+x}" ]; then
200+
stdtrace.log 2 "vmd: '$vmd'"
201+
stdtrace.log 3 "vmd_key: '$vmd_key'"
202+
stdtrace.log 3 "vmd_value: '$vmd_value'"
203+
fi
204+
205+
case "$vmd_key" in
206+
type) vmd_dtype="$vmd_value" ;;
207+
esac
208+
done <<< "$virtual_metadatas"
209+
210+
REPLY1="$virtual_object_name"
211+
REPLY2="$vmd_dtype"
212+
}

pkg/lib/traverse.sh

Lines changed: 41 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -80,38 +80,11 @@ bash_object.traverse() {
8080
# This means we will be setting either an object or an array
8181
if [ "${key_value::2}" = $'\x1C\x1D' ]; then
8282
virtual_item="${key_value#??}"
83-
local virtual_metadatas="${virtual_item%%&*}" # type=string;attr=smthn;
84-
local current_object_name="${virtual_item#*&}" # __bash_object_383028
85-
local -n current_object="$current_object_name"
86-
87-
if [ -n "${TRACE_BASH_OBJECT_TRAVERSE+x}" ]; then
88-
stdtrace.log 2 "BLOCK: OBJECT/ARRAY"
89-
stdtrace.log 2 "virtual_item: '$virtual_item'"
90-
stdtrace.log 2 "virtual_metadatas: '$virtual_metadatas'"
91-
stdtrace.log 2 "current_object_name: '$current_object_name'"
92-
fi
93-
94-
# Parse info about the virtual object
95-
local vmd_dtype=
96-
while IFS= read -rd \; vmd; do
97-
if [ -z "$vmd" ]; then
98-
continue
99-
fi
100-
101-
vmd="${vmd%;}"
102-
vmd_key="${vmd%%=*}"
103-
vmd_value="${vmd#*=}"
10483

105-
if [ -n "${TRACE_BASH_OBJECT_TRAVERSE+x}" ]; then
106-
stdtrace.log 2 "vmd: '$vmd'"
107-
stdtrace.log 3 "vmd_key: '$vmd_key'"
108-
stdtrace.log 3 "vmd_value: '$vmd_value'"
109-
fi
110-
111-
case "$vmd_key" in
112-
type) vmd_dtype="$vmd_value" ;;
113-
esac
114-
done <<< "$virtual_metadatas"
84+
bash_object.parse_virtual_object "$virtual_item"
85+
local current_object_name="$REPLY1"
86+
local vmd_dtype="$REPLY2"
87+
local -n current_object="$current_object_name"
11588

11689
# If we are not on the last element of the query, then do nothing. We have
11790
# already set 'current_object_name' and 'current_object', so at the next loop
@@ -159,16 +132,15 @@ bash_object.traverse() {
159132
fi
160133
fi
161134
else
162-
# If we are getting a single string
135+
# If we are getting a string
163136

164137
if [ -n "${TRACE_BASH_OBJECT_TRAVERSE+x}" ]; then
165138
stdtrace.log 2 "BLOCK: STRING"
166139
fi
167140

168-
# If we are less than the last element in the query, and the object
169-
# member has a type of 'string', throw an error. This means the
170-
# user expected an object to have a key with type 'object', but the
171-
# type really is 'string'
141+
# If we are less than the last element in the query, and the object member has a type
142+
# of 'string', throw an error. This means the user expected an object to have a key
143+
# with type 'object', but the type really is 'string'
172144
if ((i+1 < ${#REPLIES[@]})); then
173145
:
174146
elif ((i+1 == ${#REPLIES[@]})); then
@@ -199,29 +171,43 @@ bash_object.traverse() {
199171

200172

201173
elif [ "$action" = 'set' ]; then
202-
# If we are before the last element in the query
203-
if ((i+1 < ${#REPLIES[@]})); then
204-
# The variable is 'new_current_object_name', but it also could
205-
# be the name of a new _array_
206-
local new_current_object_name="__bash_object_${root_object_name}_tree_${key}_${RANDOM}_${RANDOM}_${RANDOM}_${RANDOM}_${RANDOM}"
174+
# If 'key' is not a member of object, create the object, and set it
175+
if [ -z "${current_object["$key"]+x}" ]; then
176+
# If we are before the last element in the query, then set
177+
if ((i+1 < ${#REPLIES[@]})); then
178+
# The variable is 'new_current_object_name', but it also could
179+
# be the name of a new _array_
180+
local new_current_object_name="__bash_object_${root_object_name}_tree_${key}_${RANDOM}_${RANDOM}_${RANDOM}_${RANDOM}_${RANDOM}"
207181

208-
# TODO: double-check if new_current_object_name only has underscores, dots, etc. (printf %q?)
182+
# TODO: double-check if new_current_object_name only has underscores, dots, etc. (printf %q?)
209183

210-
if ! eval "declare -gA $new_current_object_name=()"; then
211-
printf '%s\n' 'Error: bash-object: eval declare failed'
212-
exit 1
213-
fi
214-
# local -n new_current_object="$new_current_object_name"
184+
if ! eval "declare -gA $new_current_object_name=()"; then
185+
printf '%s\n' 'Error: bash-object: eval declare failed'
186+
exit 1
187+
fi
188+
# local -n new_current_object="$new_current_object_name"
215189

216-
current_object["$key"]=$'\x1C\x1D'"type=object;&$new_current_object_name"
190+
current_object["$key"]=$'\x1C\x1D'"type=object;&$new_current_object_name"
191+
192+
current_object_name="$new_current_object_name"
193+
# shellcheck disable=SC2178
194+
local -n current_object="$new_current_object_name"
195+
# If we are at the last element in the query
196+
elif ((i+1 == ${#REPLIES[@]})); then
197+
# TODO: object, arrays
198+
current_object["$key"]="$final_value"
199+
fi
200+
# If 'key' is already a member of object, use it if it's a virtual object. If
201+
# it's not a virtual object, then a throw an error
202+
else
203+
local key_value="${current_object["$key"]}"
217204

218-
current_object_name="$new_current_object_name"
219-
# shellcheck disable=SC2178
220-
local -n current_object="$new_current_object_name"
221-
# If we are at the last element in the query
222-
elif ((i+1 == ${#REPLIES[@]})); then
223-
# TODO: object, arrays
224-
current_object["$key"]="$final_value"
205+
if [ "${key_value::2}" = $'\x1C\x1D' ]; then
206+
:
207+
else
208+
# TODO: throw error
209+
:
210+
fi
225211
fi
226212

227213
if [ -n "${TRACE_BASH_OBJECT_TRAVERSE+x}" ]; then

tests/set-string.bats

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ load './util/init.sh'
1212
assert [ "$REPLY" = 'my_value' ]
1313
}
1414

15-
# @test "properly sets 2" {
16-
# declare -A OBJ=()
15+
@test "properly sets 2" {
16+
declare -A OBJ=()
1717

18-
# bash_object.traverse set string 'OBJ' '.xray.yankee.zulu' 'boson'
19-
# bash_object.traverse set string 'OBJ' '.xray.yankee' 'lithography'
18+
bash_object.traverse set string 'OBJ' '.xray.yankee.zulu' 'boson'
19+
bash_object.traverse set string 'OBJ' '.xray.yankee.alfa' 'lithography'
2020

21-
# bash_object.traverse get string 'OBJ' '.xray.yankee.zulu'
22-
# assert [ "$REPLY" = 'boson' ]
21+
bash_object.traverse get string 'OBJ' '.xray.yankee.zulu'
22+
assert [ "$REPLY" = 'boson' ]
2323

24-
# # bash_object.traverse get string 'OBJ' '.xray.yankee'
25-
# # assert [ "$REPLY" = 'lithography' ]
26-
# }
24+
bash_object.traverse get string 'OBJ' '.xray.yankee.alfa'
25+
assert [ "$REPLY" = 'lithography' ]
26+
}

0 commit comments

Comments
 (0)