/
charmedTag.go
51 lines (44 loc) · 1.08 KB
/
charmedTag.go
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
package charmed
import (
"errors"
"github.com/ionous/tell/charm"
)
// determine whether the first line of the heredoc has a custom closing tag
func decoodeTag(tag *[]rune) charm.State {
type headerStage int
const (
waitingForRedirect headerStage = iota
waitingForTag
haveTag
)
var buf runeSlice
var stage headerStage
return decodeHeaderHere(&buf, func(header headerToken) (err error) {
switch header {
case headerWord:
if stage == haveTag {
err = errors.New("expected an end tag marker with one word")
} else if stage == waitingForTag {
*tag, buf = buf, nil
stage = haveTag
} else {
buf = buf[:0] // reset
}
case headerRedirect:
if stage != waitingForRedirect {
err = errors.New("expected at most once end tag maker")
} else {
stage = waitingForTag
}
buf = buf[:0] // reset
}
return
})
}
// accumulate runes without converting to a string
// ( b/c the heredoc decoder searches for the closing tag rune by rune )
type runeSlice []rune
func (rs *runeSlice) WriteRune(q rune) (_ int, _ error) {
(*rs) = append(*rs, q)
return
}