This repository was archived by the owner on Mar 18, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprint.go
More file actions
131 lines (110 loc) · 3.69 KB
/
print.go
File metadata and controls
131 lines (110 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package sqroot
import (
"io"
"os"
"strings"
"github.com/keep94/consume2"
)
// Option represents an option for the Print, Fprint, and Sprint methods
type Option interface {
mutate(p *printerSettings)
}
// DigitsPerRow sets the number of digits per row. Zero or negative means no
// separate rows.
func DigitsPerRow(count int) Option {
return optionFunc(func(p *printerSettings) {
p.digitsPerRow = count
})
}
// DigitsPerColumn sets the number of digits per column. Zero or negative
// means no separate columns.
func DigitsPerColumn(count int) Option {
return optionFunc(func(p *printerSettings) {
p.digitsPerColumn = count
})
}
// ShowCount shows the digit count in the left margin if on is true.
func ShowCount(on bool) Option {
return optionFunc(func(p *printerSettings) {
p.showCount = on
})
}
// MissingDigit sets the character to represent a missing digit.
func MissingDigit(missingDigit rune) Option {
return optionFunc(func(p *printerSettings) {
p.missingDigit = missingDigit
})
}
func bufferSize(size int) Option {
return optionFunc(func(p *printerSettings) {
p.bufferSize = size
})
}
// Sequence represents a sequence of digits. Number pointers implement
// Sequence.
type Sequence interface {
// FullIterator returns a function that generates the digits in this
// Sequence along with their zero based positions from beginning to end.
// If there are no more digits, returned function returns false.
FullIterator() func() (Digit, bool)
// FullReverse returns a function that generates the digits in this
// Sequence along with their zero based positions from end to beginning.
// When there are no more digits, returned function returns false. If
// this Sequence happens to have an infinite number of digits, FullReverse
// runs forever.
FullReverse() func() (Digit, bool)
// WithStart returns a Sequence like this one that only has digits with
// zero based positions greater than or equal to start.
WithStart(start int) Sequence
// WithEnd returns a sequence like this one that only has digits with
// zero based positions less than end.
WithEnd(end int) Sequence
private()
}
// Fprint prints digits of s to w. Fprint returns the number of bytes written
// and any error encountered. p contains the positions of the digits to print.
// For options, the default is 50 digits per row, 5 digits per column,
// show digit count, and period (.) for missing digits.
func Fprint(w io.Writer, s Sequence, p Positions, options ...Option) (
written int, err error) {
settings := &printerSettings{
digitsPerRow: 50,
digitsPerColumn: 5,
showCount: true,
missingDigit: '.',
}
printer := newPrinter(w, p.End(), mutateSettings(options, settings))
fromSequenceWithPositions(s, p, printer)
printer.Finish()
return printer.BytesWritten(), printer.Err()
}
// Sprint works like Fprint and prints digits of s to a string.
func Sprint(s Sequence, p Positions, options ...Option) string {
var builder strings.Builder
Fprint(&builder, s, p, options...)
return builder.String()
}
// Print works like Fprint and prints digits of s to stdout.
func Print(s Sequence, p Positions, options ...Option) (
written int, err error) {
return Fprint(os.Stdout, s, p, options...)
}
func fromSequenceWithPositions(
s Sequence, p Positions, consumer consume2.Consumer[Digit]) {
iter := p.Ranges()
for pr, ok := iter(); ok; pr, ok = iter() {
consume2.FromGenerator(
s.WithStart(pr.Start).WithEnd(pr.End).FullIterator(), consumer)
}
}
type optionFunc func(p *printerSettings)
func (o optionFunc) mutate(p *printerSettings) {
o(p)
}
func mutateSettings(
options []Option, settings *printerSettings) *printerSettings {
for _, option := range options {
option.mutate(settings)
}
return settings
}