143 lines
2.8 KiB
Go
143 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)
|
|
current = 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
|
|
|
|
}
|