From db8bb97dfa2dacef002a1f349ea970d76fee4fc9 Mon Sep 17 00:00:00 2001 From: Alexander Neonxp Kiryukhin Date: Sun, 22 Feb 2026 20:15:50 +0300 Subject: Refactoring --- visitor/default.go | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 visitor/default.go (limited to 'visitor/default.go') diff --git a/visitor/default.go b/visitor/default.go new file mode 100644 index 0000000..d8c8172 --- /dev/null +++ b/visitor/default.go @@ -0,0 +1,63 @@ +package visitor + +import ( + "errors" + "fmt" + "strings" + + "go.neonxp.ru/conf/model" +) + +var ( + ErrEmptyQuery = errors.New("empty query") + ErrNoChildKey = errors.New("no child key") +) + +func NewDefault() *Default { + return &Default{ + vars: map[string]model.Values{}, + children: map[string]*Default{}, + args: model.Values{}, + } +} + +// Default просто собирает рекурсивно все переменные в дерево. +// На самом деле, для большинства сценариев конфигов его должно хватить. +type Default struct { + vars map[string]model.Values + children map[string]*Default + args model.Values +} + +func (p *Default) VisitDirective(ident string, args model.Values, body model.Body) error { + p.children[ident] = NewDefault() + p.children[ident].args = args + return body.Execute(p.children[ident]) +} + +func (p *Default) VisitSetting(key string, values model.Values) error { + p.vars[key] = values + + return nil +} + +func (p *Default) Get(path string) (model.Values, error) { + splitPath := strings.SplitN(path, ".", 2) + switch len(splitPath) { + case 1: + if v, ok := p.vars[splitPath[0]]; ok { + return v, nil + } + if child, ok := p.children[splitPath[0]]; ok { + return child.args, nil + } + return nil, fmt.Errorf("%w: %s", ErrNoChildKey, splitPath[0]) + case 2: + if child, ok := p.children[splitPath[0]]; ok { + return child.Get(splitPath[1]) + } + return nil, fmt.Errorf("%w: %s", ErrNoChildKey, splitPath[0]) + default: + return nil, ErrEmptyQuery + } +} -- cgit v1.2.3