package ini import ( "bytes" "io" "strings" "asciigoat.org/core" "asciigoat.org/core/reflective" "asciigoat.org/ini/parser" ) // Decoder ... type Decoder struct { io.Closer out *reflective.Reflection p *parser.Parser queue []*token } // Decode ... func (dec *Decoder) Decode(v any) error { defer dec.Close() r, err := reflective.New(v) switch e := err.(type) { case *reflective.InvalidUnmarshalError: // customize error e.Prefix = "ini" e.Method = "Decode" case nil: // good reflection. Go! dec.out = r err = dec.p.Run() } return err } // NewDecoder creates a Decoder using the provided [io.Reader] // as source func NewDecoder(r io.Reader) *Decoder { rc := core.NewReadCloser(r) switch { case rc == nil: return nil default: dec := &Decoder{ p: parser.NewParser(rc), Closer: rc, } // callbacks dec.p.OnToken = dec.parserOnToken dec.p.OnError = dec.parserOnError return dec } } // NewDecoderBytes creates a Decoder using the provided bytes array // as source func NewDecoderBytes(b []byte) *Decoder { return NewDecoder(bytes.NewReader(b)) } // NewDecoderString creates a Decoder over a provided string of data func NewDecoderString(s string) *Decoder { return NewDecoder(strings.NewReader(s)) }