dialog

package module
v0.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 7, 2023 License: MIT Imports: 15 Imported by: 4

README

dialog

cross plattform commandline dialogs.

Features

The library is organized in screens. The following types of screens are available:

  • input
  • password
  • select
  • multiselect
  • output
  • error

There is also support for input validation.

Example

package main

import (
	"gitlab.com/golang-utils/dialog"
	"fmt"
	"os"
	"strings"
	"time"

	"gitlab.com/golang-utils/fmtdate"
)

func main() {
	err := run()

	if err != nil {
		fmt.Fprintf(os.Stderr, "ERROR: %s\n", err.Error())
		os.Exit(1)
	}

	os.Exit(0)
}

func run() error {
	return NewApp().Run()
}

func NewApp() *App {
	var opts []dialog.Option

	opts = append(opts,
		dialog.WithBackNavigation(),
		dialog.WithFooter(),
		dialog.WithHeader(),
		dialog.WithBreadcrumb(),
	)

	a := &App{}

	a.app = dialog.New("Person", opts...)
	return a
}

type Data struct {
	Firstname string
	Lastname  string
	Password  string
	Birthday  string
	Male      bool
	Pets      []string
	Number    string
}

type App struct {
	app  dialog.App
	Data Data
}

func (a *App) Run() error {
	return a.app.Run(a.askforGender())
}

func (a *App) askforGender() dialog.Screen {
	sc := a.app.NewSelect(
		"choose your gender", []string{"female", "male"},

		func(chosen string) dialog.Screen {
			switch chosen {
			case "female":
				a.Data.Male = false
			case "male":
				a.Data.Male = true
			}

			return a.askforFirstname()
		})

	sc.SetOptions(
		dialog.OptionSetUUID("gender"),
	)

	return sc
}

func (a *App) askforFirstname() dialog.Screen {
	sc := a.app.NewInput(
		"please enter your firstname",

		func(fname string) dialog.Screen {
			a.Data.Firstname = fname

			return a.askforLastname()
		})
	sc.SetOptions(
		dialog.OptionSetUUID("firstname"),
		dialog.OptionValidator(dialog.String),
	)
	return sc
}

func (a *App) askforLastname() dialog.Screen {
	sc := a.app.NewInput(
		"please enter your lastname",

		func(lname string) dialog.Screen {
			a.Data.Lastname = lname

			return a.askforBirthday()
		})

	sc.SetOptions(
		dialog.OptionSetUUID("lastname"),
		dialog.OptionValidator(dialog.String),
	)

	return sc
}

func (a *App) askforBirthday() dialog.Screen {
	sc := a.app.NewInput(
		"please enter your birthday (YYYY-MM-DD)",

		func(bday string) dialog.Screen {
			a.Data.Birthday = bday

			return a.askforPets()
		})

	prefill := fmtdate.Format("YYYY-MM-DD", time.Now())

	sc.SetOptions(
		dialog.OptionSetUUID("birthday"),
		dialog.OptionValidator(dialog.DateTime("YYYY-MM-DD")),
		dialog.OptionPrefilled(prefill),
	)

	return sc
}

func (a *App) askforPets() dialog.Screen {
	var options []string

	for i := 1; i <= 40; i++ {
		options = append(options, fmt.Sprintf("Pet %v", i))
	}

	sc := a.app.NewMultiSelect(
		"which pets do you have", options,
		func(pets []string) dialog.Screen {
			a.Data.Pets = pets

			return a.askforNumber()
		})

	sc.SetOptions(
		dialog.OptionSetUUID("pets"),
		dialog.OptionValidator(dialog.And{dialog.Min(3), dialog.Max(5)}),
	)

	return sc
}

func (a *App) askforNumber() dialog.Screen {
	var options []string

	for i := 1; i <= 50; i++ {
		options = append(options, fmt.Sprintf("%v", i))
	}

	sc := a.app.NewSelect(
		"which number do you choose", options,

		func(choosen string) dialog.Screen {
			a.Data.Number = choosen

			return a.askforPassword()
		})

	sc.SetOptions(
		dialog.OptionSetUUID("number"),
		dialog.OptionValidator(dialog.NonEmpty),
	)

	return sc
}

func (a *App) askforPassword() dialog.Screen {
	sc := a.app.NewPassword(
		"please enter your password",
		func(pw string) dialog.Screen {
			a.Data.Password = pw

			return a.showSummary()
		})

	sc.SetOptions(
		dialog.OptionSetUUID("password"),
		dialog.OptionValidator(dialog.String),
	)

	return sc
}

func (a *App) showSummary() dialog.Screen {
	sc := a.app.NewOutput(
		a.summary(),
		func() dialog.Screen {
			return a.byebye()
		})

	return sc
}

func (a *App) byebye() dialog.Screen {
	sc := a.app.NewOutput(
		"Thanks and byebye",
		func() dialog.Screen {
			return dialog.QuitScreen()
		})

	return sc
}

func (a *App) summary() string {
	var g = "f"

	if a.Data.Male {
		g = "m"
	}

	var bd strings.Builder

	for i := 0; i < 5; i++ {
		s := fmt.Sprintf(`
### %v ##
%s %s (%s)
Password: %s
born %s
pets %s
number: %v
	`, i, a.Data.Firstname, a.Data.Lastname, g,
			a.Data.Password,
			a.Data.Birthday,
			strings.Join(a.Data.Pets, ", "),
			a.Data.Number)
		bd.WriteString(s)
	}

	return bd.String()
}

also, see example-app

Documentation

see https://pkg.go.dev/gitlab.com/golang-utils/dialog

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrCanceled = fmt.Errorf("operation canceled")

Functions

func QuitScreen

func QuitScreen() quitScreen

Types

type And

type And []Validator

func (And) Validate

func (a And) Validate(v interface{}) error

type App

type App interface {
	Name() string
	Run(firstScreen Screen) error
	NewPassword(question string, hd func(string) Screen) *InputScreen
	NewInput(question string, hd func(string) Screen) *InputScreen
	NewMultiSelect(question string, choices []string, hd func(s []string) Screen) *MultiSelectScreen
	NewOutput(message string, next func() Screen) *OutputScreen
	NewSelect(question string, choices []string, hd func(string) Screen) *SelectScreen
	NewError(message string) *ErrorScreen
}

func New

func New(name string, opts ...Option) App

type AppExt added in v0.0.3

type AppExt interface {
	App
	GetBreadcrumb() string
	GetValue(sc Screen) interface{}
	SetValue(sc Screen, value interface{})
	ClearValues()
	HasBackNav() bool
}

type DateTime

type DateTime string

the string is the format of the expected datetime (excel format)

func (DateTime) Validate

func (d DateTime) Validate(v interface{}) error

type ErrorScreen

type ErrorScreen struct {
	// contains filtered or unexported fields
}

ErrorScreen is a screen just for printing an error message

func (*ErrorScreen) AvailableLines

func (l *ErrorScreen) AvailableLines() int

func (*ErrorScreen) Body

func (l *ErrorScreen) Body() string

func (*ErrorScreen) Header

func (l *ErrorScreen) Header() string

func (*ErrorScreen) Lines

func (i *ErrorScreen) Lines() int

func (*ErrorScreen) Name

func (l *ErrorScreen) Name() string

func (*ErrorScreen) OnInput

func (l *ErrorScreen) OnInput(s string) Screen

func (*ErrorScreen) RunGui

func (l *ErrorScreen) RunGui() (sc Screen, back bool, err error)

func (*ErrorScreen) SetOptions

func (i *ErrorScreen) SetOptions(opts ...ScreenOption)

func (*ErrorScreen) SetValue

func (l *ErrorScreen) SetValue(v interface{})

func (*ErrorScreen) UUID

func (i *ErrorScreen) UUID() string

type GUI

type GUI interface {
	Input(msg string, prefilled string, hideText bool) (res string, back bool, err error)
	Select(msg string, items []string, selected string) (res string, back bool, err error)
	MultiSelect(msg string, items []string, preselected []string) (res []string, back bool, err error)
	Output(msg string) (back bool, err error)
	Error(msg string)
	SetApp(a AppExt)
}

type InputScreen

type InputScreen struct {
	// contains filtered or unexported fields
}

InputScreen is a Screen that allows user input

func (*InputScreen) AvailableLines

func (l *InputScreen) AvailableLines() int

func (*InputScreen) Body

func (l *InputScreen) Body() string

func (*InputScreen) Header

func (l *InputScreen) Header() string

func (*InputScreen) Lines

func (i *InputScreen) Lines() int

func (*InputScreen) Name

func (l *InputScreen) Name() string

func (*InputScreen) OnInput

func (l *InputScreen) OnInput(str string) Screen

func (*InputScreen) RunGui

func (l *InputScreen) RunGui() (sc Screen, back bool, err error)

func (*InputScreen) SetOptions

func (i *InputScreen) SetOptions(opts ...ScreenOption)

func (*InputScreen) SetValue

func (l *InputScreen) SetValue(v interface{})

func (*InputScreen) UUID

func (i *InputScreen) UUID() string

func (*InputScreen) Update

func (l *InputScreen) Update(msg tea.Msg) (tea.Model, tea.Cmd)

type Max

type Max int

func (Max) Validate

func (t Max) Validate(v interface{}) error

type Min

type Min int

func (Min) Validate

func (m Min) Validate(v interface{}) error

type MultiSelectScreen

type MultiSelectScreen struct {
	// contains filtered or unexported fields
}

MultiSelectScreen is a Screen that allows to choose more than one option of a given number of options

func (*MultiSelectScreen) AvailableLines

func (l *MultiSelectScreen) AvailableLines() int

func (*MultiSelectScreen) Body

func (l *MultiSelectScreen) Body() string

func (*MultiSelectScreen) Header

func (l *MultiSelectScreen) Header() string

func (*MultiSelectScreen) Lines

func (s *MultiSelectScreen) Lines() int

func (*MultiSelectScreen) Name

func (l *MultiSelectScreen) Name() string

func (*MultiSelectScreen) OnInput

func (l *MultiSelectScreen) OnInput(str string) Screen

func (*MultiSelectScreen) RunGui

func (l *MultiSelectScreen) RunGui() (sc Screen, back bool, err error)

func (*MultiSelectScreen) SetOptions

func (i *MultiSelectScreen) SetOptions(opts ...ScreenOption)

func (*MultiSelectScreen) SetValue

func (l *MultiSelectScreen) SetValue(v interface{})

func (*MultiSelectScreen) UUID

func (i *MultiSelectScreen) UUID() string

type Multihandler

type Multihandler func(st app, inputs ...string) Screen

type Option

type Option func(s *app)

func NoQuit

func NoQuit() Option

func WithBackNavigation

func WithBackNavigation() Option

func WithBreadcrumb

func WithBreadcrumb() Option

func WithFooter

func WithFooter() Option

func WithGui

func WithGui(g GUI) Option

func WithHeader

func WithHeader() Option

type Or

type Or []Validator

func (Or) Validate

func (a Or) Validate(v interface{}) error

type OutputScreen

type OutputScreen struct {
	// contains filtered or unexported fields
}

OutputScreen is a screen just for printing

func (*OutputScreen) AvailableLines

func (l *OutputScreen) AvailableLines() int

func (*OutputScreen) Body

func (l *OutputScreen) Body() string

func (*OutputScreen) Header

func (l *OutputScreen) Header() string

func (*OutputScreen) Lines

func (i *OutputScreen) Lines() int

func (*OutputScreen) Name

func (l *OutputScreen) Name() string

func (*OutputScreen) OnInput

func (l *OutputScreen) OnInput(str string) Screen

func (*OutputScreen) RunGui

func (l *OutputScreen) RunGui() (sc Screen, back bool, err error)

func (*OutputScreen) SetOptions

func (i *OutputScreen) SetOptions(opts ...ScreenOption)

func (*OutputScreen) SetValue

func (l *OutputScreen) SetValue(v interface{})

func (*OutputScreen) UUID

func (i *OutputScreen) UUID() string

type Regexp

type Regexp string

func (Regexp) Validate

func (d Regexp) Validate(v interface{}) error

type Screen

type Screen interface {
	Name() string
	Body() string
	OnInput(s string) Screen
	Header() string
	RunGui() (sc Screen, back bool, err error)
	SetValue(interface{})
	Lines() int
	AvailableLines() int
	SetOptions(opts ...ScreenOption)
	UUID() string
}

type ScreenOption

type ScreenOption func(*screenConfig)

func OptionCharLimit

func OptionCharLimit(n int) ScreenOption

func OptionName

func OptionName(n string) ScreenOption

func OptionPrefilled

func OptionPrefilled(val interface{}) ScreenOption

func OptionSetUUID

func OptionSetUUID(s string) ScreenOption

func OptionValidator

func OptionValidator(v Validator) ScreenOption

type SelectScreen

type SelectScreen struct {
	// contains filtered or unexported fields
}

SelectScreen is a screen that shows different options to select one of them

func (*SelectScreen) AvailableLines

func (l *SelectScreen) AvailableLines() int

func (*SelectScreen) Body

func (l *SelectScreen) Body() string

func (*SelectScreen) Header

func (l *SelectScreen) Header() string

func (*SelectScreen) Lines

func (s *SelectScreen) Lines() int

func (*SelectScreen) Name

func (l *SelectScreen) Name() string

func (*SelectScreen) OnInput

func (l *SelectScreen) OnInput(str string) Screen

func (*SelectScreen) RunGui

func (l *SelectScreen) RunGui() (sc Screen, back bool, err error)

func (*SelectScreen) SetOptions

func (i *SelectScreen) SetOptions(opts ...ScreenOption)

func (*SelectScreen) SetValue

func (l *SelectScreen) SetValue(v interface{})

func (*SelectScreen) UUID

func (i *SelectScreen) UUID() string

type Validator

type Validator interface {
	// if the value is valid, nil is returned. otherwise we can use the error message
	Validate(v interface{}) error
}

type ValidatorFunc

type ValidatorFunc func(interface{}) error
var Any ValidatorFunc = func(v interface{}) error {
	return nil
}
var Float ValidatorFunc = func(v interface{}) error {
	switch t := v.(type) {
	case float32:
	case float64:
	case string:
		_, err := strconv.ParseFloat(t, 64)

		if err != nil {
			return fmt.Errorf("'%s' is no float", t)
		}

	default:
		return fmt.Errorf("%v is no float", v)

	}

	return nil
}
var Int ValidatorFunc = func(v interface{}) error {
	switch t := v.(type) {
	case int:
	case int8:
	case int16:
	case int32:
	case int64:
	case uint:
	case uint8:
	case uint16:
	case uint32:
	case uint64:
	case string:
		_, err := strconv.Atoi(t)

		if err != nil {
			return fmt.Errorf("'%s' is no integer", t)
		}

	default:
		return fmt.Errorf("%v is no integer", v)

	}

	return nil
}
var NonEmpty ValidatorFunc = func(v interface{}) error {
	err := fmt.Errorf("%v is empty", v)
	switch vv := v.(type) {
	case string:
		if vv == "" {
			return err
		}
	case int:
		if vv == -1 {
			return err
		}
	case float32:
		if vv < 0.0 {
			return err
		}
	case float64:
		if vv < 0.0 {
			return err
		}
	default:
		if v == nil {
			return err
		}
	}

	return nil
}
var String ValidatorFunc = func(v interface{}) error {
	switch v.(type) {
	case string:
	default:
		return fmt.Errorf("%#v is no string", v)

	}

	return nil
}

func (ValidatorFunc) Validate

func (fn ValidatorFunc) Validate(v interface{}) error

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL