diff --git a/errors.go b/errors.go index 7152e3a..b0730e0 100644 --- a/errors.go +++ b/errors.go @@ -6,4 +6,5 @@ import ( var ( ErrNothingToUnread = adverr.NewErrTmpl("ErrNothingToUnread", "Unreading failed because there wasn't any Read yet") + ErrNoMatchFound = adverr.NewErrTmpl("ErrNoMatchFound", "no match found") ) diff --git a/reader.go b/reader.go index d9379ca..130c653 100644 --- a/reader.go +++ b/reader.go @@ -204,6 +204,48 @@ func (r *Reader) ExpectRune(f ...RuneFunc) (bool, error) { return findFirstTrue(rn, f), nil } +// ExpectString calls ExpectRune for each rune in str successively. +// If the expected string was not found, all read runes will be unread +func (r *Reader) ExpectString(str string) (bool, error) { + read := 0 + for _, rn := range str { + ok, err := r.ExpectRune(Is(rn)) + if err != nil { + return false, err + } + + read++ + + if !ok { + if err := r.UnreadRunes(read); err != nil { + return false, err + } + return false, nil + } + } + + return true, nil +} + +// ExpectOneOfString calls ExpectString for each string successively +// and returns the string which first matched. +// The returned string will not be unread. +// If no string matches, ErrNoMatchFound is returned +func (r *Reader) ExpectOneOfString(str ...string) (string, error) { + for _, s := range str { + ok, err := r.ExpectString(s) + if err != nil { + return "", err + } + + if ok { + return s, nil + } + } + + return "", ErrNoMatchFound +} + // Commit clears the internal buffer and therefore removes all data which were already read. // After calling Commit any unreads will return ErrNothingToUnread until another read occured. func (r *Reader) Commit() {