]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/hil/scanner/peeker.go
Initial transfer of provider code
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / hil / scanner / peeker.go
1 package scanner
2
3 // Peeker is a utility that wraps a token channel returned by Scan and
4 // provides an interface that allows a caller (e.g. the parser) to
5 // work with the token stream in a mode that allows one token of lookahead,
6 // and provides utilities for more convenient processing of the stream.
7 type Peeker struct {
8 ch <-chan *Token
9 peeked *Token
10 }
11
12 func NewPeeker(ch <-chan *Token) *Peeker {
13 return &Peeker{
14 ch: ch,
15 }
16 }
17
18 // Peek returns the next token in the stream without consuming it. A
19 // subsequent call to Read will return the same token.
20 func (p *Peeker) Peek() *Token {
21 if p.peeked == nil {
22 p.peeked = <-p.ch
23 }
24 return p.peeked
25 }
26
27 // Read consumes the next token in the stream and returns it.
28 func (p *Peeker) Read() *Token {
29 token := p.Peek()
30
31 // As a special case, we will produce the EOF token forever once
32 // it is reached.
33 if token.Type != EOF {
34 p.peeked = nil
35 }
36
37 return token
38 }
39
40 // Close ensures that the token stream has been exhausted, to prevent
41 // the goroutine in the underlying scanner from leaking.
42 //
43 // It's not necessary to call this if the caller reads the token stream
44 // to EOF, since that implicitly closes the scanner.
45 func (p *Peeker) Close() {
46 for _ = range p.ch {
47 // discard
48 }
49 // Install a synthetic EOF token in 'peeked' in case someone
50 // erroneously calls Peek() or Read() after we've closed.
51 p.peeked = &Token{
52 Type: EOF,
53 Content: "",
54 }
55 }