Добавление и исправление комментариев, начало добавление валидации, сообщение прокрути viewport на форме
This commit is contained in:
parent
c7ff7662ba
commit
e37cabadcc
14 changed files with 371 additions and 297 deletions
|
|
@ -2,10 +2,13 @@ package setup
|
|||
|
||||
import (
|
||||
"bubble/types"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
"github.com/expr-lang/expr"
|
||||
"github.com/sirupsen/logrus"
|
||||
"io"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
|
@ -18,8 +21,7 @@ import (
|
|||
// userRE - с начала строки, делит все по знаку двоеточия, берется первые 3 группы, пример user_name:x:1000:
|
||||
var userRE = regexp.MustCompile(`^([^:]+):[^:]*:([0-9]+):`)
|
||||
|
||||
// ParamsForCondition — собирает все текущие значения переменных приложения
|
||||
// для использования в expr-условиях (condition)
|
||||
// ParamsForCondition получение словаря переменных с приведением типов для проверки условий
|
||||
func ParamsForCondition(app *types.PackageApplication) map[string]interface{} {
|
||||
params := make(map[string]interface{})
|
||||
|
||||
|
|
@ -77,7 +79,7 @@ func ParamsForCondition(app *types.PackageApplication) map[string]interface{} {
|
|||
return params
|
||||
}
|
||||
|
||||
// CheckCondition — проверяет условие visibility (condition) для секции или поля
|
||||
// CheckCondition проверяет равно ли переданное условие
|
||||
func CheckCondition(condition string, app *types.PackageApplication) bool {
|
||||
if condition == "" {
|
||||
return true
|
||||
|
|
@ -99,7 +101,7 @@ func CheckCondition(condition string, app *types.PackageApplication) bool {
|
|||
return boolResult
|
||||
}
|
||||
|
||||
// ParamsForCompute — аналогично, но только по переменным (как в твоём старом коде)
|
||||
// ParamsForCompute получение словаря переменных без приведения типов, для вычисления
|
||||
func ParamsForCompute(app *types.PackageApplication) map[string]interface{} {
|
||||
params := make(map[string]interface{})
|
||||
|
||||
|
|
@ -129,7 +131,7 @@ func ParamsForCompute(app *types.PackageApplication) map[string]interface{} {
|
|||
return params
|
||||
}
|
||||
|
||||
// ComputeValue — вычисляет значение для compute-поля
|
||||
// ComputeValue вычисляет значение для поля compute.
|
||||
func ComputeValue(computeExpr string, app *types.PackageApplication) (interface{}, error) {
|
||||
if computeExpr == "" {
|
||||
return nil, nil
|
||||
|
|
@ -172,6 +174,44 @@ func Recompute(app *types.PackageApplication) {
|
|||
}
|
||||
}
|
||||
|
||||
// ValidateField создает функцию типа textinput.ValidateFunc для проверки значения полей
|
||||
func ValidateField(fieldName, variableName string, validations []types.FieldValidate, app *types.PackageApplication) textinput.ValidateFunc {
|
||||
if len(validations) == 0 {
|
||||
return nil
|
||||
}
|
||||
return func(text string) error {
|
||||
env := ParamsForCompute(app)
|
||||
env[variableName] = text //todo text это строка, если использовать функцию типа textinput.ValidateFunc, то словим ошибку типов
|
||||
options := append([]expr.Option{
|
||||
expr.Env(env),
|
||||
expr.AllowUndefinedVariables(),
|
||||
}, DefineExprCustomFunctions()...)
|
||||
for _, validate := range validations {
|
||||
program, err := expr.Compile(validate.Rule, options...)
|
||||
prefix := fmt.Sprintf("Валидация поля %s,", fieldName)
|
||||
if err != nil {
|
||||
msg := fmt.Errorf("ошибка компиляции правила: %s, err: %v", validate.Rule, err)
|
||||
logrus.Errorf("%s %v", prefix, msg)
|
||||
return msg
|
||||
}
|
||||
result, err := expr.Run(program, env)
|
||||
if err != nil {
|
||||
msg := fmt.Errorf("ошибка выполнения правила: %s, err: %v", validate.Rule, err)
|
||||
logrus.Errorf("%s %v", prefix, msg)
|
||||
return msg
|
||||
}
|
||||
if boolValue, ok := result.(bool); ok && !boolValue {
|
||||
return fmt.Errorf("%s", validate.Message)
|
||||
} else if !ok {
|
||||
msg := fmt.Errorf("возвращаемое значение правила: %s не булево", validate.Rule)
|
||||
logrus.Errorf("%s %v", prefix, msg)
|
||||
return msg
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DefineExprCustomFunctions возвращает собственные функции expr
|
||||
func DefineExprCustomFunctions() []expr.Option {
|
||||
return []expr.Option{
|
||||
|
|
@ -270,8 +310,17 @@ func DefineExprCustomFunctions() []expr.Option {
|
|||
return false, nil
|
||||
}
|
||||
path := fmt.Sprintf("%v", args[0])
|
||||
_, err := os.Stat(path)
|
||||
return err == nil, nil
|
||||
fileInfo, err := os.Stat(path)
|
||||
if err == nil && !fileInfo.IsDir() {
|
||||
return true, nil
|
||||
} else if err == nil && fileInfo.IsDir() {
|
||||
return false, fmt.Errorf("file is dir")
|
||||
}
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return false, fmt.Errorf("no such directory or file")
|
||||
} else {
|
||||
return false, err
|
||||
}
|
||||
}, new(func(string) bool),
|
||||
),
|
||||
//проверяет наличие директории в системе
|
||||
|
|
@ -282,13 +331,16 @@ func DefineExprCustomFunctions() []expr.Option {
|
|||
}
|
||||
path := fmt.Sprintf("%v", args[0])
|
||||
fileInfo, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if fileInfo.IsDir() {
|
||||
if err == nil && fileInfo.IsDir() {
|
||||
return true, nil
|
||||
} else if err == nil && !fileInfo.IsDir() {
|
||||
return false, fmt.Errorf("file is not a dir")
|
||||
}
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return false, fmt.Errorf("no such directory or file")
|
||||
} else {
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
}, new(func(string) bool),
|
||||
),
|
||||
//проверяет доступность порта
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue