4 Commits

Author SHA1 Message Date
amery d9f98e9cb7 Unmarshal: WIP
Signed-off-by: Alejandro Mery <amery@jpi.io>
2023-08-29 02:45:10 +00:00
amery f4dc0a0270 Decoder: WIP
Signed-off-by: Alejandro Mery <amery@jpi.io>
2023-08-29 02:45:10 +00:00
amery 3c94d7fc7c basic: WIP
Signed-off-by: Alejandro Mery <amery@jpi.io>
2023-08-29 02:45:10 +00:00
amery c43cc7d0dd parser: WIP
Signed-off-by: Alejandro Mery <amery@jpi.io>
2023-08-29 02:45:10 +00:00
7 changed files with 167 additions and 1 deletions
+2
View File
@@ -0,0 +1,2 @@
// Package basic provides a basic representation of dosini-style documents
package basic
+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
}
+48
View File
@@ -0,0 +1,48 @@
package ini
import (
"bytes"
"io"
"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.NewBuffer(b))
}
// NewDecoderString creates a Decoder over a provided string of data
func NewDecoderString(s string) *Decoder {
return NewDecoder(bytes.NewBufferString(s))
}
+4 -1
View File
@@ -4,7 +4,10 @@ go 1.19
replace asciigoat.org/core => ../core
require github.com/mgechev/revive v1.3.3
require (
asciigoat.org/core v0.3.0
github.com/mgechev/revive v1.3.3
)
require (
github.com/BurntSushi/toml v1.3.2 // indirect
+68
View File
@@ -0,0 +1,68 @@
// Package parser parses dosini-style files
package parser
import (
"io"
"asciigoat.org/core/lexer"
)
// Parser parses a dosini-style document
type Parser struct {
src *lexer.Reader
OnSection func(pos lexer.Position, name, subname string, hasSubname bool) error
OnField func(pos lexer.Position, key, value string) error
OnComment func(pos lexer.Position, comment string) error
OnError func(pos lexer.Position, content string, err error) error
}
func defaultOnSection(_ lexer.Position, _, _ string, _ bool) error { return nil }
func defaultOnField(_ lexer.Position, _, _ string) error { return nil }
func defaultOnComment(_ lexer.Position, _ string) error { return nil }
func defaultOnError(pos lexer.Position, content string, err error) error {
return &lexer.Error{
Line: pos.Line,
Column: pos.Column,
Content: content,
Err: err,
}
}
func (p *Parser) setDefaults() {
if p.OnSection == nil {
p.OnSection = defaultOnSection
}
if p.OnField == nil {
p.OnField = defaultOnField
}
if p.OnComment == nil {
p.OnComment = defaultOnComment
}
if p.OnError == nil {
p.OnError = defaultOnError
}
}
// Run parses the source
func (p *Parser) Run() error {
p.setDefaults()
return lexer.Run(p.initialState)
}
// NewParser creates a dosini-style parser using
// an [io.Reader] as source
func NewParser(r io.Reader) *Parser {
if r == nil {
return nil
}
return &Parser{
src: lexer.NewReader(r),
}
}
+7
View File
@@ -0,0 +1,7 @@
package parser
import "asciigoat.org/core/lexer"
func (*Parser) initialState() (lexer.StateFn, error) {
return nil, nil
}
+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 (*Decoder) Unmarshal(any) error {
return nil
}