/
question_mark_expr.go
69 lines (57 loc) 路 1.38 KB
/
question_mark_expr.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
package q
import (
"reflect"
"sort"
)
// QuestionMarkExpr ("?") is a special function. See Evaluate.
type QuestionMarkExpr struct{}
// "?" is a special function that can be used to show all of the possible next
// functions and accessors. This is useful when exploring data by creating the
// query interactively.
//
// For example the following query:
//
// .Individuals | ?
//
// Returns (most items removed for brevity):
//
// [
// ".AddNode",
// ".Age",
// ".AgeAt",
// ...
// ".SurroundingSimilarity",
// ".Tag",
// ".Value",
// "?",
// "Length"
// ]
//
func (e *QuestionMarkExpr) Evaluate(engine *Engine, input interface{}, args []*Statement) (interface{}, error) {
in := reflect.TypeOf(input)
if in.Kind() == reflect.Slice {
value := reflect.Zero(TypeOfSliceElement(input)).Interface()
return e.Evaluate(engine, value, nil)
}
if in.Kind() != reflect.Ptr {
in = reflect.New(in).Type()
}
options := []string{}
// Accessors
for i := 0; i < in.NumMethod(); i++ {
methodName := "." + in.Method(i).Name
options = append(options, methodName)
}
// Functions
for function := range Functions {
options = append(options, function)
}
// Variables
for _, statement := range engine.Statements {
if statement.VariableName != "" {
options = append(options, statement.VariableName)
}
}
sort.Strings(options)
return options, nil
}