syndicate-sh/lib/syndicate.sh

109 lines
2.3 KiB
Bash
Raw Normal View History

2021-08-13 01:08:50 +00:00
#!/bin/bash
2021-08-19 23:28:17 +00:00
set -euo pipefail
2021-08-13 01:08:50 +00:00
ds_handle=0
ds_buf=""
declare -A ds_handles
declare -A ds_handle_oids
declare -A ds_object_map
declare -A ds_retraction_handlers
ds_project() {
# cargo install preserves-tools
local input="$1"
local selector="$2"
shift 2
echo "$input" | preserves-tool convert --indent=no --select "$selector" "$@"
}
ds_connect_stdio() {
eval "$1"
exec 5<&0 6>&1
ds_flush
ds_mainloop
2021-08-13 01:08:50 +00:00
}
ds_connect() {
local addr=$1
case $(ds_project "$addr" ".^") in
tcp) nc_args="$(ds_project "$addr" ". 0" --output-format=unquoted) $(ds_project "$addr" ". 1")";;
unix) nc_args="-U $(ds_project "$addr" ". 0" --output-format=unquoted)";;
stdio) ds_connect_stdio "$2"; return;;
*) echo "ds_connect: address '$addr' not supported"; return 1;;
esac
2021-08-13 01:08:50 +00:00
local f=$(mktemp -u /tmp/ds.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX)
mkfifo $f
trap "rm -f $f" 2 EXIT RETURN
{
eval "$2"
2021-08-13 01:08:50 +00:00
ds_flush
ds_mainloop
} 5< <(nc $nc_args <$f) 6>$f
2021-08-13 01:08:50 +00:00
}
ds_send() {
echo "$@" >&6
# echo "SENDING: $@"
}
ds_mainloop() {
while read ds_packet
do
# echo "RECEIVING: $ds_packet"
while read ds_turnevent
do
ds_dispatch "$(ds_project "$ds_turnevent" '. 0')" "$(ds_project "$ds_turnevent" '. 1')"
done < <(ds_project "$ds_packet" 'seq /')
ds_flush
done <&5
}
ds_dispatch() {
ds_event="$2"
eval "${ds_object_map[$1]}"
}
ds_action() {
case $(ds_project "$1" '.embedded . 0') in
0) ds_dispatch "$(ds_project "$1" '.embedded . 1')" "$2" ;;
1) ds_buf="${ds_buf}[$(ds_project "$1" '.embedded . 1') $2]" ;;
esac
}
ds_flush() {
if [ -n "$ds_buf" ]
then
ds_send "[$ds_buf]"
ds_buf=""
fi
}
ds_assert() {
local h="$ds_handle"
ds_handle=$(($ds_handle + 1))
ds_action "$1" "<assert $2 $h>"
2021-08-19 23:28:17 +00:00
if [ -n "${3:-}" ]
2021-08-13 01:08:50 +00:00
then
ds_handle_oids[$3]="$1"
ds_handles[$3]="$h"
fi
}
ds_retract() {
ds_action "${ds_handle_oids[$1]}" "<retract ${ds_handles[$1]}>"
}
ds_message() {
ds_action "$1" "<message $2>"
}
ds_object() {
local oid="$ds_handle"
ds_handle=$(($ds_handle + 1))
ds_object_map[$oid]="$2"
printf -v $1 '%s' "#![0,$oid]"
}