ana-ledger/cmd/cli/query.go

101 lines
1.8 KiB
Go

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
}