Skip to content

Commit dafb1a8

Browse files
committed
v0.2.1.
1 parent d55703d commit dafb1a8

6 files changed

Lines changed: 41 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## v0.2.1
4+
5+
- Improved examples and documentation.
6+
37
## v0.2.0
48

59
### Added

example_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"mz.attahri.com/code/lines"
88
)
99

10+
// ExampleHead demonstrates iterating over the first n lines of a reader.
1011
func ExampleHead() {
1112
r := strings.NewReader("one\ntwo\nthree\nfour\nfive")
1213
for line, err := range lines.Head(r, 3) {
@@ -21,6 +22,7 @@ func ExampleHead() {
2122
// three
2223
}
2324

25+
// ExampleTail demonstrates iterating over the last n lines of a reader in reverse order.
2426
func ExampleTail() {
2527
r := strings.NewReader("one\ntwo\nthree\nfour\nfive")
2628
for line, err := range lines.Tail(r, 2) {
@@ -34,6 +36,7 @@ func ExampleTail() {
3436
// four
3537
}
3638

39+
// ExampleFilter demonstrates filtering lines that exactly match a given value.
3740
func ExampleFilter() {
3841
r := strings.NewReader("apple\nbanana\napricot\ncherry")
3942
for line, err := range lines.Filter(lines.All(r), "banana") {
@@ -46,6 +49,7 @@ func ExampleFilter() {
4649
// Line 2: banana
4750
}
4851

52+
// ExampleFilterFunc demonstrates filtering lines using a custom predicate function.
4953
func ExampleFilterFunc() {
5054
r := strings.NewReader("apple\nbanana\napricot\ncherry")
5155
for line, err := range lines.FilterFunc[string](lines.All(r), func(s string) bool {
@@ -61,6 +65,7 @@ func ExampleFilterFunc() {
6165
// apricot
6266
}
6367

68+
// ExampleTake demonstrates limiting a scanner to the first n lines.
6469
func ExampleTake() {
6570
r := strings.NewReader("one\ntwo\nthree\nfour\nfive")
6671
for line, err := range lines.Take(lines.All(r), 2) {
@@ -74,6 +79,7 @@ func ExampleTake() {
7479
// two
7580
}
7681

82+
// ExampleSkip demonstrates skipping the first n lines of a scanner.
7783
func ExampleSkip() {
7884
r := strings.NewReader("one\ntwo\nthree\nfour\nfive")
7985
for line, err := range lines.Skip(lines.All(r), 3) {
@@ -87,6 +93,7 @@ func ExampleSkip() {
8793
// five
8894
}
8995

96+
// ExampleRange demonstrates extracting a range of lines by line number.
9097
func ExampleRange() {
9198
r := strings.NewReader("one\ntwo\nthree\nfour\nfive")
9299
for line, err := range lines.Range(lines.All(r), 2, 4) {
@@ -101,6 +108,7 @@ func ExampleRange() {
101108
// four
102109
}
103110

111+
// ExampleTakeWhile demonstrates yielding lines while a predicate holds true.
104112
func ExampleTakeWhile() {
105113
r := strings.NewReader("# comment 1\n# comment 2\ncode\n# not a header")
106114
for line, err := range lines.TakeWhile[string](lines.All(r), func(s string) bool {
@@ -116,6 +124,7 @@ func ExampleTakeWhile() {
116124
// # comment 2
117125
}
118126

127+
// ExampleSkipWhile demonstrates skipping lines while a predicate holds true.
119128
func ExampleSkipWhile() {
120129
r := strings.NewReader("# comment 1\n# comment 2\ncode\nmore code")
121130
for line, err := range lines.SkipWhile[string](lines.All(r), func(s string) bool {
@@ -131,6 +140,7 @@ func ExampleSkipWhile() {
131140
// more code
132141
}
133142

143+
// ExampleMap demonstrates transforming each line's content.
134144
func ExampleMap() {
135145
r := strings.NewReader("hello\nworld")
136146
for upper, err := range lines.Map[string](lines.All(r), func(l *lines.Line) string {
@@ -146,6 +156,7 @@ func ExampleMap() {
146156
// WORLD
147157
}
148158

159+
// ExampleCollect demonstrates materializing a scanner into a slice.
149160
func ExampleCollect() {
150161
r := strings.NewReader("one\ntwo\nthree")
151162
all, err := lines.Collect(lines.All(r))
@@ -159,6 +170,7 @@ func ExampleCollect() {
159170
// two
160171
}
161172

173+
// ExampleGet demonstrates retrieving a specific line by number.
162174
func ExampleGet() {
163175
r := strings.NewReader("one\ntwo\nthree")
164176
line, err := lines.Get(lines.All(r), 2)
@@ -170,6 +182,7 @@ func ExampleGet() {
170182
// two
171183
}
172184

185+
// ExampleContains demonstrates checking if a line exists in a scanner.
173186
func ExampleContains() {
174187
r := strings.NewReader("apple\nbanana\ncherry")
175188
found, err := lines.Contains(lines.All(r), "banana")
@@ -181,6 +194,7 @@ func ExampleContains() {
181194
// true
182195
}
183196

197+
// ExampleIndex demonstrates finding the line number of the first matching line.
184198
func ExampleIndex() {
185199
r := strings.NewReader("apple\nbanana\ncherry")
186200
lineno, err := lines.Index(lines.All(r), "banana")
@@ -192,6 +206,7 @@ func ExampleIndex() {
192206
// 2
193207
}
194208

209+
// ExampleLastIndex demonstrates finding the line number of the last matching line.
195210
func ExampleLastIndex() {
196211
r := strings.NewReader("apple\nbanana\napple\ncherry")
197212
lineno, err := lines.LastIndex(lines.All(r), "apple")
@@ -203,6 +218,7 @@ func ExampleLastIndex() {
203218
// 3
204219
}
205220

221+
// ExampleFindAll demonstrates finding all line numbers matching a predicate.
206222
func ExampleFindAll() {
207223
r := strings.NewReader("TODO: first\ndone\nTODO: second\ndone")
208224
matches, err := lines.FindAll[string](lines.All(r), func(s string) bool {
@@ -216,6 +232,7 @@ func ExampleFindAll() {
216232
// [1 3]
217233
}
218234

235+
// ExampleCount demonstrates counting lines equal to a given value.
219236
func ExampleCount() {
220237
r := strings.NewReader("apple\nbanana\napple\ncherry")
221238
n, err := lines.Count(lines.All(r), "apple")
@@ -227,6 +244,7 @@ func ExampleCount() {
227244
// 2
228245
}
229246

247+
// ExampleCountFunc demonstrates counting lines matching a predicate.
230248
func ExampleCountFunc() {
231249
r := strings.NewReader("short\na]very long line here\nmedium")
232250
n, err := lines.CountFunc(lines.All(r), func(s string) bool {

lines.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
// Package lines provides iterator-based tools to read, search, and modify
22
// lines in text files and streams.
33
//
4+
// # Generic Text Support
5+
//
6+
// Many functions in this package are generic over the [Text] constraint,
7+
// accepting both string and []byte. This allows working with line content
8+
// in whichever form is most convenient for your use case.
9+
//
410
// # Line Numbers
511
//
612
// All line numbers in this package are 1-based to match editor conventions.
@@ -10,7 +16,8 @@
1016
//
1117
// The core abstraction is [Scanner], a type alias for iter.Seq2[*Line, error].
1218
// Create scanners with [All] (forward) or [Backward] (reverse), then compose
13-
// them with [Filter], [Take], [Head], and [Tail].
19+
// them with [Filter], [Take], [Skip], and [Range]. Use [Head] and [Tail] for
20+
// convenient access to the first or last n lines from a reader.
1421
//
1522
// # Searching
1623
//

rewrite.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func (lw *lineWriter) Write(p []byte) (n int, err error) {
6868
}
6969

7070
// Transform applies fn to each line from src and writes results to dst.
71+
// Return [ErrDrop] from fn to skip a line.
7172
// Lines are processed in a streaming fashion without buffering the entire
7273
// file, making it suitable for large files. The caller is responsible for
7374
// positioning src (e.g., seek to start if needed) before calling.

rewrite_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ func ExampleRewrite() {
9494
}
9595

9696
if err := lines.Rewrite(f, fn); err != nil {
97-
f.Close() //nolint:errcheck // best effort cleanup before exit
97+
if err := f.Close(); err != nil {
98+
log.Fatal(err)
99+
}
98100
log.Fatal(err)
99101
}
100102
if err := f.Close(); err != nil {

scan_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"mz.attahri.com/code/lines"
1313
)
1414

15+
// ExampleAll demonstrates iterating over all lines from a reader.
1516
func ExampleAll() {
1617
const txt = "First line\nSecond line\nThird line"
1718

@@ -27,6 +28,7 @@ func ExampleAll() {
2728
// 3: Third line
2829
}
2930

31+
// ExampleBackward demonstrates iterating over lines in reverse order.
3032
func ExampleBackward() {
3133
const txt = "First line\nSecond line\nThird line"
3234

@@ -86,7 +88,11 @@ func TestBackward(t *testing.T) {
8688
if err != nil {
8789
t.Fatal(err)
8890
}
89-
defer f.Close() //nolint:errcheck // test cleanup
91+
defer func() {
92+
if err := f.Close(); err != nil {
93+
t.Fatal(err)
94+
}
95+
}()
9096

9197
// Collect lines in reverse
9298
var reverse []string

0 commit comments

Comments
 (0)