105 lines
1.9 KiB
Go
105 lines
1.9 KiB
Go
package cli
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
|
|
"gogs.inhome.blapointe.com/ana-ledger/src/ledger"
|
|
)
|
|
|
|
type Query struct{}
|
|
|
|
func BuildQuery(config Config, 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(config, args)
|
|
}()
|
|
return result, err
|
|
}
|
|
|
|
func buildQuery(config Config, 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()),
|
|
)
|
|
}
|
|
}
|
|
|
|
if config.Query.With != "" {
|
|
like = andLike(like, ledger.LikeWith(config.Query.With))
|
|
}
|
|
|
|
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
|
|
}
|