• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stephenafamo / bob / 14939098091

09 May 2025 10:59PM UTC coverage: 36.868% (-4.6%) from 41.506%
14939098091

push

github

stephenafamo
Move reusable sqlite parser components to antlrhelpers package

0 of 758 new or added lines in 12 files covered. (0.0%)

547 existing lines in 8 files now uncovered.

6533 of 17720 relevant lines covered (36.87%)

212.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

44.6
/internal/editor.go
1
package internal
2

3
import (
4
        "fmt"
5
        "slices"
6
        "strings"
7
)
8

9
type RuleType int
10

11
const (
12
        CopyRuleType RuleType = iota
13
        InsertRuleType
14
        DeleteRuleType
15
        ReplaceRuleType
16
)
17

18
func (r RuleType) String() string {
×
19
        switch r {
×
20
        case CopyRuleType:
×
21
                return "copy"
×
22
        case InsertRuleType:
×
23
                return "insert"
×
24
        case ReplaceRuleType:
×
25
                return "replace"
×
26
        case DeleteRuleType:
×
27
                return "delete"
×
28
        default:
×
29
                return "unknown"
×
30
        }
31
}
32

33
func EditString(s string, rules ...EditRule) (string, error) {
12✔
34
        return EditStringSegment(s, 0, len(s)-1, rules...)
12✔
35
}
12✔
36

37
func EditStringSegment(s string, from, to int, rules ...EditRule) (string, error) {
12✔
38
        // sort rules by priority
12✔
39
        slices.SortStableFunc(rules, func(i, j EditRule) int {
16✔
40
                iStart, _ := i.position()
4✔
41
                jStart, _ := j.position()
4✔
42

4✔
43
                if iStart != jStart {
4✔
UNCOV
44
                        return iStart - jStart
×
UNCOV
45
                }
×
46

47
                return int(i.ruleType() - j.ruleType())
4✔
48
        })
49

50
        cursor := from // current position in the original string
12✔
51
        s = s[:to+1]   // limit the string to the range
12✔
52

12✔
53
        var err error
12✔
54
        var buf strings.Builder
12✔
55

12✔
56
        for i, r := range rules {
28✔
57
                start, end := r.position()
16✔
58

16✔
59
                if start < cursor {
16✔
UNCOV
60
                        // rule starts before cursor, skip it
×
UNCOV
61
                        // fmt.Printf("Skipping rule %d: %s[%d-%d] starts before cursor(%d), %q, %#v\n", i, r.ruleType(), start, end, cursor, s[start:end], r)
×
UNCOV
62
                        continue
×
63
                }
64

65
                if end < cursor {
16✔
66
                        // rule is before cursor, skip it
×
67
                        // fmt.Printf("Skipping rule %d: %s[%d-%d] ends before cursor(%d), %q, %#v\n", i, r.ruleType(), start, end, cursor, s[start:end], r)
×
68
                        continue
×
69
                }
70

71
                if start > len(s) {
16✔
UNCOV
72
                        // rule is after the string, skip it
×
UNCOV
73
                        // fmt.Printf("Skipping rule %d: %s[%d-%d] out of bounds(%d), %q, %#v\n", i, r.ruleType(), start, end, len(s), s[start:end], r)
×
UNCOV
74
                        continue
×
75
                }
76

77
                // fmt.Printf("Applying rule %d: %s[%d-%d] cursor(%d), %q, %#v\n", i, r.ruleType(), start, end, cursor, s[start:end], r)
78

79
                buf.WriteString(s[cursor:start])
16✔
80
                cursor = start
16✔
81

16✔
82
                if err = r.edit(s, &buf); err != nil {
16✔
83
                        return "", fmt.Errorf("rule %d: cursor %d, %w", i, cursor, err)
×
84
                }
×
85

86
                cursor = min(end, len(s))
16✔
87
        }
88

89
        return buf.String() + s[cursor:], nil
12✔
90
}
91

92
type OutOfBoundsError int
93

94
func (e OutOfBoundsError) Error() string {
×
95
        return fmt.Sprintf("out of bounds: %d", int(e))
×
96
}
×
97

98
func (e OutOfBoundsError) Is(target error) bool {
×
99
        t, ok := target.(OutOfBoundsError)
×
100
        return ok && t == e
×
101
}
×
102

103
type EditRule interface {
104
        position() (int, int)
105
        ruleType() RuleType
106
        edit(source string, buf *strings.Builder) error
107
}
108

109
type deleteRule struct{ from, to int }
110

111
func (d deleteRule) position() (int, int) {
14✔
112
        return d.from, d.to + 1
14✔
113
}
14✔
114

115
func (d deleteRule) ruleType() RuleType {
4✔
116
        return DeleteRuleType
4✔
117
}
4✔
118

119
func (d deleteRule) edit(source string, buf *strings.Builder) error {
10✔
120
        return nil
10✔
121
}
10✔
122

123
func Delete(from, to int) deleteRule {
12✔
124
        return deleteRule{from, to}
12✔
125
}
12✔
126

127
type insertRule struct {
128
        pos     int
129
        content func() string
130
}
131

132
func (i insertRule) position() (int, int) {
10✔
133
        return i.pos, i.pos
10✔
134
}
10✔
135

136
func (i insertRule) ruleType() RuleType {
4✔
137
        return InsertRuleType
4✔
138
}
4✔
139

140
func (i insertRule) edit(source string, buf *strings.Builder) error {
8✔
141
        if _, err := buf.WriteString(i.content()); err != nil {
8✔
142
                return fmt.Errorf("insert: %w", err)
×
143
        }
×
144
        return nil
8✔
145
}
146

147
func Insert(pos int, content string) insertRule {
8✔
148
        return insertRule{pos, func() string { return content }}
16✔
149
}
150

151
func InsertFromFunc(pos int, content func() string) insertRule {
×
152
        return insertRule{pos, content}
×
153
}
×
154

155
type replaceRule struct {
156
        from, to int
157
        content  func() string
158
}
159

160
func (r replaceRule) position() (int, int) {
2✔
161
        return Delete(r.from, r.to).position()
2✔
162
}
2✔
163

UNCOV
164
func (r replaceRule) ruleType() RuleType {
×
UNCOV
165
        return ReplaceRuleType
×
UNCOV
166
}
×
167

168
func (r replaceRule) edit(source string, buf *strings.Builder) error {
2✔
169
        var err error
2✔
170
        if err = Insert(r.from, r.content()).edit(source, buf); err != nil {
2✔
171
                return fmt.Errorf("replace: %w", err)
×
172
        }
×
173

174
        if err = Delete(r.from, r.to).edit(source, buf); err != nil {
2✔
175
                return fmt.Errorf("replace: %w", err)
×
176
        }
×
177

178
        return nil
2✔
179
}
180

181
func Replace(from, to int, content string) replaceRule {
2✔
182
        return replaceRule{from, to, func() string { return content }}
4✔
183
}
184

UNCOV
185
func ReplaceFromFunc(from, to int, content func() string) replaceRule {
×
UNCOV
186
        return replaceRule{from, to, content}
×
UNCOV
187
}
×
188

189
type callbackRule struct {
190
        EditRule
191
        callbacks []func(start, end int, before, after string) error
192
}
193

UNCOV
194
func (r callbackRule) edit(source string, buf *strings.Builder) error {
×
UNCOV
195
        start := buf.Len()
×
UNCOV
196

×
UNCOV
197
        ruleStart, ruleEnd := r.EditRule.position()
×
UNCOV
198

×
UNCOV
199
        if err := r.EditRule.edit(source, buf); err != nil {
×
200
                return err
×
201
        }
×
202

UNCOV
203
        end := buf.Len()
×
UNCOV
204

×
UNCOV
205
        for _, cb := range r.callbacks {
×
UNCOV
206
                if err := cb(start, end, source[ruleStart:ruleEnd], buf.String()[start:]); err != nil {
×
207
                        return err
×
208
                }
×
209
        }
210

UNCOV
211
        return nil
×
212
}
213

UNCOV
214
func EditCallback(rule EditRule, callbacks ...func(start, end int, before, after string) error) callbackRule {
×
UNCOV
215
        return callbackRule{rule, callbacks}
×
UNCOV
216
}
×
217

UNCOV
218
func RecordPoints(oldStart, oldEnd int, callbacks ...func(start, end int) error) []EditRule {
×
UNCOV
219
        firstPoint := 0
×
UNCOV
220
        return []EditRule{
×
UNCOV
221
                EditCallback(
×
UNCOV
222
                        Insert(oldStart, ""),
×
UNCOV
223
                        func(start int, _ int, _, _ string) error { firstPoint = start; return nil },
×
224
                ),
225
                EditCallback(
226
                        Insert(oldEnd+1, ""),
UNCOV
227
                        func(_, end int, _, content string) error {
×
UNCOV
228
                                for _, cb := range callbacks {
×
UNCOV
229
                                        if err := cb(firstPoint, end); err != nil {
×
230
                                                return err
×
231
                                        }
×
232
                                }
UNCOV
233
                                return nil
×
234
                        },
235
                ),
236
        }
237
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc