Skip to content

Commit

Permalink
replace collection start with a function; fix regression
Browse files Browse the repository at this point in the history
the last cl had an unnecessary second interface; rewind slightly to use a function for the collection iteration generation.
also: fix a crash bug when comments are missing in a map which wants to encode comments ( regression from 0.7 behavior )
  • Loading branch information
ionous committed Jan 16, 2024
1 parent dcef29b commit 88b6ca2
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 35 deletions.
18 changes: 7 additions & 11 deletions encode/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,28 @@ import (
// an encoder that expects no comments
func MakeEncoder(w io.Writer) Encoder {
var m MapTransform
var n SequenceTransform
return Encoder{
Tabs: TabWriter{Writer: w},
Mapper: m.Mapper(),
Sequencer: n.Sequencer(),
Sequencer: MakeSequence,
}
}

// use the "CommentBlock" encoder
func MakeCommentEncoder(w io.Writer) Encoder {
var m MapTransform
var n SequenceTransform
return Encoder{
Tabs: TabWriter{Writer: w},
Mapper: m.Mapper(),
Sequencer: n.Sequencer(),
Sequencer: MakeSequence,
MapComments: CommentBlock,
SequenceComments: CommentBlock,
}
}

type Encoder struct {
Tabs TabWriter
Mapper, Sequencer Collection
Mapper, Sequencer StartCollection
MapComments Commenting
SequenceComments Commenting
}
Expand Down Expand Up @@ -125,7 +123,7 @@ func (enc *Encoder) WriteValue(v r.Value, wasMaps bool) (err error) {

case r.Array, r.Slice:
// tbd: look at tag for "want array"?
if it, e := enc.Sequencer.StartCollection(v); e != nil {
if it, e := enc.Sequencer(v); e != nil {
err = e
} else if it == nil {
tab.WriteRune(runes.ArrayOpen)
Expand All @@ -135,7 +133,7 @@ func (enc *Encoder) WriteValue(v r.Value, wasMaps bool) (err error) {
}

case r.Map:
if it, e := enc.Mapper.StartCollection(v); e != nil {
if it, e := enc.Mapper(v); e != nil {
err = e
} else if it != nil {
err = enc.WriteMapping(it, wasMaps)
Expand Down Expand Up @@ -180,10 +178,8 @@ func (enc *Encoder) writeCollection(it Iterator, cmts Commenting, wasMaps, maps
}

// setup a comment iterator:
var cit Comments
if cmts == nil {
cit = noComments{} // expect none by default
} else {
var cit Comments = noComments{} // expect none by default
if cmts != nil {
key, val := it.GetKey(), getValue(it)
if !maps || len(key) == 0 {
cit, err = cmts(val)
Expand Down
15 changes: 3 additions & 12 deletions encode/encodeCollect.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ package encode

import r "reflect"

type Collection interface {
// for sequences, value is guaranteed to be a reflect.Slice
// for mappings, value is guaranteed to be a reflect.Map
StartCollection(r.Value) (Iterator, error)
}
// for sequences, value is guaranteed to be a reflect.Slice
// for mappings, value is guaranteed to be a reflect.Map
type StartCollection func(r.Value) (Iterator, error)

// controls serialization when implemented by a value that's being encoded
type TellMapping interface {
Expand Down Expand Up @@ -48,10 +46,3 @@ type Comments interface {
Next() bool // called before every element, false if there are no more elements
GetComment() Comment // valid after next returns true
}

// implements StartCollection using a function
type sequenceStarter func(r.Value) (Iterator, error)

func (q sequenceStarter) StartCollection(v r.Value) (Iterator, error) {
return q(v)
}
3 changes: 3 additions & 0 deletions encode/encodeComments.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ func CommentSlice(els []Comment) Comments {
return &commentSlice{next: els}
}

// a nil commenting implementation for readability
var NoComments Commenting = nil

// implies that there are comments;
// the encoder should simply skip them.
func DiscardComments(r.Value) (Comments, error) {
Expand Down
4 changes: 2 additions & 2 deletions encode/encodeMap.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ type MapTransform struct {
}

// return a factory function for the encoder
func (m *MapTransform) Mapper() Collection {
return sequenceStarter(m.makeMapping)
func (m *MapTransform) Mapper() StartCollection {
return m.makeMapping
}

// sort keys; by default keys are written sorted as per standard go string rules.
Expand Down
9 changes: 1 addition & 8 deletions encode/encodeSeq.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,12 @@ import (
r "reflect"
)

type SequenceTransform struct{}

// return a factory function for the encoder
func (n *SequenceTransform) Sequencer() Collection {
return sequenceStarter(n.makeSequence)
}

// todo? sort values; by default sequences are not sorted
// func (m *SequenceTransform) Sort(t func(a, b r.Value) bool) {
// m.sort = t
// }

func (n *SequenceTransform) makeSequence(src r.Value) (ret Iterator, err error) {
func MakeSequence(src r.Value) (ret Iterator, err error) {
if e := validateSeq(src); e != nil {
err = e
} else if cnt := src.Len(); cnt > 0 {
Expand Down
4 changes: 2 additions & 2 deletions encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (enc *Encoder) Encode(v any) (err error) {

// configure how mappings are encoded
// returns self for chaining
func (enc *Encoder) SetMapper(n encode.Collection, c encode.Commenting) *Encoder {
func (enc *Encoder) SetMapper(n encode.StartCollection, c encode.Commenting) *Encoder {
inner := (*encode.Encoder)(enc)
inner.Mapper = n
inner.MapComments = c
Expand All @@ -35,7 +35,7 @@ func (enc *Encoder) SetMapper(n encode.Collection, c encode.Commenting) *Encoder

// configure how sequences are encoded
// returns self for chaining
func (enc *Encoder) SetSequencer(n encode.Collection, c encode.Commenting) *Encoder {
func (enc *Encoder) SetSequencer(n encode.StartCollection, c encode.Commenting) *Encoder {
inner := (*encode.Encoder)(enc)
inner.Sequencer = n
inner.SequenceComments = c
Expand Down

0 comments on commit 88b6ca2

Please sign in to comment.