package cli import ( "fmt" "io" "gogs.inhome.blapointe.com/ana-ledger/src/ledger" ) type Query struct{} func BuildQuery(args args) (ledger.Like, error) { likes := make(ledger.Likes, 0) for _, ok := args.peek(); ok; _, ok = args.peek() { like, err := buildOneQuery(args) if err != nil { return nil, err } likes = append(likes, like) } return likes.Any, nil } func buildOneQuery(args args) (ledger.Like, error) { word, ok := args.peek() if !ok { return nil, io.EOF } likes := make(ledger.Likes, 0) for _, ok := args.peek(); ok; _, ok = args.peek() { switch word { case "and": if len(likes) == 0 { return nil, fmt.Errorf("and without predicate") } args.pop() like, err := buildOneQuery(args) if err != nil { return nil, err } likes = append(likes, like) case "not": args.pop() like, err := buildOneQuery(args) if err != nil { return nil, err } likes = append(likes, like) default: return nil, io.EOF if next, _ := args.peek(); next != "and" { return likes.All, nil } } } return nil, io.EOF } type args []string func (args *args) pop() string { first := (*args)[0] *args = (*args)[1:] return first } func (args *args) peek() (string, bool) { if len(*args) == 0 { return "", false } return (*args)[0], true }