4 Commits

Author SHA1 Message Date
amery ca1796e895 Unmarshal: WIP
Signed-off-by: Alejandro Mery <amery@jpi.io>
2023-08-31 16:30:07 +00:00
amery b662a8587c Decoder: WIP
Signed-off-by: Alejandro Mery <amery@jpi.io>
2023-08-31 16:30:07 +00:00
amery b123415c8f basic: WIP
Signed-off-by: Alejandro Mery <amery@jpi.io>
2023-08-31 16:30:07 +00:00
amery df773c7a3a build-sys: use local asciigoat.org/core [DO-NOT-MERGE]
Signed-off-by: Alejandro Mery <amery@jpi.io>
2023-08-31 15:19:27 +01:00
8 changed files with 165 additions and 50 deletions
-47
View File
@@ -1,47 +0,0 @@
# asciigoat's INI parser
[![Go Reference][godoc-badge]][godoc]
[![Go Report Card][goreport-badge]][goreport]
`asciigoat.org/ini` is a simple Go library that very loosly parses
[`INI`-style][wikipedia-dosini] documents allowing the implementation
of stricter parsers of similar form.
**asciigoat** is [MIT](https://opensource.org/license/mit/) licensed.
[godoc]: https://pkg.go.dev/asciigoat.org/ini
[godoc-badge]: https://pkg.go.dev/badge/asciigoat.org/ini.svg
[goreport]: https://goreportcard.com/report/asciigoat.org/ini
[goreport-badge]: https://goreportcard.com/badge/asciigoat.org/ini
[godoc-lexer]: https://pkg.go.dev/asciigoat.org/core/lexer
[godoc-parser-parser]: https://pkg.go.dev/asciigoat.org/ini/parser#Parser
[wikipedia-dosini]: https://en.wikipedia.org/wiki/INI_file
## Parser
[`parser.Parser`][godoc-parser-parser] uses
[`asciigoat`'s lexer][godoc-lexer] to process an `INI`-style document
emiting tokens and errors via callbacks.
## Other Implementations
Other implementations exist, and they are mature and feature-rich, but they
are highly opinionated about what's a valid file. Built around maps they don't
allow repeating names and constraint what characters can be used.
These are great when you can adapt, or already agree, to their conditions but
that's not always the case when you are parsing configuration files from
other applications and that's what [asciigoat.org/ini][godoc] attempts to solve.
* [gcfg](https://pkg.go.dev/gopkg.in/gcfg.v1)
* [unknwon's go-ini](https://github.com/go-ini/ini)
* [wlevene's GoINI](https://github.com/wlevene/ini)
## See also
* [asciigoat.org/core](https://asciigoat.org/core)
* [oss.jpi.io](https://oss.jpi.io)
* [INI file][wikipedia-dosini] (_wikipedia_)
* [TOML](https://www.kelche.co/blog/go/toml/)
+2
View File
@@ -0,0 +1,2 @@
// Package basic provides a basic representation of dosini-style documents
package basic
+73
View File
@@ -0,0 +1,73 @@
package basic
import (
"bytes"
"io"
"io/fs"
"log"
"strings"
"asciigoat.org/core/lexer"
"asciigoat.org/ini/parser"
)
type token struct {
pos lexer.Position
typ parser.TokenType
value string
}
type decoder struct {
p *parser.Parser
out *Document
queue []token
curSection *Section
curField *Field
}
func (dec *decoder) OnToken(pos lexer.Position, typ parser.TokenType, value string) error {
tok := token{pos, typ, value}
log.Printf("%s[%v]: %s %s: %q", "decoder", len(dec.queue), pos, typ, value)
dec.queue = append(dec.queue, tok)
return nil
}
func (*decoder) OnError(pos lexer.Position, hint string, err error) error {
log.Printf("%s: %s %s: %s: %v", "decoder", pos, "error", hint, err)
return err
}
// Decode ...
func Decode(r io.Reader) (*Document, error) {
var out Document
if r == nil {
return nil, fs.ErrNotExist
}
// parser
p := parser.NewParser(r)
// decoder
dec := decoder{p: p, out: &out}
// glue
p.OnToken = dec.OnToken
p.OnError = dec.OnError
// Go!
err := p.Run()
return &out, err
}
// DecodeBytes ...
func DecodeBytes(b []byte) (*Document, error) {
return Decode(bytes.NewReader(b))
}
// DecodeString ...
func DecodeString(s string) (*Document, error) {
return Decode(strings.NewReader(s))
}
+23
View File
@@ -0,0 +1,23 @@
package basic
// Document ...
type Document struct {
Global []Field
Sections []Section
}
// Section ...
type Section struct {
Name string
Key string
HadKey bool
Fields []Field
}
// Field ...
type Field struct {
Key string
Value string
}
+49
View File
@@ -0,0 +1,49 @@
package ini
import (
"bytes"
"io"
"strings"
"asciigoat.org/core"
"asciigoat.org/ini/parser"
)
// Decoder ...
type Decoder struct {
io.Closer
p *parser.Parser
}
// Decode ...
func (dec *Decoder) Decode() error {
defer dec.Close()
return dec.p.Run()
}
// NewDecoder creates a Decoder over the provided [io.Reader]
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,
}
return dec
}
}
// NewDecoderBytes creates a Decoder over a provided bytes array
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))
}
+3 -1
View File
@@ -2,8 +2,10 @@ module asciigoat.org/ini
go 1.19
replace asciigoat.org/core => ../core
require (
asciigoat.org/core v0.3.6
asciigoat.org/core v0.3.7
github.com/mgechev/revive v1.3.3
golang.org/x/tools v0.12.0
)
-2
View File
@@ -1,5 +1,3 @@
asciigoat.org/core v0.3.6 h1:b1vL090OxylmSOwLQryjrmC8FhhCtktMyeJSy1e6LwI=
asciigoat.org/core v0.3.6/go.mod h1:tXj+JUutxRbcO40ZQRuUVaZ4rnYz1kAZ0nblisV8u74=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/chavacava/garif v0.0.0-20230608123814-4bd63c2919ab h1:5JxePczlyGAtj6R1MUEFZ/UFud6FfsOejq7xLC2ZIb0=
+15
View File
@@ -0,0 +1,15 @@
package ini
import "io"
// ReadInto ...
func ReadInto(v any, r io.Reader) error {
dec := NewDecoder(r)
return dec.Unmarshal(v)
}
// Unmarshal ...
func (dec *Decoder) Unmarshal(any) error {
return dec.p.Run()
}