/
easycomp.go
88 lines (72 loc) · 1.55 KB
/
easycomp.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
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
package easycomp
type Argument interface {
Children() []Argument
Complete([]string) []string
Match([]string) bool
String() string
}
type Arguments []Argument
func (a *Arguments) Children() []Argument {
return *a
}
func (a *Arguments) Append(arg Argument) {
*a = append(*a, arg)
}
func (a *Arguments) Complete(words []string) []string {
reply := make([]string, 0)
for _, arg := range *a {
if arg.Match(words) {
reply = append(reply, arg.Complete(words)...)
}
}
return reply
}
func (a *Arguments) Match(_ []string) bool {
return len(*a) > 0
}
func (a *Arguments) String() string {
return ""
}
type Transform struct {
Argument
fn func([]string) []string
}
func NewTransform(arg Argument, fn func([]string) []string) *Transform {
return &Transform{Argument: arg, fn: fn}
}
func Nest(arg Argument, depth int) Argument {
if depth == 0 {
return arg
}
return NewTransform(
Nest(arg, depth-1),
func(words []string) []string {
if len(words) < 1 {
return []string{}
}
return words[1:]
},
)
}
func (t *Transform) Transform(words []string) []string {
return t.fn(words)
}
func (t *Transform) Complete(words []string) []string {
return t.Argument.Complete(t.Transform(words))
}
func (t *Transform) Match(words []string) bool {
return len(t.Transform(words)) >= 1
}
type Condition struct {
Argument
match func([]string) bool
}
func NewCondition(arg Argument, match func([]string) bool) *Condition {
return &Condition{
Argument: arg,
match: match,
}
}
func (c *Condition) Match(words []string) bool {
return c.match(words)
}