nix-amer/internal/cnf/nginx.go

142 lines
2.8 KiB
Go

package cnf
import (
lib "git.xdrm.io/go/nix-amer/internal/cnf/parser/nginx"
"io"
"strings"
)
type nginx struct {
data *lib.Line
parsed bool
}
// ReadFrom implements io.ReaderFrom
func (d *nginx) ReadFrom(_reader io.Reader) (int64, error) {
d.data = new(lib.Line)
// 1. get nginx decoder
decoder := lib.NewDecoder(_reader)
err := decoder.Decode(d.data)
if err != nil {
return 0, err
}
d.parsed = true
return 0, nil
}
// WriteTo implements io.WriterTo
func (d *nginx) WriteTo(_writer io.Writer) (int64, error) {
encoder := lib.NewEncoder(_writer)
return 0, encoder.Encode(d.data)
}
// browse returns the target of a dot-separated path (as an interface{} chain where the last is the target if found)
// if <create> is true, create if does not exist
func (d *nginx) browse(_path string, create ...bool) (*lib.Line, bool) {
mustCreate := len(create) > 0 && create[0]
// 1. extract path
path := strings.Split(_path, ".")
// 2. nothing
if len(path) < 1 {
return &lib.Line{}, true
}
// 3. init output chain
current := d.data
// 4. iterate over path / nested fields
l := len(path)
for i, field := range path {
// 5. intermediary fields (sections)
if i < l-1 {
found := false
for _, child := range current.Lines {
if child.Type == lib.SECTION && len(child.Components) > 0 && child.Components[0] == field {
found = true
current = child
break
}
}
if found {
continue
}
// create section
if mustCreate {
sec := &lib.Line{
Type: lib.SECTION,
Components: []string{field},
Lines: make([]*lib.Line, 0),
}
current.Lines = append(current.Lines, sec)
continue
}
// not found and not create
return nil, false
}
// 6. last field (assignment)
for _, child := range current.Lines {
if child.Type == lib.ASSIGNMENT && len(child.Components) > 0 && child.Components[0] == field {
return child, true
}
}
// create assignment
if mustCreate {
assignment := &lib.Line{
Type: lib.ASSIGNMENT,
Components: []string{field, ""},
Lines: nil,
}
current.Lines = append(current.Lines, assignment)
return assignment, true
}
// not found and not create
return nil, false
}
return nil, false
}
// Get returns the value of a dot-separated path, and if it exists
func (d *nginx) Get(_path string) (string, bool) {
// 1. browse path
last, found := d.browse(_path, true)
if !found || len(last.Components) < 2 {
return "", false
}
// 2. Get last field
return last.Components[1], true
}
// Set the value of a dot-separated path, and creates it if not found
func (d *nginx) Set(_path, _value string) bool {
// 1. browse path
last, found := d.browse(_path, true)
if !found || len(last.Components) < 2 {
return false
}
// 2. Set value
last.Components[1] = _value
return true
}