package cli import ( "fmt" "log" "gogs.inhome.blapointe.com/ana-ledger/src/ledger" ) type Query struct{} func BuildQuery(args args) (ledger.Like, error) { var result ledger.Like var err error func() { defer func() { if err := recover(); err != nil { err = fmt.Errorf("panicked: %v", err) } }() result, err = buildQuery(args) }() return result, err } func buildQuery(args args) (ledger.Like, error) { likeName := func(s string) ledger.Like { return ledger.LikeName(s) } andLike := func(a, b ledger.Like) ledger.Like { return (ledger.Likes{a, b}).All } orLike := func(a, b ledger.Like) ledger.Like { return (ledger.Likes{a, b}).Any } notLike := func(a ledger.Like) ledger.Like { return ledger.LikeNot(a) } if !args.more() { return likeName(""), nil } like := likeName("ajskfdlsjfkdasj") for args.more() { switch args.peek() { case "and": args.pop() var like ledger.Like switch args.peek() { case "not": args.pop() log.Println("and not", args.peek()) like = notLike(likeName(args.pop())) default: log.Println("and ", args.peek()) like = likeName(args.pop()) } like = andLike(like, like) case "not": args.pop() log.Println("or not ", args.peek()) like = orLike(like, notLike( likeName(args.pop()), )) default: log.Println("or ", args.peek()) like = orLike(like, likeName(args.pop()), ) } } return like, nil } type args []string func (args *args) pop() string { if !args.more() { panic("expected more arguments") } first := "" if len(*args) > 0 { first = (*args)[0] *args = (*args)[1:] } return first } func (args *args) peek() string { if len(*args) == 0 { return "" } return (*args)[0] } func (args *args) more() bool { return len(*args) > 0 }