Handle reader errors in Regexp
This commit is contained in:
		@@ -16,6 +16,7 @@ import (
 | 
				
			|||||||
// with the regexp package.
 | 
					// with the regexp package.
 | 
				
			||||||
type RuneReader struct {
 | 
					type RuneReader struct {
 | 
				
			||||||
	cursor cursor.Cursor[byte]
 | 
						cursor cursor.Cursor[byte]
 | 
				
			||||||
 | 
						err    error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewRuneReader(c cursor.Cursor[byte]) *RuneReader {
 | 
					func NewRuneReader(c cursor.Cursor[byte]) *RuneReader {
 | 
				
			||||||
@@ -23,6 +24,9 @@ func NewRuneReader(c cursor.Cursor[byte]) *RuneReader {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (rr *RuneReader) ReadRune() (r rune, size int, err error) {
 | 
					func (rr *RuneReader) ReadRune() (r rune, size int, err error) {
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							rr.err = err
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
	var b [4]byte
 | 
						var b [4]byte
 | 
				
			||||||
	s := b[:]
 | 
						s := b[:]
 | 
				
			||||||
	n, next, err := rr.cursor.Read(s)
 | 
						n, next, err := rr.cursor.Read(s)
 | 
				
			||||||
@@ -40,6 +44,10 @@ func (rr *RuneReader) Cursor() cursor.Cursor[byte] {
 | 
				
			|||||||
	return rr.cursor
 | 
						return rr.cursor
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (rr *RuneReader) Error() error {
 | 
				
			||||||
 | 
						return rr.err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Regexp(str string) gigaparsec.Parser[byte, []byte] {
 | 
					func Regexp(str string) gigaparsec.Parser[byte, []byte] {
 | 
				
			||||||
	if !strings.HasPrefix(str, "^") && !strings.HasPrefix(str, `\A`) {
 | 
						if !strings.HasPrefix(str, "^") && !strings.HasPrefix(str, `\A`) {
 | 
				
			||||||
		str = "^" + str
 | 
							str = "^" + str
 | 
				
			||||||
@@ -49,7 +57,10 @@ func Regexp(str string) gigaparsec.Parser[byte, []byte] {
 | 
				
			|||||||
	return func(input gigaparsec.State[byte]) (gigaparsec.Result[byte, []byte], error) {
 | 
						return func(input gigaparsec.State[byte]) (gigaparsec.Result[byte, []byte], error) {
 | 
				
			||||||
		r := NewRuneReader(input.Cursor())
 | 
							r := NewRuneReader(input.Cursor())
 | 
				
			||||||
		idx := re.FindReaderIndex(r)
 | 
							idx := re.FindReaderIndex(r)
 | 
				
			||||||
		// TODO Check error from r; this requires an Error() method on cursor.RuneReader.
 | 
							err := r.Error()
 | 
				
			||||||
 | 
							if err != nil && !errors.Is(err, io.EOF) {
 | 
				
			||||||
 | 
								return gigaparsec.Result[byte, []byte]{}, fmt.Errorf("Regexp: reader error: %w", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if idx == nil {
 | 
							if idx == nil {
 | 
				
			||||||
			return gigaparsec.Fail[byte, []byte](false, gigaparsec.Message{
 | 
								return gigaparsec.Fail[byte, []byte](false, gigaparsec.Message{
 | 
				
			||||||
				Pos:      input.Pos(),
 | 
									Pos:      input.Pos(),
 | 
				
			||||||
@@ -65,7 +76,7 @@ func Regexp(str string) gigaparsec.Parser[byte, []byte] {
 | 
				
			|||||||
		n, _, err := input.Cursor().Read(dst)
 | 
							n, _, err := input.Cursor().Read(dst)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			// If we can't access those same bytes again, something is wrong.
 | 
								// If we can't access those same bytes again, something is wrong.
 | 
				
			||||||
			return gigaparsec.Result[byte, []byte]{}, fmt.Errorf("Regex: unexpected error: %w", err)
 | 
								return gigaparsec.Result[byte, []byte]{}, fmt.Errorf("Regexp: unexpected error: %w", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		next := input.At(input.Pos() + n)
 | 
							next := input.At(input.Pos() + n)
 | 
				
			||||||
		return gigaparsec.Succeed(true, dst, next, gigaparsec.MessageOK(input.Pos())), nil
 | 
							return gigaparsec.Succeed(true, dst, next, gigaparsec.MessageOK(input.Pos())), nil
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user