-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathasl.go
More file actions
112 lines (92 loc) · 2.73 KB
/
asl.go
File metadata and controls
112 lines (92 loc) · 2.73 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
package parser
import (
"errors"
"slices"
)
// ASL represents an Abstract Syntax List of a gemtext document.
type ASL struct {
elems []Element
}
var aslErrs = struct {
nTooLarge error
}{
errors.New("n larger than number of elements"),
}
func NewASL(elems ...Element) ASL {
return ASL{elems: elems}
}
// Clone returns a clone of asl.
func (asl *ASL) Clone() ASL {
return ASL{elems: asl.elems}
}
// InsertFirst inserts elems at the start of the list.
func (asl *ASL) InsertFirst(elems ...Element) {
asl.elems = slices.Insert(asl.elems, 0, elems...)
}
// InsertLast inserts elems at the end of the list.
func (asl *ASL) InsertLast(elems ...Element) {
asl.elems = slices.Insert(asl.elems, len(asl.elems), elems...)
}
// InsertAfter inserts elems after the first element where f returns true. Does
// nothing if f returns false for all elements.
func (asl *ASL) InsertAfter(elems []Element, f func(Element) bool) {
i := slices.IndexFunc(asl.elems, f)
if i == -1 {
return
}
asl.elems = slices.Insert(asl.elems, i+1, elems...)
}
// InsertBefore inserts elems before the first element where f returns true.
// Does nothing if f returns false for all elements.
func (asl *ASL) InsertBefore(elems []Element, f func(Element) bool) {
i := slices.IndexFunc(asl.elems, f)
if i == -1 {
return
}
asl.elems = slices.Insert(asl.elems, i, elems...)
}
// DeleteFirst deletes the first n elements of the list. Returns an error if n
// is larger than the number of elements asl currently has.
func (asl *ASL) DeleteFirst(n uint) error {
end := 0 + int(n)
if end > len(asl.elems) {
return aslErrs.nTooLarge
}
asl.elems = slices.Delete(asl.elems, 0, end)
return nil
}
// DeleteLast deletes the last n elements of the list. Returns an error if n is
// larger than the number of elements asl currently has.
func (asl *ASL) DeleteLast(n uint) error {
end := len(asl.elems)
start := end - int(n)
if start < 0 {
return aslErrs.nTooLarge
}
asl.elems = slices.Delete(asl.elems, start, end)
return nil
}
// DeleteAll deletes all elements where f returns true. Does nothing if f
// returns false for all elements.
func (asl *ASL) DeleteAll(f func(Element) bool) {
asl.elems = slices.DeleteFunc(asl.elems, f)
}
// Replace replaces the first element where f returns true with elems. Does
// nothing if f returns false for all elements.
func (asl *ASL) Replace(elems []Element, f func(Element) bool) {
i := slices.IndexFunc(asl.elems, f)
if i == -1 {
return
}
asl.elems = slices.Replace(asl.elems, i, i+1, elems...)
}
// Visit iterates over all elements that asl has, passing each element to f.
func (asl *ASL) Visit(f func(Element)) {
for e := range slices.Values(asl.elems) {
f(e)
}
}
// Possible methods to add later:
// InsertBetween
// DeleteBetween
// ReplaceAll