RuneFunc implemented
This commit is contained in:
		
							
								
								
									
										41
									
								
								reader.go
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								reader.go
									
									
									
									
									
								
							| @ -119,16 +119,16 @@ func (r *Reader) UnreadRunes(n int) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // StringWhile reads runes and calls f for each one. | // StringWhile reads runes and calls all functions for each one. | ||||||
| // It returns all runes as a string for which f returned true. | // It returns all runes as a string for which any function returned true. | ||||||
| // It stops when f returns false or an error occured. | // It stops when all functions returned false or an error occured. | ||||||
| // The rune for which f returned false will not be unread. | // The rune for which that function returned false will not be unread. | ||||||
| func (r *Reader) StringWhile(f func(rn rune) bool) (string, error) { | func (r *Reader) StringWhile(f ...RuneFunc) (string, error) { | ||||||
| 	s := new(strings.Builder) | 	s := new(strings.Builder) | ||||||
|  |  | ||||||
| 	var rn rune | 	var rn rune | ||||||
| 	var err error | 	var err error | ||||||
| 	for rn, err = r.Rune(); err == nil && f(rn); rn, err = r.Rune() { | 	for rn, err = r.Rune(); err == nil && findFirstTrue(rn, f); rn, err = r.Rune() { | ||||||
| 		s.WriteRune(rn) | 		s.WriteRune(rn) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -136,8 +136,8 @@ func (r *Reader) StringWhile(f func(rn rune) bool) (string, error) { | |||||||
| } | } | ||||||
|  |  | ||||||
| // PeekStringWhile acts as StringWhile but does not advance reader position | // PeekStringWhile acts as StringWhile but does not advance reader position | ||||||
| func (r *Reader) PeekStringWhile(f func(rn rune) bool) (string, error) { | func (r *Reader) PeekStringWhile(f ...RuneFunc) (string, error) { | ||||||
| 	str, err := r.StringWhile(f) | 	str, err := r.StringWhile(f...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| @ -149,14 +149,23 @@ func (r *Reader) PeekStringWhile(f func(rn rune) bool) (string, error) { | |||||||
| 	return str, nil | 	return str, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // StringUntil is a shorthand for r.StringWhile(func(rn rune) bool { return !f(rn) }) | // SkipStringWhile acts as StringWhile but discards the string | ||||||
| func (r *Reader) StringUntil(f func(rn rune) bool) (string, error) { | func (r *Reader) SkipStringWhile(f ...RuneFunc) error { | ||||||
| 	return r.StringWhile(func(rn rune) bool { return !f(rn) }) | 	_, err := r.StringWhile(f...) | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // StringUntil reads runes and calls all functions for each one. | ||||||
|  | // It returns all runes as a string for which all functions returned true. | ||||||
|  | // It stops when any function returns false or an error occured. | ||||||
|  | // The rune for which that function returned false will not be unread. | ||||||
|  | func (r *Reader) StringUntil(f ...RuneFunc) (string, error) { | ||||||
|  | 	return r.StringWhile(func(rn rune) bool { return !findFirstTrue(rn, f) }) | ||||||
| } | } | ||||||
|  |  | ||||||
| // PeekStringUntil acts as StringUntil but does not advance reader position | // PeekStringUntil acts as StringUntil but does not advance reader position | ||||||
| func (r *Reader) PeekStringUntil(f func(rn rune) bool) (string, error) { | func (r *Reader) PeekStringUntil(f ...RuneFunc) (string, error) { | ||||||
| 	str, err := r.StringUntil(f) | 	str, err := r.StringUntil(f...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| @ -168,6 +177,12 @@ func (r *Reader) PeekStringUntil(f func(rn rune) bool) (string, error) { | |||||||
| 	return str, nil | 	return str, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // SkipStringUntil acts as StringUntil but discards the string | ||||||
|  | func (r *Reader) SkipStringUntil(f ...RuneFunc) error { | ||||||
|  | 	_, err := r.StringUntil(f...) | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  |  | ||||||
| // Commit clears the internal buffer and therefore removes all data which were already read. | // 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. | // After calling Commit any unreads will return ErrNothingToUnread until another read occured. | ||||||
| func (r *Reader) Commit() { | func (r *Reader) Commit() { | ||||||
|  | |||||||
| @ -26,11 +26,11 @@ func TestPos(t *testing.T) { | |||||||
| func TestEOF(t *testing.T) { | func TestEOF(t *testing.T) { | ||||||
| 	r := NewReader(strings.NewReader("hello world\nasddsa")) | 	r := NewReader(strings.NewReader("hello world\nasddsa")) | ||||||
|  |  | ||||||
| 	for line, err := r.StringUntil(isNewline); err == nil; line, err = r.StringUntil(isNewline) { | 	var line string | ||||||
|  | 	var err error | ||||||
|  | 	for line, err = r.StringUntil(IsNewLine); err == nil; line, err = r.StringUntil(IsNewLine) { | ||||||
| 		fmt.Println(line, err) | 		fmt.Println(line, err) | ||||||
| 	} | 	} | ||||||
| } |  | ||||||
|  |  | ||||||
| func isNewline(rn rune) bool { | 	fmt.Println(line, err) | ||||||
| 	return rn == '\n' |  | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										52
									
								
								runefunc.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								runefunc.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | |||||||
|  | package bufr | ||||||
|  |  | ||||||
|  | import "git.milar.in/milarin/ds" | ||||||
|  |  | ||||||
|  | type RuneFunc = func(rn rune) bool | ||||||
|  |  | ||||||
|  | func IsNewLine(rn rune) bool { | ||||||
|  | 	return rn == '\n' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func IsSpace(rn rune) bool { | ||||||
|  | 	return rn == ' ' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func IsWhitespace(rn rune) bool { | ||||||
|  | 	return IsSpace(rn) || IsNewLine(rn) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func And(f ...RuneFunc) RuneFunc { | ||||||
|  | 	return func(rn rune) bool { | ||||||
|  | 		return findFirstFalse(rn, f) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func Or(f ...RuneFunc) RuneFunc { | ||||||
|  | 	return func(rn rune) bool { | ||||||
|  | 		return findFirstTrue(rn, f) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func Not(f RuneFunc) RuneFunc { | ||||||
|  | 	return func(rn rune) bool { | ||||||
|  | 		return !f(rn) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func Is(rn rune) RuneFunc { | ||||||
|  | 	return func(r rune) bool { | ||||||
|  | 		return rn == r | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func OneOf(runes string) RuneFunc { | ||||||
|  | 	m := ds.NewSet[rune]() | ||||||
|  | 	for _, rn := range runes { | ||||||
|  | 		m.Add(rn) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return func(r rune) bool { | ||||||
|  | 		return m.Has(r) | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										18
									
								
								utils.go
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								utils.go
									
									
									
									
									
								
							| @ -13,3 +13,21 @@ func prependString(str string, r io.Reader) *bufio.Reader { | |||||||
| func prependRune(rn rune, r io.Reader) *bufio.Reader { | func prependRune(rn rune, r io.Reader) *bufio.Reader { | ||||||
| 	return prependString(string(rn), r) | 	return prependString(string(rn), r) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func findFirstTrue(rn rune, functions []RuneFunc) bool { | ||||||
|  | 	for _, f := range functions { | ||||||
|  | 		if f(rn) { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func findFirstFalse(rn rune, functions []RuneFunc) bool { | ||||||
|  | 	for _, f := range functions { | ||||||
|  | 		if !f(rn) { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return true | ||||||
|  | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 milarin
					milarin