diff options
| author | 2026-02-17 21:33:24 +0300 | |
|---|---|---|
| committer | 2026-02-21 16:23:10 +0300 | |
| commit | ba06314d59e55945b103ead2c7a9e01f58c6a93c (patch) | |
| tree | 34ab8ac19307da60bd5caf76d844a6dc2e730361 /model | |
| parent | init (diff) | |
| download | conf-ba06314d59e55945b103ead2c7a9e01f58c6a93c.tar.gz conf-ba06314d59e55945b103ead2c7a9e01f58c6a93c.tar.bz2 conf-ba06314d59e55945b103ead2c7a9e01f58c6a93c.tar.xz conf-ba06314d59e55945b103ead2c7a9e01f58c6a93c.zip | |
v0.0.1v0.0.1
Diffstat (limited to '')
| -rw-r--r-- | model/assignment.go | 6 | ||||
| -rw-r--r-- | model/command.go | 9 | ||||
| -rw-r--r-- | model/doc.go | 43 | ||||
| -rw-r--r-- | model/lookup.go | 49 | ||||
| -rw-r--r-- | model/value.go | 42 |
5 files changed, 139 insertions, 10 deletions
diff --git a/model/assignment.go b/model/assignment.go new file mode 100644 index 0000000..746e2b3 --- /dev/null +++ b/model/assignment.go @@ -0,0 +1,6 @@ +package model + +type Assignment struct { + Key string + Value Values +} diff --git a/model/command.go b/model/command.go new file mode 100644 index 0000000..237e94f --- /dev/null +++ b/model/command.go @@ -0,0 +1,9 @@ +package model + +type Command struct { + Name string + Arguments Values + Body *Doc +} + +type Commands []*Command diff --git a/model/doc.go b/model/doc.go index 76f03e4..9c13a4c 100644 --- a/model/doc.go +++ b/model/doc.go @@ -1,18 +1,41 @@ package model -type Doc []any +type Doc struct { + items []any + vars map[string]Values + commands map[string]Commands +} -type Assignment struct { - Key string - Value []Value +func New(cap int) *Doc { + return &Doc{ + items: make([]any, 0, cap), + vars: make(map[string]Values, cap), + commands: make(map[string]Commands, cap), + } } -type Command struct { - Name string - Arguments []Value - Body Doc +func (d *Doc) AppendAssignment(e *Assignment) { + d.items = append(d.items, e) + d.vars[e.Key] = append(d.vars[e.Key], e.Value...) } -type Value any +func (d *Doc) AppendCommand(c *Command) { + d.items = append(d.items, c) + d.commands[c.Name] = append(d.commands[c.Name], c) +} -type Word string +func (d *Doc) Vars() map[string]Values { + return d.vars +} + +func (d *Doc) Get(key string) Values { + return d.vars[key] +} + +func (d *Doc) Commands(name string) Commands { + return d.commands[name] +} + +func (d *Doc) Items() []any { + return d.items +} diff --git a/model/lookup.go b/model/lookup.go new file mode 100644 index 0000000..e8cc8bf --- /dev/null +++ b/model/lookup.go @@ -0,0 +1,49 @@ +package model + +import ( + "os" + "strings" +) + +// WordLookup тип определяющий функцию поиска замены слов при +// стрингификации Values. +type WordLookup func(word Word) string + +// chainLookup утилитарная функция для последовательных применений функций +// поиска до первого нахождения подстановки. Если returnOrigin == true, +// то в случае неудачи вернёт имя слова. +func chainLookup(lookups ...WordLookup) WordLookup { + return func(word Word) string { + for _, lookup := range lookups { + if v := lookup(word); v != "" { + return v + } + } + return string(word) + } +} + +// LookupEnv функция типа WordLookup которая пытается подставить вместо word +// соответствующую ему переменную окружения ОС. При этом он срабатывает только +// если слово начинается со знака `$`. +func LookupEnv(word Word) string { + if !strings.HasPrefix(string(word), "$") { + return "" + } + varName := strings.TrimPrefix(string(word), "$") + if result, ok := os.LookupEnv(varName); ok { + return result + } + return "" +} + +// LookupSubst функция типа WordLookup которая пытается подставить вместо word +// значение из словаря подстановок по соответствующему ключу. +func LookupSubst(subst map[Word]string) WordLookup { + return func(word Word) string { + if result, ok := subst[word]; ok { + return result + } + return "" + } +} diff --git a/model/value.go b/model/value.go new file mode 100644 index 0000000..4ec7344 --- /dev/null +++ b/model/value.go @@ -0,0 +1,42 @@ +package model + +import ( + "strconv" + "strings" +) + +type Value any + +type Values []Value + +// BuildString собирает из значений Value цельную строку, при этом приводя все +// значения к типу string. Так же принимает функции типа WordLookup, которые +// последовательно будут пытаться привести значения типа Word к +// контекстозависимым значениям. Например, пытаться находить по имени переменную +// окружения ОС. +func (v Values) BuildString(lookups ...WordLookup) string { + sw := strings.Builder{} + + for _, v := range v { + switch v := v.(type) { + case string: + sw.WriteString(v) + case float64: + sw.WriteString(strconv.FormatFloat(v, 'f', 5, 64)) + case int: + sw.WriteString(strconv.Itoa(v)) + case bool: + if v { + sw.WriteString("true") + continue + } + sw.WriteString("false") + case Word: + sw.WriteString(chainLookup(lookups...)(v)) + } + } + + return sw.String() +} + +type Word string |
