Documentation
¶
Overview ¶
Example (Encoding_json_reader_broken) ¶
const readerBroken = `{
"foo": "bar",
"baz": ["yay", "nay", 5, "wow"]`
dec := NewJsonDecoder(
json.NewDecoder(
io.MultiReader(
strings.NewReader(readerBroken),
iotest.ErrReader(errors.New("sample")),
),
),
)
for t := range dec.Iter() {
fmt.Printf("%v\n", t)
}
fmt.Printf("stored error: %v\n", dec.Err())
Output: { foo bar baz [ yay nay 5 wow ] stored error: sample
Example (Encoding_json_semantically_broken) ¶
const semanticallyBroken = `{
"foo": "bar",
"baz": ["yay", "nay", 5, "wow"]
}`
dec := NewJsonDecoder(json.NewDecoder(strings.NewReader(semanticallyBroken)))
var depth int
for t := range dec.Iter() {
if depth == 1 && t == "baz" {
// read 1 ahead.
t, err := dec.Dec.Token()
if err != nil {
panic(err)
}
if t != json.Delim('[') {
panic("??")
}
var yayyay string
for dec.Dec.More() {
err = dec.Dec.Decode(&yayyay)
if err == nil {
fmt.Printf("yay? = %s\n", yayyay)
} else {
fmt.Printf("yay err = %v\n", err)
}
}
}
switch t {
case json.Delim('{'), json.Delim('['):
depth++
case json.Delim('}'), json.Delim(']'):
depth--
}
}
fmt.Printf("stored error: %v\n", dec.Err())
_, err := dec.Dec.Token()
fmt.Printf("eof: %t\n", err == io.EOF)
Output: yay? = yay yay? = nay yay err = json: cannot unmarshal number into Go value of type string yay? = wow stored error: <nil> eof: true
Example (Encoding_json_syntactically_broken) ¶
const syntacticallyBroken = `{
"foo": "bar",
"baz": ["yay", "nay", 5, "wow"],
"broken": {
}`
dec := NewJsonDecoder(json.NewDecoder(strings.NewReader(syntacticallyBroken)))
for t := range dec.Iter() {
fmt.Printf("%v\n", t)
}
fmt.Printf("stored error: %v\n", dec.Err())
_, err := dec.Dec.Token()
fmt.Printf("eof: %t\n", err == io.EOF)
Output: { foo bar baz [ yay nay 5 wow ] broken { } stored error: <nil> eof: true
Example (Encoding_xml_reader_broken) ¶
const readerBroken = `
<root>
<self/>
<foo>bar</foo>
<baz>5</baz>
<baz>23</baz>
<baz>yay</baz>
<baz>49`
dec := NewXmlDecoder(
xml.NewDecoder(
io.MultiReader(
strings.NewReader(strings.TrimSpace(readerBroken)),
iotest.ErrReader(errors.New("sample")),
),
),
)
for t := range dec.Iter() {
fmt.Printf("%#v\n", t)
}
fmt.Printf("stored err: %v\n", dec.Err())
Output: xml.StartElement{Name:xml.Name{Space:"", Local:"root"}, Attr:[]xml.Attr{}} xml.CharData{0xa, 0x9, 0x9} xml.StartElement{Name:xml.Name{Space:"", Local:"self"}, Attr:[]xml.Attr{}} xml.EndElement{Name:xml.Name{Space:"", Local:"self"}} xml.CharData{0xa, 0x9, 0x9} xml.StartElement{Name:xml.Name{Space:"", Local:"foo"}, Attr:[]xml.Attr{}} xml.CharData{0x62, 0x61, 0x72} xml.EndElement{Name:xml.Name{Space:"", Local:"foo"}} xml.CharData{0xa, 0x9, 0x9} xml.StartElement{Name:xml.Name{Space:"", Local:"baz"}, Attr:[]xml.Attr{}} xml.CharData{0x35} xml.EndElement{Name:xml.Name{Space:"", Local:"baz"}} xml.CharData{0xa, 0x9, 0x9} xml.StartElement{Name:xml.Name{Space:"", Local:"baz"}, Attr:[]xml.Attr{}} xml.CharData{0x32, 0x33} xml.EndElement{Name:xml.Name{Space:"", Local:"baz"}} xml.CharData{0xa, 0x9, 0x9} xml.StartElement{Name:xml.Name{Space:"", Local:"baz"}, Attr:[]xml.Attr{}} xml.CharData{0x79, 0x61, 0x79} xml.EndElement{Name:xml.Name{Space:"", Local:"baz"}} xml.CharData{0xa, 0x9, 0x9} xml.StartElement{Name:xml.Name{Space:"", Local:"baz"}, Attr:[]xml.Attr{}} xml.CharData{0x34, 0x39} stored err: sample
Example (Encoding_xml_semantically_broken) ¶
const semanticallyBroken = `
<root>
<self/>
<foo>bar</foo>
<baz>5</baz>
<baz>23</baz>
<baz>yay</baz>
<baz>49</baz>
</root>`
dec := NewXmlDecoder(xml.NewDecoder(strings.NewReader(strings.TrimSpace(semanticallyBroken))))
var depth int
for t := range dec.Iter() {
var ok bool
tok, ok := t.(xml.StartElement)
if ok {
if depth == 1 && tok.Name.Local == "baz" {
var yayyay int
err := dec.Dec.DecodeElement(&yayyay, &tok)
if err == nil {
fmt.Printf("yay? = %d\n", yayyay)
} else {
fmt.Printf("yay err = %v\n", err)
}
continue
}
depth++
}
_, ok = t.(xml.EndElement)
if ok {
depth--
}
}
fmt.Printf("stored error: %v\n", dec.Err())
_, err := dec.Dec.Token()
fmt.Printf("eof: %t\n", err == io.EOF)
Output: yay? = 5 yay? = 23 yay err = strconv.ParseInt: parsing "yay": invalid syntax yay? = 49 stored error: <nil> eof: true
Example (Encoding_xml_syntactically_broken) ¶
const syntacticallyBroken = `
<root>
<self/>
<foo>bar</foo>
<baz>5</baz>
<baz>23</baz>
<baz>yay</baz>
<baz>49`
dec := NewXmlDecoder(xml.NewDecoder(strings.NewReader(strings.TrimSpace(syntacticallyBroken))))
for t := range dec.Iter() {
fmt.Printf("%#v\n", t)
}
fmt.Printf("stored err: %v\n", dec.Err())
Output: xml.StartElement{Name:xml.Name{Space:"", Local:"root"}, Attr:[]xml.Attr{}} xml.CharData{0xa, 0x9, 0x9} xml.StartElement{Name:xml.Name{Space:"", Local:"self"}, Attr:[]xml.Attr{}} xml.EndElement{Name:xml.Name{Space:"", Local:"self"}} xml.CharData{0xa, 0x9, 0x9} xml.StartElement{Name:xml.Name{Space:"", Local:"foo"}, Attr:[]xml.Attr{}} xml.CharData{0x62, 0x61, 0x72} xml.EndElement{Name:xml.Name{Space:"", Local:"foo"}} xml.CharData{0xa, 0x9, 0x9} xml.StartElement{Name:xml.Name{Space:"", Local:"baz"}, Attr:[]xml.Attr{}} xml.CharData{0x35} xml.EndElement{Name:xml.Name{Space:"", Local:"baz"}} xml.CharData{0xa, 0x9, 0x9} xml.StartElement{Name:xml.Name{Space:"", Local:"baz"}, Attr:[]xml.Attr{}} xml.CharData{0x32, 0x33} xml.EndElement{Name:xml.Name{Space:"", Local:"baz"}} xml.CharData{0xa, 0x9, 0x9} xml.StartElement{Name:xml.Name{Space:"", Local:"baz"}, Attr:[]xml.Attr{}} xml.CharData{0x79, 0x61, 0x79} xml.EndElement{Name:xml.Name{Space:"", Local:"baz"}} xml.CharData{0xa, 0x9, 0x9} xml.StartElement{Name:xml.Name{Space:"", Local:"baz"}, Attr:[]xml.Attr{}} xml.CharData{0x34, 0x39} stored err: XML syntax error on line 7: unexpected EOF
Example (Sql_rows_row_error) ¶
package main
import (
"fmt"
"github.com/ngicks/go-iterator-helper/hiter/errbox"
"github.com/ngicks/go-iterator-helper/internal/testhelper"
)
func main() {
mock := testhelper.OpenMockDB(true)
defer mock.Close()
boxed := errbox.NewSqlRows(testhelper.QueryRows(mock), testhelper.Scan)
for row := range boxed.Iter() {
fmt.Printf("row = %#v\n", row)
}
fmt.Printf("stored err: %v\n", boxed.Err())
}
Output: row = testhelper.TestRow{Id:1, Title:"post 1", Body:"hello"} row = testhelper.TestRow{Id:2, Title:"post 2", Body:"world"} stored err: mock error
Example (Sql_rows_scan_error) ¶
package main
import (
"database/sql"
"errors"
"fmt"
"github.com/ngicks/go-iterator-helper/hiter/errbox"
"github.com/ngicks/go-iterator-helper/internal/testhelper"
)
func main() {
scanErr := errors.New("scan")
mock := testhelper.OpenMockDB(true)
defer mock.Close()
var count int
boxed := errbox.NewSqlRows(
testhelper.QueryRows(mock),
func(r *sql.Rows) (testhelper.TestRow, error) {
count++
if count > 1 {
return *new(testhelper.TestRow), scanErr
}
return testhelper.Scan(r)
},
)
for row := range boxed.Iter() {
fmt.Printf("row = %#v\n", row)
}
fmt.Printf("stored err: %v\n", boxed.Err())
}
Output: row = testhelper.TestRow{Id:1, Title:"post 1", Body:"hello"} stored err: scan
Example (Sql_rows_successful) ¶
package main
import (
"database/sql"
"fmt"
"github.com/ngicks/go-iterator-helper/hiter/errbox"
"github.com/ngicks/go-iterator-helper/internal/testhelper"
)
func main() {
type TestRow struct {
Id int
Title string
Body string
}
mock := testhelper.OpenMockDB(false)
defer mock.Close()
rows, err := mock.Query("SELECT id, title, body FROM posts")
if err != nil {
panic(err)
}
scanner := func(r *sql.Rows) (TestRow, error) {
var t TestRow
err := r.Scan(&t.Id, &t.Title, &t.Body)
return t, err
}
boxed := errbox.NewSqlRows(rows, scanner)
for row := range boxed.Iter() {
fmt.Printf("row = %#v\n", row)
}
fmt.Printf("stored err: %v\n", boxed.Err())
}
Output: row = errbox_test.TestRow{Id:1, Title:"post 1", Body:"hello"} row = errbox_test.TestRow{Id:2, Title:"post 2", Body:"world"} row = errbox_test.TestRow{Id:3, Title:"post 3", Body:"iter"} stored err: <nil>
Index ¶
Examples ¶
- Package (Encoding_json_reader_broken)
- Package (Encoding_json_semantically_broken)
- Package (Encoding_json_syntactically_broken)
- Package (Encoding_xml_reader_broken)
- Package (Encoding_xml_semantically_broken)
- Package (Encoding_xml_syntactically_broken)
- Package (Sql_rows_row_error)
- Package (Sql_rows_scan_error)
- Package (Sql_rows_successful)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Box ¶
type Box[V any] struct { // contains filtered or unexported fields }
Box boxes an input iter.Seq2[V, error] to iter.Seq[V], by storing a first non nil error encountered. Later the error can be examined by *Box.Err.
*Box.Iter returns an iterator converted to be stateful from input iter.Seq2 by iter.Pull2. When non nil error is yielded from the iterator, Box stores the error and the boxed iterator stops without yielding paired value V. *Box.Err returns that error otherwise nil.
The zero Box is invalid and it must be allocated by New.
func New ¶
New returns a newly allocate Box.
When a pair from seq contains non-nil error, Box discards a former value of the pair(V), then the iterator returned from Box.Iter stops.
*Box.Stop must be called to release resource regardless of usage.
func (*Box[V]) Err ¶
Err returns an error the input iterator has returned. If the iterator has not yet encountered an error, Err returns nil.
type JsonDecoder ¶
func NewJsonDecoder ¶
func NewJsonDecoder(dec *json.Decoder) *JsonDecoder
type XmlDecoder ¶
func NewXmlDecoder ¶
func NewXmlDecoder(dec *xml.Decoder) *XmlDecoder