package cnf import ( lib "github.com/xdrm-brackets/nix-amer/internal/cnf/parser/bash" "io" "strings" ) type bash struct { data *lib.File parsed bool } // ReadFrom implements io.ReaderFrom func (d *bash) ReadFrom(_reader io.Reader) (int64, error) { d.data = new(lib.File) // 1. get bash 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 *bash) 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 is true, create if does not exist func (d *bash) browse(_path string, create ...bool) (*lib.Line, bool) { mustCreate := len(create) > 0 && create[0] // 1. extract path path := strings.Split(_path, ".") field := path[len(path)-1] // 2. nothing if len(path) < 1 { return &lib.Line{}, true } // 3. iterate over path / nested fields for _, line := range d.data.Lines { if line.Type == lib.ASSIGNMENT && len(line.Components) > 1 && line.Components[1] == field { return line, true } } // 4. create assignment if mustCreate { assignment := &lib.Line{ Type: lib.ASSIGNMENT, Components: []string{"", field, "", ""}, } d.data.Lines = append(d.data.Lines, assignment) return assignment, true } return nil, false } // Get returns the value of a dot-separated path, and if it exists func (d *bash) Get(_path string) (string, bool) { // 1. browse path last, found := d.browse(_path, true) if !found { return "", false } // 2. Get last field return last.Components[2], true } // Set the value of a dot-separated path, and creates it if not found func (d *bash) Set(_path, _value string) bool { // 1. browse path last, found := d.browse(_path, true) if !found { return false } // 2. Set value last.Components[2] = _value return true }