go-calc/calc/cli/functions.go

230 lines
4.5 KiB
Go
Raw Normal View History

2024-02-21 10:42:56 +00:00
package cli
import (
"errors"
"fmt"
"os"
"strings"
"gitea.zaclys.com/bvaudour/gob/option"
"gitea.zaclys.net/bvaudour/calc/calc"
)
type integer interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
}
type CliFunc func(*Cli) option.Option[error]
type WordCliFunc func(string) CliFunc
func stack2Str(numbers calc.Stack) string {
sl := make([]string, len(numbers))
for i, n := range numbers {
sl[i] = n.String()
}
return strings.Join(sl, " ")
}
func printResult(arg any) (result option.Option[error]) {
if _, e := fmt.Printf("\033[1;33m%s\033[m\n", arg); e != nil {
result = option.Some(e)
}
return
}
func printError(err error) (result option.Option[error]) {
if _, e := fmt.Printf("\033[1;31m%s\033[m\n", err); e != nil {
result = option.Some(e)
}
return
}
func printLine(k string, arg any) (result option.Option[error]) {
if _, e := fmt.Printf("\033[1;32m%s\033[m → \033[1;33m%s\033[m\n", k, arg); e != nil {
result = option.Some(e)
}
return
}
func printHelp() (result option.Option[error]) {
if _, e := fmt.Print(help); e != nil {
result = option.Some(e)
}
return
}
func printOption(c *calc.Calc) option.Option[error] {
p, f := c.Precision()
t := "auto"
if f {
t = "fixe"
}
return printResult(fmt.Sprintf("%d (%s)", p, t))
}
func printLast(c *calc.Calc) (err option.Option[error]) {
result := c.Last()
if n, ok := result.Ok(); ok {
err = printResult(n)
} else if e, ok := result.Err(); ok {
err = option.Some(e)
}
return
}
func printStack(c *calc.Calc) (err option.Option[error]) {
result := c.GetStack()
if s, ok := result.Ok(); ok {
err = printResult(stack2Str(s))
} else if e, ok := result.Err(); ok {
err = option.Some(e)
}
return
}
func printRegistries(c *calc.Calc) (err option.Option[error]) {
result := c.GetRegistries()
if r, ok := result.Ok(); ok {
for k, s := range r {
printLine(k, stack2Str(s))
}
} else if e, ok := result.Err(); ok {
err = option.Some(e)
}
return
}
func printRegistry(k string) calc.CalcFunc {
return func(c *calc.Calc) (err option.Option[error]) {
result := c.Registry(k)
if s, ok := result.Ok(); ok {
err = printResult(stack2Str(s))
} else if e, ok := result.Err(); ok {
err = option.Some(e)
}
return
}
}
func printMacros(c *Cli) (err option.Option[error]) {
result := c.c.GetMacros()
if e, ok := result.Err(); ok {
err = option.Some(e)
} else {
for k, m := range c.macros {
printLine(k, m)
}
}
return
}
func printMacro(k string) CliFunc {
return func(c *Cli) (err option.Option[error]) {
result := c.c.Macro(k)
if e, ok := result.Err(); ok {
err = option.Some(e)
} else {
err = printResult(c.macros[k])
}
return
}
}
func resetMacro(k string) CliFunc {
return func(c *Cli) option.Option[error] {
return c.removeMacro(k)
}
}
func storeMacro(k string) CliFunc {
return func(c *Cli) option.Option[error] {
return c.endMacro(k)
}
}
func addMacro(v string) CliFunc {
return func(c *Cli) option.Option[error] {
return c.addMacro(v)
}
}
func setPrecision(c *calc.Calc, precision option.Option[uint64], fix bool) (err option.Option[error]) {
c.SetPrecision(precision, option.Some(fix))
return
}
func fixPrecision(fix bool) calc.CalcFunc {
return func(c *calc.Calc) (err option.Option[error]) {
return setPrecision(c, option.None[uint64](), fix)
}
}
func precision[N integer](fix bool) calc.IntCalcFunc[N] {
return func(args ...N) calc.CalcFunc {
return func(c *calc.Calc) (err option.Option[error]) {
var p option.Option[uint64]
if len(args) > 1 {
p = option.Some(uint64(args[0]))
}
return setPrecision(c, p, fix)
}
}
}
func beginMacro(c *Cli) option.Option[error] {
return c.beginMacro()
}
func conditional(c *Cli) option.Option[error] {
return c.beginAlt()
}
func addConditional(v string) CliFunc {
return func(c *Cli) option.Option[error] {
return c.addAlt(v)
}
}
func quit() (err option.Option[error]) {
os.Exit(0)
return
}
func execMacro(k string) calc.CalcFunc {
return func(c *calc.Calc) (err option.Option[error]) {
errs := c.ExecMacro(k)
if len(errs) > 0 {
sErrors := make([]string, len(errs))
for i, e := range errs {
sErrors[i] = e.Error()
}
err = option.Some(errors.New(strings.Join(sErrors, "\n")))
}
return
}
}
func cliToCalcFunc(c *Cli, cb CliFunc) calc.CalcFunc {
return func(_ *calc.Calc) option.Option[error] {
return cb(c)
}
}
func otherToCalcFunc(cb func() option.Option[error]) calc.CalcFunc {
return func(_ *calc.Calc) option.Option[error] {
return cb()
}
}