#!/bin/bash
# input - Command line input helpers
set -e
######
# Config
mcui_input_config_init() {
lib_setting_vars prompt_allow_empty
prompt_allow_empty=true
}
######
# Value parsing functions
# These functions all have the same interface.
#
# Upon return, a valid value will be stored in the named variable;
# if the value was not valid, the function raises an error.
# parse_int - Parse a string as an integer
# $1 - raw value to parse
# $2 - variable name
parse_int() {
has_args 2 "$@"
case "$1" in
[0-9]*) eval $2=$(printf "%d" "$1") ;;
*) false ;;
esac
}
# parse_bool - Parse a string as a boolean
# $1 - raw value to parse
# $2 - variable name
parse_bool() {
has_args 2 "$@"
case "$1" in
t|T|true|True|TRUE) eval "$2=true" ;;
f|F|false|False|FALSE) eval "$2=false" ;;
*) false ;;
esac
}
# parse_yesno - Parse a string as a yes or no answer
# $1 - raw value to parse
# $2 - variable name
parse_yesno() {
has_args 2 "$@"
case "$1" in
y|yes|Y|YES) eval "$2=true" ;;
n|no|N|NO) eval "$2=false" ;;
*) false ;;
esac
}
# parse_yesnocancel - Parse a string as a yes, no, or cancel answer
# $1 - raw value to parse
# $2 - variable name
parse_yesnocancel() {
has_args 2 "$@"
case "$1" in
c|cancel|C|CANCEL) eval "$2=" ;;
*) parse_yesno "$@" ;;
esac
}
# parse_onoff - Parse a string as an on or off answer
# $1 - raw value to parse
# $2 - variable name
parse_onoff() {
has_args 2 "$@"
case "$1" in
on|On|ON) eval "$2=true" ;;
off|Off|OFF) eval "$2=false" ;;
*) false ;;
esac
}
######
# Input helpers
# read_string - Interactively reads a string into a variable
# $1 - prompt
# $2 - target variable
read_string() {
has_args 2 "$@"
run read -p "$1" -e $2
}
# read_silent - Same as read_string, but does not echo input.
read_silent() {
has_args 2 "$@"
run read -s -p "$1" -e $2
}
# read_and_parse - Reads a string and parses it into a typed variable
# $1 - name of parser function
# $2 - prompt
# $3 - target variable
read_and_parse() {
min_args 3 "$@"
local parser=$1
local prompt=$2
local outvar=$3
local _line
local linevar=${4:-_line}
read_string "$prompt" $linevar
local -n line=$linevar
$parser "$line" "$outvar"
}
read_int() { read_and_parse parse_int "$@"; }
read_bool() { read_and_parse parse_bool "$@"; }
read_yesno() { read_and_parse parse_yesno "$@"; }
read_yesnocancel() { read_and_parse parse_yesnocancel "$@"; }
read_onoff() { read_and_parse parse_onoff "$@"; }
######
# Prompt input
prompt_newline() { local x; read_string "Press <enter> to continue..." x; }
prompt_error() { error "$1" || prompt_newline; }
prompt_warn() { warn "$1" && prompt_newline; }
prompt_info() { app_echo "INFO: $1" && prompt_newline; }
prompt_for() {
has_args 3 "$@"
local raw
while ! read_and_parse "$@" raw; do
if [ -z "$raw" ]; then
! $prompt_allow_empty || return 0
else
! error "'$raw' is not a valid response"
fi
done
}
prompt_int() { prompt_for parse_int "$@"; }
prompt_bool() { prompt_for parse_bool "$@"; }
prompt_yesno() { prompt_for parse_yesno "$@"; }
prompt_yesnocancel() { prompt_for parse_yesnocancel "$@"; }
prompt_onoff() { prompt_for parse_onoff "$@"; }
######
# Input validation
# assert_parse - Asserts variable ($2) is type ($1) or prints error ($3)
# $1 - parsing type, used to derive parsing function (e.g. 'parse_int')
# $2 - name of variable
# $3 - error to display if assertion fails
assert_parse() {
has_args 3 "$@"
local _ptype=$1
local _var=$2
local _error=$3
local _pfunc="parse_$_ptype"
local _value
eval "_value=\"\$$_var\""
assert "$_var: '$_value' not a $_ptype: $_error" \
"$_pfunc" "$_value" "$_var"
}
# assert_parse_list - Asserts values ($...) are type ($1) or prints error ($2)
assert_parse_list() {
min_args 2 "$@"
local _ptype=$1
local _error=$2
shift 2
for_each "_assert_parse_list $_ptype $_error" "$@";
}
# $1 - $ptype, $2 - $error, $3 - $var
_assert_parse_list() { assert_parse "$1" "$3" "$2"; }
assert_is_int() { assert_parse_list int "$@"; }
assert_is_bool() { assert_parse_list bool "$@"; }
assert_is_yesno() { assert_parse_list yesno "$@"; }
assert_is_onoff() { assert_parse_list onoff "$@"; }
######
# Library testing
check_is_input_valid() {
has_args 2 "$@"
local _type=$1
local _var=$2
local -a _cmd=( assert_is_${_type} failed $_var )
check_for_pass "checking $_var is a $_type" "${_cmd[@]}"
}
check_is_input_invalid() {
has_args 2 "$@"
local _type=$1
local _var=$2
local -a _cmd=( assert_is_${_type} failed $_var )
check_for_fail "checking $_var is not a $_type" "${_cmd[@]}"
}
mcui_input_lib_check() {
check_list_start
local testvar=123
check_is_input_valid int testvar
check_is_expected testvar 123
testvar=0000
check_is_input_valid int testvar
check_is_expected testvar 0
testvar=abc
check_is_input_invalid int testvar
check_list_finish
}
Generated on Tue Jul 4 17:00:50 PDT 2017 by mcsh d14 v0.21.0.