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 | ||||
| } | ||||
|  | ||||
| // StringWhile reads runes and calls f for each one. | ||||
| // It returns all runes as a string for which f returned true. | ||||
| // It stops when f returns false or an error occured. | ||||
| // The rune for which f returned false will not be unread. | ||||
| func (r *Reader) StringWhile(f func(rn rune) bool) (string, error) { | ||||
| // StringWhile reads runes and calls all functions for each one. | ||||
| // It returns all runes as a string for which any function returned true. | ||||
| // It stops when all functions returned false or an error occured. | ||||
| // The rune for which that function returned false will not be unread. | ||||
| func (r *Reader) StringWhile(f ...RuneFunc) (string, error) { | ||||
| 	s := new(strings.Builder) | ||||
|  | ||||
| 	var rn rune | ||||
| 	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) | ||||
| 	} | ||||
|  | ||||
| @ -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 | ||||
| func (r *Reader) PeekStringWhile(f func(rn rune) bool) (string, error) { | ||||
| 	str, err := r.StringWhile(f) | ||||
| func (r *Reader) PeekStringWhile(f ...RuneFunc) (string, error) { | ||||
| 	str, err := r.StringWhile(f...) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| @ -149,14 +149,23 @@ func (r *Reader) PeekStringWhile(f func(rn rune) bool) (string, error) { | ||||
| 	return str, nil | ||||
| } | ||||
|  | ||||
| // StringUntil is a shorthand for r.StringWhile(func(rn rune) bool { return !f(rn) }) | ||||
| func (r *Reader) StringUntil(f func(rn rune) bool) (string, error) { | ||||
| 	return r.StringWhile(func(rn rune) bool { return !f(rn) }) | ||||
| // SkipStringWhile acts as StringWhile but discards the string | ||||
| func (r *Reader) SkipStringWhile(f ...RuneFunc) error { | ||||
| 	_, 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 | ||||
| func (r *Reader) PeekStringUntil(f func(rn rune) bool) (string, error) { | ||||
| 	str, err := r.StringUntil(f) | ||||
| func (r *Reader) PeekStringUntil(f ...RuneFunc) (string, error) { | ||||
| 	str, err := r.StringUntil(f...) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| @ -168,6 +177,12 @@ func (r *Reader) PeekStringUntil(f func(rn rune) bool) (string, error) { | ||||
| 	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. | ||||
| // After calling Commit any unreads will return ErrNothingToUnread until another read occured. | ||||
| func (r *Reader) Commit() { | ||||
|  | ||||
| @ -26,11 +26,11 @@ func TestPos(t *testing.T) { | ||||
| func TestEOF(t *testing.T) { | ||||
| 	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) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func isNewline(rn rune) bool { | ||||
| 	return rn == '\n' | ||||
| 	fmt.Println(line, err) | ||||
| } | ||||
|  | ||||
							
								
								
									
										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 { | ||||
| 	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