mirror of
https://github.com/mjl-/mox.git
synced 2024-12-30 18:33:48 +03:00
71 lines
1.7 KiB
Go
71 lines
1.7 KiB
Go
package sconf
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"reflect"
|
|
)
|
|
|
|
// ParseFile reads an sconf file from path into dst.
|
|
func ParseFile(path string, dst interface{}) error {
|
|
src, err := os.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer src.Close()
|
|
return parse(path, src, dst)
|
|
}
|
|
|
|
// Parse reads an sconf file from a reader into dst.
|
|
func Parse(src io.Reader, dst interface{}) error {
|
|
return parse("", src, dst)
|
|
}
|
|
|
|
// Describe writes an example sconf file describing v to w. The file includes all
|
|
// fields, values and documentation on the fields as configured with the "sconf"
|
|
// and "sconf-doc" struct tags. Describe does not detect recursive values and will
|
|
// attempt to write them.
|
|
func Describe(w io.Writer, v interface{}) error {
|
|
return describe(w, v, true, true)
|
|
}
|
|
|
|
// Write writes a valid sconf file describing v to w, without comments, without
|
|
// zero values of optional fields. Write does not detect recursive values and
|
|
// will attempt to write them.
|
|
func Write(w io.Writer, v interface{}) error {
|
|
return describe(w, v, false, false)
|
|
}
|
|
|
|
// WriteDocs is like Write, but does write comments.
|
|
func WriteDocs(w io.Writer, v interface{}) error {
|
|
return describe(w, v, false, true)
|
|
}
|
|
|
|
func describe(w io.Writer, v interface{}, keepZero bool, docs bool) (err error) {
|
|
value := reflect.ValueOf(v)
|
|
t := value.Type()
|
|
if t.Kind() == reflect.Ptr {
|
|
value = value.Elem()
|
|
t = value.Type()
|
|
}
|
|
if t.Kind() != reflect.Struct {
|
|
return fmt.Errorf("top level object must be a struct, is a %T", v)
|
|
}
|
|
defer func() {
|
|
x := recover()
|
|
if x == nil {
|
|
return
|
|
}
|
|
if e, ok := x.(writeError); ok {
|
|
err = error(e)
|
|
} else {
|
|
panic(x)
|
|
}
|
|
}()
|
|
wr := &writer{out: bufio.NewWriter(w), keepZero: keepZero, docs: docs}
|
|
wr.describeStruct(value)
|
|
wr.flush()
|
|
return nil
|
|
}
|