Skip to content

Commit 223b4c4

Browse files
authored
feat: integrating numscript rewrite (#503)
1 parent e5594ac commit 223b4c4

24 files changed

+1062
-799
lines changed

cmd/serve.go

+11-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
package cmd
22

33
import (
4+
"net/http"
5+
"net/http/pprof"
6+
"time"
7+
48
apilib "github.com/formancehq/go-libs/v2/api"
59
"github.com/formancehq/go-libs/v2/health"
610
"github.com/formancehq/go-libs/v2/httpserver"
711
"github.com/formancehq/go-libs/v2/otlp"
812
"github.com/formancehq/ledger/internal/storage/driver"
913
"github.com/go-chi/chi/v5"
1014
"go.opentelemetry.io/otel/sdk/metric"
11-
"net/http"
12-
"net/http/pprof"
13-
"time"
15+
16+
"github.com/formancehq/ledger/internal/bus"
1417

1518
"github.com/formancehq/go-libs/v2/auth"
1619
"github.com/formancehq/go-libs/v2/aws/iam"
@@ -19,7 +22,7 @@ import (
1922
"github.com/formancehq/go-libs/v2/otlp/otlptraces"
2023
"github.com/formancehq/go-libs/v2/publish"
2124
"github.com/formancehq/ledger/internal/api"
22-
"github.com/formancehq/ledger/internal/bus"
25+
2326
ledgercontroller "github.com/formancehq/ledger/internal/controller/ledger"
2427
systemcontroller "github.com/formancehq/ledger/internal/controller/system"
2528
"github.com/formancehq/ledger/internal/storage"
@@ -37,6 +40,7 @@ const (
3740
AutoUpgradeFlag = "auto-upgrade"
3841
ExperimentalFeaturesFlag = "experimental-features"
3942
BulkMaxSizeFlag = "bulk-max-size"
43+
NumscriptInterpreterFlag = "experimental-numscript-interpreter"
4044
)
4145

4246
func NewServeCommand() *cobra.Command {
@@ -55,6 +59,7 @@ func NewServeCommand() *cobra.Command {
5559
if err != nil {
5660
return err
5761
}
62+
numscriptInterpreter, _ := cmd.Flags().GetBool(NumscriptInterpreterFlag)
5863

5964
bulkMaxSize, err := cmd.Flags().GetInt(BulkMaxSizeFlag)
6065
if err != nil {
@@ -71,6 +76,7 @@ func NewServeCommand() *cobra.Command {
7176
bunconnect.Module(*connectionOptions, service.IsDebug(cmd)),
7277
storage.NewFXModule(serveConfiguration.autoUpgrade),
7378
systemcontroller.NewFXModule(systemcontroller.ModuleConfiguration{
79+
NumscriptInterpreter: numscriptInterpreter,
7480
NSCacheConfiguration: ledgercontroller.CacheConfiguration{
7581
MaxCount: serveConfiguration.numscriptCacheMaxCount,
7682
},
@@ -120,6 +126,7 @@ func NewServeCommand() *cobra.Command {
120126
cmd.Flags().String(BindFlag, "0.0.0.0:3068", "API bind address")
121127
cmd.Flags().Bool(ExperimentalFeaturesFlag, false, "Enable features configurability")
122128
cmd.Flags().Int(BulkMaxSizeFlag, api.DefaultBulkMaxSize, "Bulk max size (default 100)")
129+
cmd.Flags().Bool(NumscriptInterpreterFlag, false, "Enable experimental numscript rewrite")
123130

124131
service.AddFlags(cmd.Flags())
125132
bunconnect.AddFlags(cmd.Flags())

docs/api/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -3189,6 +3189,8 @@ Authorization ( Scopes: ledger:write )
31893189
|*anonymous*|IMPORT|
31903190
|*anonymous*|TIMEOUT|
31913191
|*anonymous*|BULK_SIZE_EXCEEDED|
3192+
|*anonymous*|INTERPRETER_PARSE|
3193+
|*anonymous*|INTERPRETER_RUNTIME|
31923194

31933195
<h2 id="tocS_V2LedgerInfoResponse">V2LedgerInfoResponse</h2>
31943196
<!-- backwards compatibility -->

go.mod

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/formancehq/ledger
22

3-
go 1.22.0
3+
go 1.22.1
44

55
toolchain go1.22.7
66

@@ -14,19 +14,22 @@ require (
1414
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10
1515
github.com/bluele/gcache v0.0.2
1616
github.com/formancehq/go-libs/v2 v2.0.1-0.20241022185745-110c95803b63
17+
github.com/formancehq/numscript v0.0.9-0.20241009144012-1150c14a1417
1718
github.com/formancehq/stack/ledger/client v0.0.0-00010101000000-000000000000
1819
github.com/go-chi/chi/v5 v5.1.0
1920
github.com/go-chi/cors v1.2.1
2021
github.com/google/go-cmp v0.6.0
2122
github.com/google/uuid v1.6.0
2223
github.com/invopop/jsonschema v0.12.0
24+
github.com/jackc/pgx/v5 v5.7.1
2325
github.com/jamiealquiza/tachymeter v2.0.0+incompatible
2426
github.com/logrusorgru/aurora v2.0.3+incompatible
2527
github.com/nats-io/nats.go v1.37.0
2628
github.com/onsi/ginkgo/v2 v2.20.2
2729
github.com/onsi/gomega v1.34.2
2830
github.com/ory/dockertest/v3 v3.11.0
2931
github.com/pborman/uuid v1.2.1
32+
github.com/pkg/errors v0.9.1
3033
github.com/shomali11/xsql v0.0.0-20190608141458-bf76292144df
3134
github.com/spf13/cobra v1.8.1
3235
github.com/spf13/pflag v1.0.5
@@ -39,7 +42,7 @@ require (
3942
go.opentelemetry.io/otel/metric v1.31.0
4043
go.opentelemetry.io/otel/sdk/metric v1.31.0
4144
go.opentelemetry.io/otel/trace v1.31.0
42-
go.uber.org/fx v1.22.2
45+
go.uber.org/fx v1.23.0
4346
go.uber.org/mock v0.4.0
4447
golang.org/x/oauth2 v0.23.0
4548
golang.org/x/sync v0.8.0
@@ -56,6 +59,7 @@ require (
5659
github.com/ThreeDotsLabs/watermill-kafka/v3 v3.0.5 // indirect
5760
github.com/ThreeDotsLabs/watermill-nats/v2 v2.1.1 // indirect
5861
github.com/ajg/form v1.5.1 // indirect
62+
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
5963
github.com/aws/aws-msk-iam-sasl-signer-go v1.0.0 // indirect
6064
github.com/aws/aws-sdk-go-v2 v1.32.2 // indirect
6165
github.com/aws/aws-sdk-go-v2/config v1.27.43 // indirect
@@ -111,7 +115,6 @@ require (
111115
github.com/inconshreveable/mousetrap v1.1.0 // indirect
112116
github.com/jackc/pgpassfile v1.0.0 // indirect
113117
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
114-
github.com/jackc/pgx/v5 v5.7.1 // indirect
115118
github.com/jackc/puddle/v2 v2.2.2 // indirect
116119
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
117120
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
@@ -137,7 +140,6 @@ require (
137140
github.com/opencontainers/image-spec v1.1.0 // indirect
138141
github.com/opencontainers/runc v1.1.14 // indirect
139142
github.com/pierrec/lz4/v4 v4.1.21 // indirect
140-
github.com/pkg/errors v0.9.1 // indirect
141143
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
142144
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
143145
github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect
@@ -182,6 +184,7 @@ require (
182184
go.uber.org/multierr v1.11.0 // indirect
183185
go.uber.org/zap v1.27.0 // indirect
184186
golang.org/x/crypto v0.28.0 // indirect
187+
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
185188
golang.org/x/net v0.30.0 // indirect
186189
golang.org/x/sys v0.26.0 // indirect
187190
golang.org/x/text v0.19.0 // indirect

go.sum

+24-6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ github.com/alitto/pond v1.9.2 h1:9Qb75z/scEZVCoSU+osVmQ0I0JOeLfdTDafrbcJ8CLs=
2424
github.com/alitto/pond v1.9.2/go.mod h1:xQn3P/sHTYcU/1BR3i86IGIrilcrGC2LiS+E2+CJWsI=
2525
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves=
2626
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
27+
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
28+
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
2729
github.com/aws/aws-msk-iam-sasl-signer-go v1.0.0 h1:UyjtGmO0Uwl/K+zpzPwLoXzMhcN9xmnR2nrqJoBrg3c=
2830
github.com/aws/aws-msk-iam-sasl-signer-go v1.0.0/go.mod h1:TJAXuFs2HcMib3sN5L0gUC+Q01Qvy3DemvA55WuC+iA=
2931
github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI=
@@ -95,14 +97,18 @@ github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
9597
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
9698
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
9799
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
98-
github.com/formancehq/go-libs/v2 v2.0.1-0.20241017152835-2c30f563ab46 h1:8wZtnWSIYNV7DwD0Jr4HsbcRgezOrgDJ2Q0w9ABieKc=
99-
github.com/formancehq/go-libs/v2 v2.0.1-0.20241017152835-2c30f563ab46/go.mod h1:LgxayMN6wgAQbkB3ioBDTHOVMKp1rC6Q55M1CvG44xY=
100-
github.com/formancehq/go-libs/v2 v2.0.1-0.20241017153232-1a62cecf1a61 h1:GSIhsdo/YXuZXI4q8xA8IrdOkkjfFp6O+DiNywk8s8U=
101-
github.com/formancehq/go-libs/v2 v2.0.1-0.20241017153232-1a62cecf1a61/go.mod h1:LgxayMN6wgAQbkB3ioBDTHOVMKp1rC6Q55M1CvG44xY=
102100
github.com/formancehq/go-libs/v2 v2.0.1-0.20241022185745-110c95803b63 h1:DN6gDFwh3zO9VwV6Nt2tj4/BEecyfWfOdHp1YYJ5sBA=
103101
github.com/formancehq/go-libs/v2 v2.0.1-0.20241022185745-110c95803b63/go.mod h1:LgxayMN6wgAQbkB3ioBDTHOVMKp1rC6Q55M1CvG44xY=
102+
github.com/formancehq/numscript v0.0.9-0.20241009144012-1150c14a1417 h1:LOd5hxnXDIBcehFrpW1OnXk+VSs0yJXeu1iAOO+Hji4=
103+
github.com/formancehq/numscript v0.0.9-0.20241009144012-1150c14a1417/go.mod h1:btuSv05cYwi9BvLRxVs5zrunU+O1vTgigG1T6UsawcY=
104104
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
105105
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
106+
github.com/gkampitakis/ciinfo v0.3.0 h1:gWZlOC2+RYYttL0hBqcoQhM7h1qNkVqvRCV1fOvpAv8=
107+
github.com/gkampitakis/ciinfo v0.3.0/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
108+
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
109+
github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=
110+
github.com/gkampitakis/go-snaps v0.5.4 h1:GX+dkKmVsRenz7SoTbdIEL4KQARZctkMiZ8ZKprRwT8=
111+
github.com/gkampitakis/go-snaps v0.5.4/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y=
106112
github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec=
107113
github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
108114
github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
@@ -216,6 +222,8 @@ github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMD
216222
github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
217223
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
218224
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
225+
github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=
226+
github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
219227
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
220228
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
221229
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@@ -299,6 +307,14 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
299307
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
300308
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
301309
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
310+
github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
311+
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
312+
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
313+
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
314+
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
315+
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
316+
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
317+
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
302318
github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU=
303319
github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=
304320
github.com/tklauser/numcpus v0.9.0 h1:lmyCHtANi8aRUgkckBgoDk1nHCux3n2cgkJLXdQGPDo=
@@ -385,8 +401,8 @@ go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeX
385401
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
386402
go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw=
387403
go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
388-
go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw=
389-
go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU=
404+
go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg=
405+
go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU=
390406
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
391407
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
392408
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
@@ -402,6 +418,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
402418
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
403419
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
404420
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
421+
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
422+
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
405423
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
406424
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
407425
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=

internal/api/v2/controllers_bulk.go

+4
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ func ProcessBulk(
115115
code = ErrNoPostings
116116
case errors.Is(err, ledgercontroller.ErrTransactionReferenceConflict{}):
117117
code = ErrConflict
118+
case errors.Is(err, ledgercontroller.ErrParsing{}):
119+
code = ErrInterpreterParse
120+
case errors.Is(err, ledgercontroller.ErrRuntime{}):
121+
code = ErrInterpreterRuntime
118122
default:
119123
code = api.ErrorInternal
120124
}

internal/api/v2/controllers_transactions_create.go

+6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import (
77
ledgercontroller "github.com/formancehq/ledger/internal/controller/ledger"
88

99
"errors"
10+
1011
"github.com/formancehq/go-libs/v2/api"
12+
1113
"github.com/formancehq/ledger/internal/api/common"
1214
)
1315

@@ -50,6 +52,10 @@ func createTransaction(w http.ResponseWriter, r *http.Request) {
5052
api.WriteErrorResponse(w, http.StatusConflict, ErrConflict, err)
5153
case errors.Is(err, ledgercontroller.ErrInvalidIdempotencyInput{}):
5254
api.BadRequest(w, ErrValidation, err)
55+
case errors.Is(err, ledgercontroller.ErrParsing{}):
56+
api.BadRequest(w, ErrInterpreterParse, err)
57+
case errors.Is(err, ledgercontroller.ErrRuntime{}):
58+
api.BadRequest(w, ErrInterpreterRuntime, err)
5359
default:
5460
common.HandleCommonErrors(w, r, err)
5561
}

internal/api/v2/errors.go

+3
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@ const (
99
ErrCompilationFailed = "COMPILATION_FAILED"
1010
ErrMetadataOverride = "METADATA_OVERRIDE"
1111
ErrBulkSizeExceeded = "BULK_SIZE_EXCEEDED"
12+
13+
ErrInterpreterParse = "INTERPRETER_PARSE"
14+
ErrInterpreterRuntime = "INTERPRETER_RUNTIME"
1215
)

internal/controller/ledger/errors.go

+30
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66

77
"github.com/formancehq/go-libs/v2/platform/postgres"
8+
"github.com/formancehq/numscript"
89

910
"github.com/formancehq/ledger/internal/machine"
1011

@@ -188,6 +189,35 @@ func newErrCompilationFailed(err error) ErrCompilationFailed {
188189
}
189190
}
190191

192+
type ErrRuntime struct {
193+
Source string
194+
Inner numscript.InterpreterError
195+
}
196+
197+
func (e ErrRuntime) Error() string {
198+
return e.Inner.Error()
199+
}
200+
201+
func (e ErrRuntime) Is(err error) bool {
202+
_, ok := err.(ErrRuntime)
203+
return ok
204+
}
205+
206+
type ErrParsing struct {
207+
Source string
208+
// Precondition: Errors is not empty
209+
Errors []numscript.ParserError
210+
}
211+
212+
func (e ErrParsing) Error() string {
213+
return numscript.ParseErrorsToString(e.Errors, e.Source)
214+
}
215+
216+
func (e ErrParsing) Is(err error) bool {
217+
_, ok := err.(ErrParsing)
218+
return ok
219+
}
220+
191221
// ErrMetadataOverride is used when a metadata is defined at numscript level AND at the input level
192222
type ErrMetadataOverride struct {
193223
key string

internal/controller/ledger/numscript_parser.go

+21
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/bluele/gcache"
88
"github.com/formancehq/ledger/internal/machine/script/compiler"
9+
"github.com/formancehq/numscript"
910
)
1011

1112
//go:generate mockgen -write_source_comment=false -write_package_comment=false -source numscript_parser.go -destination numscript_parser_generated_test.go -package ledger . NumscriptParser
@@ -32,6 +33,26 @@ func NewDefaultNumscriptParser() *DefaultNumscriptParser {
3233

3334
var _ NumscriptParser = (*DefaultNumscriptParser)(nil)
3435

36+
type InterpreterNumscriptParser struct{}
37+
38+
func (n *InterpreterNumscriptParser) Parse(script string) (NumscriptRuntime, error) {
39+
result := numscript.Parse(script)
40+
errs := result.GetParsingErrors()
41+
if len(errs) != 0 {
42+
return nil, ErrParsing{
43+
Source: script,
44+
Errors: errs,
45+
}
46+
}
47+
return NewDefaultInterpreterMachineAdapter(result), nil
48+
}
49+
50+
func NewInterpreterNumscriptParser() *InterpreterNumscriptParser {
51+
return &InterpreterNumscriptParser{}
52+
}
53+
54+
var _ NumscriptParser = (*InterpreterNumscriptParser)(nil)
55+
3556
type CacheConfiguration struct {
3657
MaxCount uint
3758
}

0 commit comments

Comments
 (0)