From d7edc1ff1d1099a11465c3fe5ef477b4d032fd01 Mon Sep 17 00:00:00 2001 From: Bel LaPointe <153096461+breel-render@users.noreply.github.com> Date: Fri, 13 Dec 2024 10:49:19 -0700 Subject: [PATCH] nicer but my fsm is wrong if i want to bundle ands first --- cmd/cli/main.go | 62 ++++++--------------------- cmd/cli/query.go | 106 +++++++++++++++++++++++++++++------------------ 2 files changed, 78 insertions(+), 90 deletions(-) diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 4ab66ed..0aabd00 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -40,31 +40,10 @@ func Main() { } cmd := positional[0] - q, err := BuildQuery(positional) + q, err := BuildQuery(positional[1:]) if err != nil { panic(err) } - panic(q) - - likePattern := "" - notLikePattern := "" - i := 1 - for i < len(positional) { - switch positional[i] { - case "not": - _ = notLikePattern - panic(positional[i:]) - case "and": - panic(positional[i:]) - default: - if likePattern == "" { - likePattern = positional[i] - } else { - likePattern = fmt.Sprintf("%s|%s", likePattern, positional[i]) - } - } - i += 1 - } deltas, err := ledgerFiles.Deltas() if err != nil { @@ -86,37 +65,22 @@ func Main() { switch cmd[:3] { case "bal": - balances := deltas.Balances() - if likePattern != "" { - balances = balances.Like(likePattern) - } - if notLikePattern != "" { - balances = balances.NotLike(notLikePattern) - } + /* + balances := deltas.Balances() + if likePattern != "" { + balances = balances.Like(likePattern) + } + if notLikePattern != "" { + balances = balances.NotLike(notLikePattern) + } - FPrintBalances(os.Stdout, "", balances, nil) + FPrintBalances(os.Stdout, "", balances, nil) + */ case "reg": transactions := deltas.Transactions() - likes := []ledger.Like{} - if likePattern != "" { - like := ledger.LikeName(likePattern) - transactions = transactions.Like(like) - if config.Query.Reverse { - like = ledger.LikeNot(like) - } - likes = append(likes, like) - } - if notLikePattern != "" { - like := ledger.NotLikeName(notLikePattern) - transactions = transactions.NotLike(like) - if config.Query.Reverse { - like = ledger.LikeNot(like) - } - likes = append(likes, like) - } for i, transaction := range transactions { - balances := ledger.Deltas(transaction).Like(likes...).Balances() + balances := ledger.Deltas(transaction).Like(q).Balances() shouldPrint := false shouldPrint = shouldPrint || len(balances) > 2 if config.Query.NoExchanging { @@ -129,7 +93,7 @@ func Main() { } if shouldPrint { fmt.Printf("%s\t%s\n", transaction[0].Date, transaction[0].Description) - FPrintBalances(os.Stdout, "\t\t", balances, transactions[:i+1].Deltas().Like(likes...).Balances()) + FPrintBalances(os.Stdout, "\t\t", balances, transactions[:i+1].Deltas().Like(q).Balances()) } } default: diff --git a/cmd/cli/query.go b/cmd/cli/query.go index a1b2f73..1701997 100644 --- a/cmd/cli/query.go +++ b/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 }