nicer but my fsm is wrong if i want to bundle ands first
All checks were successful
cicd / ci (push) Successful in 3m29s
All checks were successful
cicd / ci (push) Successful in 3m29s
This commit is contained in:
106
cmd/cli/query.go
106
cmd/cli/query.go
@@ -2,7 +2,7 @@ package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
|
||||
"gogs.inhome.blapointe.com/ana-ledger/src/ledger"
|
||||
)
|
||||
@@ -10,67 +10,91 @@ import (
|
||||
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
|
||||
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 buildOneQuery(args args) (ledger.Like, error) {
|
||||
word, ok := args.peek()
|
||||
if !ok {
|
||||
return nil, io.EOF
|
||||
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)
|
||||
}
|
||||
|
||||
likes := make(ledger.Likes, 0)
|
||||
if !args.more() {
|
||||
return likeName(""), nil
|
||||
}
|
||||
like := likeName("ajskfdlsjfkdasj")
|
||||
|
||||
for _, ok := args.peek(); ok; _, ok = args.peek() {
|
||||
switch word {
|
||||
for args.more() {
|
||||
switch args.peek() {
|
||||
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
|
||||
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())
|
||||
}
|
||||
likes = append(likes, like)
|
||||
like = andLike(like, like)
|
||||
case "not":
|
||||
args.pop()
|
||||
like, err := buildOneQuery(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
likes = append(likes, like)
|
||||
log.Println("or not ", args.peek())
|
||||
like = orLike(like, notLike(
|
||||
likeName(args.pop()),
|
||||
))
|
||||
default:
|
||||
return nil, io.EOF
|
||||
if next, _ := args.peek(); next != "and" {
|
||||
return likes.All, nil
|
||||
}
|
||||
log.Println("or ", args.peek())
|
||||
like = orLike(like,
|
||||
likeName(args.pop()),
|
||||
)
|
||||
}
|
||||
}
|
||||
return nil, io.EOF
|
||||
|
||||
return like, nil
|
||||
}
|
||||
|
||||
type args []string
|
||||
|
||||
func (args *args) pop() string {
|
||||
first := (*args)[0]
|
||||
*args = (*args)[1:]
|
||||
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, bool) {
|
||||
func (args *args) peek() string {
|
||||
if len(*args) == 0 {
|
||||
return "", false
|
||||
return ""
|
||||
}
|
||||
return (*args)[0], true
|
||||
return (*args)[0]
|
||||
}
|
||||
|
||||
func (args *args) more() bool {
|
||||
return len(*args) > 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user