Last active
April 20, 2023 03:02
-
-
Save flisboac/d1613d4f02644525a58cf8baab901c0f to your computer and use it in GitHub Desktop.
Various slow-ish portable Shell utilities for JSON values (all depending on `jq`)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
## | |
# Sets properties in a JSON object. | |
# | |
# Properties are given in the format `KEY[:TYPE]=VALUE`, as a var-arg argument to the function. | |
# `TYPE` is optional; if not provided, the value will be simply serialized to string, regardless | |
# of its format. But if a type is informed, some conversion and validation occurs prior to | |
# assignment. Type names are case insensitive. Accepted types: | |
# | |
# - `boolean` (aliases: `bool`); | |
# - `integer` (aliases: `int`); | |
# - `number` (aliases: `num`); | |
# - `array`; | |
# - `object` (aliases: `obj`); | |
# - `json`. | |
# | |
# No variable substitution is performed on `VALUE`, but you can use the shell's own | |
# interpolation to your advantage. | |
# | |
# Examples: | |
# $ util_JsonObject_set {} \ | |
# appName="${APP_NAME}" \ | |
# debug:bool="${APP_DEBUG:-"$([ "${ENV}"!="prod" ]; echo "$?")"}" \ | |
# timeout:int="${APP_TIMEOUT:-120}" | |
# | |
# @usage $0 OBJ [ASSIGN...] | |
# @param OBJ The object to which properties will be added. | |
# @param ASSIGN The property assignment to perform. | |
# | |
util_JsonObject_set() ( | |
set -e | |
local __obj="${1}"; shift | |
local __name_type | |
local __name | |
local __type | |
local __value | |
if [ "${__obj}"=="-" ]; then | |
__obj="$(cat)" | |
fi | |
while [ "$#" -gt 0 ]; do | |
__name_type="${1%%=*}" | |
__value="${1#*=}" | |
__name="$(printf '%s\n' "$__name_type" | cut -d: -f1)" | |
__type="$(printf '%s\n' "$__name_type" | cut -d: -f2 -s | tr '[:upper:]' '[:lower:]')" | |
shift | |
printf '** %s: %s = %s\n' "$__name" "$__type" "$__value" | |
__name="$(printf '%s\n' "$__name" | jq -R --indent 0 ". | tostring")" | |
if [ -z "$__type" ]; then | |
__value="$(printf '%s' "$__value" | jq --indent 0 -R ". | tostring")" ;; | |
else | |
case "$__type" in | |
int|integer) | |
__value="$(printf '%s' "$__value" | jq --indent 0 -R '. | tonumber | floor')" ;; | |
num|number) | |
__value="$(printf '%s' "$__value" | jq --indent 0 -R '. | tonumber')" ;; | |
bool|boolean) | |
__value="$(printf '%s' "$__value" | jq --indent 0 -R '. | if test("false|f|no|n|off|0";"i") then false elif test("true|t|yes|y|on|1";"i") then true else error("value is not boolean-like") end')" ;; | |
array) | |
__value="$(printf '%s' "$__value" | jq --indent 0 '. | if type=="array" then . else error("value should be an array") end')" ;; | |
obj|object) | |
__value="$(printf '%s' "$__value" | jq --indent 0 '. | if type=="object" then . else error("value should be an object") end')" ;; | |
json) | |
__value="$(printf '%s' "$__value" | jq --indent 0 '.')" ;; | |
*) | |
printf 'Unknown declared type "%s" in property "%s".\n' "$__type" "$__name" ;; | |
esac | |
fi | |
__obj="$(printf '%s\n' "${__obj}" | jq "$(printf '. += {%s: %s}' "${__name}" "${__value}")")" | |
done | |
printf '%s\n' "${__obj}" | |
) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment