package ffdhall import ( "errors" "fmt" "io" "strings" "github.com/philandstuff/dhall-golang/v6" ) // DhallParser is a helper function that uses a default DhallParseConfig. func DhallParser(r io.Reader, set func(name, value string) error) error { return (&DhallParseConfig{}).Parse(r, set) } // DhallParseConfig collects parameters for the Dhall config file parser. type DhallParseConfig struct { // Delimiter is used when concatenating nested node keys into a flag name. // The default delimiter is ".". Delimiter string } // Parse a Dhall document from the provided io.Reader, using the provided set // function to set flag values. Flag names are derived from the node names and // their key/value pairs. func (pc *DhallParseConfig) Parse(r io.Reader, set func(name, value string) error) error { if pc.Delimiter == "" { pc.Delimiter = "." } data, err := io.ReadAll(r) if err != nil { return err } // Compatibility with other parsers if strings.TrimSpace(string(data)) == "" { return nil } var m interface{} if err := dhall.Unmarshal(data, &m); err != nil { return DhallParseError{Inner: err} } mm, ok := m.(map[string]interface{}) if !ok { return errors.New("could not unmarshal to map[string]interface{}") } if err := traverseMap(mm, pc.Delimiter, set); err != nil { return DhallParseError{Inner: err} } return nil } // DhallParseError wraps all errors originating from the DhallParser. type DhallParseError struct { Inner error } // Error implenents the error interface. func (e DhallParseError) Error() string { return fmt.Sprintf("could not parse Dhall config: %v", e.Inner) } // Unwrap implements the errors.Wrapper interface, allowing errors.Is and // errors.As to work with DhallParseErrors. func (e DhallParseError) Unwrap() error { return e.Inner }