From 69dfe59744593c40f63475d6424edcb455050dc8 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Apr 2026 20:33:32 +0000 Subject: [PATCH 1/2] grammar: move static jsonic options into csv-grammar.jsonic Follow the jsonicjs/ini pattern by declaring rule.start, lex.emptyResult, error.csv_*, and hint.csv_* as options: entries in the embedded grammar rather than in plugin code. Dynamic options (tokens, IGNORE, number/value/comment/line/fixed) stay in code because they depend on user-supplied plugin options. go/csv.go: extract the "options" key from parseGrammarText into gs.OptionsMap so grammar-level options flow through. Apply jsonicOptions after j.Grammar() so its TokenSet override survives Grammar's internal SetOptions (which resets IgnoreSet to defaults). https://claude.ai/code/session_016bybofWANz4FrWyur18uad --- csv-grammar.jsonic | 11 +++++++++++ go/csv.go | 37 +++++++++++++++++++++++-------------- src/csv.ts | 29 +++++++++++++---------------- 3 files changed, 47 insertions(+), 30 deletions(-) diff --git a/csv-grammar.jsonic b/csv-grammar.jsonic index b7c599b..a1db913 100644 --- a/csv-grammar.jsonic +++ b/csv-grammar.jsonic @@ -14,6 +14,17 @@ # non-strict prepends to existing defaults to preserve JSON parsing). { + options: rule: { start: csv } + options: lex: { emptyResult: [] } + options: error: { + csv_extra_field: 'unexpected extra field value: $fsrc' + csv_missing_field: 'missing field' + } + options: hint: { + csv_extra_field: 'Row $row has too many fields (the first of which is: $fsrc). Only $len\nfields per row are expected.' + csv_missing_field: 'Row $row has too few fields. $len fields per row are expected.' + } + rule: csv: open: [ { s: '#ZZ' } { s: '#LN' p: newline c: '@not-record-empty' } diff --git a/go/csv.go b/go/csv.go index c6a0daa..25abd86 100644 --- a/go/csv.go +++ b/go/csv.go @@ -30,6 +30,17 @@ const grammarText = ` # non-strict prepends to existing defaults to preserve JSON parsing). { + options: rule: { start: csv } + options: lex: { emptyResult: [] } + options: error: { + csv_extra_field: 'unexpected extra field value: $fsrc' + csv_missing_field: 'missing field' + } + options: hint: { + csv_extra_field: 'Row $row has too many fields (the first of which is: $fsrc). Only $len\nfields per row are expected.' + csv_missing_field: 'Row $row has too few fields. $len fields per row are expected.' + } + rule: csv: open: [ { s: '#ZZ' } { s: '#LN' p: newline c: '@not-record-empty' } @@ -132,9 +143,9 @@ func Csv(j *jsonic.Jsonic, options map[string]any) error { fieldSep := toString(fieldOpts["separation"]) recordSep := toString(recordOpts["separators"]) - // Jsonic option overrides (matching TS jsonicOptions). + // Jsonic option overrides (matching TS jsonicOptions). Static options + // (rule.start, lex.emptyResult, error, hint) live in csv-grammar.jsonic. jsonicOptions := jsonic.Options{ - Rule: &jsonic.RuleOptions{Start: "csv"}, Number: &jsonic.NumberOptions{ Lex: boolPtr(opt_number), }, @@ -144,20 +155,9 @@ func Csv(j *jsonic.Jsonic, options map[string]any) error { Comment: &jsonic.CommentOptions{ Lex: boolPtr(comment), }, - Lex: &jsonic.LexOptions{ - EmptyResult: []any{}, - }, Line: &jsonic.LineOptions{ Single: boolPtr(record_empty), }, - Error: map[string]string{ - "csv_extra_field": "unexpected extra field value: $fsrc", - "csv_missing_field": "missing field", - }, - Hint: map[string]string{ - "csv_extra_field": "Row $row has too many fields (the first of which is: $fsrc). Only $len\nfields per row are expected.", - "csv_missing_field": "Row $row has too few fields. $len fields per row are expected.", - }, } if strict { @@ -200,7 +200,9 @@ func Csv(j *jsonic.Jsonic, options map[string]any) error { jsonicOptions.TokenSet = map[string][]string{"IGNORE": {"#SP", "#CM"}} } - j.SetOptions(jsonicOptions) + // jsonicOptions is applied AFTER Grammar() below so its TokenSet + // override survives Grammar's internal SetOptions (which resets IgnoreSet + // to defaults in buildConfig when the new options omit TokenSet). // Named function references for declarative grammar definition. emptyField := toString(fieldOpts["empty"]) @@ -435,6 +437,10 @@ func Csv(j *jsonic.Jsonic, options map[string]any) error { return fmt.Errorf("failed to apply csv grammar: %w", err) } + // Apply per-instance option overrides after Grammar so TokenSet/Fixed + // tokens survive Grammar's internal SetOptions. + j.SetOptions(jsonicOptions) + // Rules list, elem, val are modified in code rather than the grammar file, // because in non-strict mode the default jsonic alternatives must be preserved // to support embedded JSON values like [1,2] and {x:1}. @@ -661,6 +667,9 @@ func parseGrammarText(text string, refs map[jsonic.FuncRef]any) (*jsonic.Grammar return nil, fmt.Errorf("grammar text did not parse to a map") } gs := &jsonic.GrammarSpec{Ref: refs} + if optionsMap, ok := parsedMap["options"].(map[string]any); ok { + gs.OptionsMap = optionsMap + } ruleMap, ok := parsedMap["rule"].(map[string]any) if !ok { return gs, nil diff --git a/src/csv.ts b/src/csv.ts index e117378..8e5f264 100644 --- a/src/csv.ts +++ b/src/csv.ts @@ -57,6 +57,17 @@ const grammarText = ` # non-strict prepends to existing defaults to preserve JSON parsing). { + options: rule: { start: csv } + options: lex: { emptyResult: [] } + options: error: { + csv_extra_field: 'unexpected extra field value: $fsrc' + csv_missing_field: 'missing field' + } + options: hint: { + csv_extra_field: 'Row $row has too many fields (the first of which is: $fsrc). Only $len\\nfields per row are expected.' + csv_missing_field: 'Row $row has too few fields. $len fields per row are expected.' + } + rule: csv: open: [ { s: '#ZZ' } { s: '#LN' p: newline c: '@not-record-empty' } @@ -178,11 +189,9 @@ const Csv: Plugin = (jsonic: Jsonic, options: CsvOptions) => { token['#CA'] = options.field.separation } - // Jsonic option overrides. + // Jsonic option overrides. Static options (rule.start, lex.emptyResult, + // error, hint) live in csv-grammar.jsonic. let jsonicOptions: any = { - rule: { - start: 'csv', - }, fixed: { token, }, @@ -202,9 +211,6 @@ const Csv: Plugin = (jsonic: Jsonic, options: CsvOptions) => { comment: { lex: comment, }, - lex: { - emptyResult: [], - }, line: { single: record_empty, chars: @@ -216,15 +222,6 @@ const Csv: Plugin = (jsonic: Jsonic, options: CsvOptions) => { ? undefined : options.record.separators, }, - error: { - csv_extra_field: 'unexpected extra field value: $fsrc', - csv_missing_field: 'missing field', - }, - hint: { - csv_extra_field: `Row $row has too many fields (the first of which is: $fsrc). Only $len -fields per row are expected.`, - csv_missing_field: `Row $row has too few fields. $len fields per row are expected.`, - }, } jsonic.options(jsonicOptions) From 15ce2d26c8167ccc81b4409cb66b2b564025b9f6 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 20 Apr 2026 19:35:07 +0000 Subject: [PATCH 2/2] deps+docs: bump jsonic to latest, fix Makefile typo, realign docs - jsonic/go bumped to v0.1.19; adapt RuleDefiner signature (now takes *Parser) and Token.ResolveVal(rule, ctx) - jsonic TS picked up 2.25.1 via npm install (no code changes) - Makefile: fix stray tab in 'git add go/csv.go' (was split by tab) - doc/csv-go.md: rewrite to match the real Go API (UseDefaults + Defaults map; no Parse/MakeJsonic/CsvOptions wrappers). Preserve Diataxis quadrants (tutorial/how-to/explanation/reference) and add an option-keys table plus a grammar-file explanation section - doc/csv-ts.md: add parallel grammar-file explanation section so both docs cover the TS/Go shared grammar design https://claude.ai/code/session_016bybofWANz4FrWyur18uad --- Makefile | 2 +- doc/csv-go.md | 277 +++++++++++++++++++++++++++++++------------------- doc/csv-ts.md | 12 +++ go/csv.go | 8 +- go/go.mod | 2 +- go/go.sum | 6 +- 6 files changed, 191 insertions(+), 116 deletions(-) diff --git a/Makefile b/Makefile index 55547ce..61e8aed 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ clean-go: publish-go: test-go @test -n "$(V)" || (echo "Usage: make publish-go V=x.y.z" && exit 1) sed -i '' 's/^const Version = ".*"/const Version = "$(V)"/' go/csv.go - git add go/csv .go + git add go/csv.go git commit -m "go: v$(V)" git tag go/v$(V) git push origin main go/v$(V) diff --git a/doc/csv-go.md b/doc/csv-go.md index 9c7322f..d3add30 100644 --- a/doc/csv-go.md +++ b/doc/csv-go.md @@ -4,6 +4,13 @@ A Jsonic syntax plugin that parses CSV text into Go slices of maps or slices, with support for headers, quoted fields, custom delimiters, streaming, and strict/non-strict modes. +```go +import ( + jsonic "github.com/jsonicjs/jsonic/go" + csv "github.com/jsonicjs/csv/go" +) +``` + ```bash go get github.com/jsonicjs/csv/go@latest ``` @@ -13,138 +20,172 @@ go get github.com/jsonicjs/csv/go@latest ### Parse a basic CSV file -Parse CSV text with a header row into a slice of ordered maps: +Create a Jsonic instance, register the `Csv` plugin with its +`Defaults`, and call `Parse` on the source text: ```go package main import ( "fmt" + jsonic "github.com/jsonicjs/jsonic/go" csv "github.com/jsonicjs/csv/go" ) func main() { - result, _ := csv.Parse("name,age\nAlice,30\nBob,25") + j := jsonic.Make() + j.UseDefaults(csv.Csv, csv.Defaults) + + result, _ := j.Parse("name,age\nAlice,30\nBob,25") fmt.Println(result) - // [{name:Alice age:30} {name:Bob age:25}] + // [map[age:30 name:Alice] map[age:25 name:Bob]] } ``` ### Parse CSV without headers -Return rows as slices instead of maps, with no header row: +Override the `header` and `object` option keys to return rows as +slices of fields: ```go -result, _ := csv.Parse("a,b,c\n1,2,3", csv.CsvOptions{ - Header: boolPtr(false), - Object: boolPtr(false), +j := jsonic.Make() +j.UseDefaults(csv.Csv, csv.Defaults, map[string]any{ + "header": false, + "object": false, }) + +result, _ := j.Parse("a,b,c\n1,2,3") // [[a b c] [1 2 3]] ``` ### Parse CSV with quoted fields -Double-quoted fields handle commas, newlines, and escaped quotes: +Double-quoted fields handle commas, newlines, and escaped quotes +(RFC 4180-style): ```go -result, _ := csv.Parse(`name,bio +j := jsonic.Make() +j.UseDefaults(csv.Csv, csv.Defaults) + +result, _ := j.Parse(`name,bio Alice,"Likes ""cats"" and dogs" Bob,"Line1 Line2"`) -// [{name:Alice bio:Likes "cats" and dogs} {name:Bob bio:Line1\nLine2}] +// [map[name:Alice bio:Likes "cats" and dogs] +// map[name:Bob bio:Line1\nLine2]] ``` ## How-to guides +Each option override is merged on top of `csv.Defaults` by +`UseDefaults`. Nested groups (`field`, `record`, `string`) are +themselves `map[string]any`. + ### Use a custom field delimiter -Set `Field.Separation` to use a delimiter other than comma: +Set `field.separation` to use a delimiter other than comma: ```go -result, _ := csv.Parse("name\tage\nAlice\t30", csv.CsvOptions{ - Field: &csv.FieldOptions{Separation: "\t"}, +j := jsonic.Make() +j.UseDefaults(csv.Csv, csv.Defaults, map[string]any{ + "field": map[string]any{"separation": "\t"}, }) -// [{name:Alice age:30}] + +result, _ := j.Parse("name\tage\nAlice\t30") +// [map[name:Alice age:30]] ``` ### Enable number and value parsing -By default in strict mode, all values are strings. Enable `Number` -and `Value` to parse numeric and boolean values: +By default in strict mode, all values are strings. Enable `number` +and `value` to parse numeric and boolean values: ```go -result, _ := csv.Parse("a,b,c\n1,true,null", csv.CsvOptions{ - Number: boolPtr(true), - Value: boolPtr(true), +j := jsonic.Make() +j.UseDefaults(csv.Csv, csv.Defaults, map[string]any{ + "number": true, + "value": true, }) -// [{a:1 b:true c:}] + +result, _ := j.Parse("a,b,c\n1,true,null") +// [map[a:1 b:true c:]] ``` ### Trim whitespace from fields -Enable `Trim` to remove leading and trailing whitespace from field +Enable `trim` to remove leading and trailing whitespace from field values: ```go -result, _ := csv.Parse("a , b \n 1 , 2 ", csv.CsvOptions{ - Trim: boolPtr(true), -}) -// [{a:1 b:2}] +j := jsonic.Make() +j.UseDefaults(csv.Csv, csv.Defaults, map[string]any{"trim": true}) + +result, _ := j.Parse("a , b \n 1 , 2 ") +// [map[a:1 b:2]] ``` ### Stream records as they are parsed -Use the `Stream` callback to receive records one at a time: +Supply a `stream` callback to receive records one at a time. The +plugin calls it with `"start"`, `"record"`, `"end"`, and `"error"` +events; `Parse` itself returns an empty slice: ```go var records []any - -result, _ := csv.Parse("a,b\n1,2\n3,4", csv.CsvOptions{ - Stream: func(what string, record any) { +j := jsonic.Make() +j.UseDefaults(csv.Csv, csv.Defaults, map[string]any{ + "stream": func(what string, record any) { if what == "record" { records = append(records, record) } }, }) -// result is [] (empty, records were streamed) -// records contains [{a:1 b:2}, {a:3 b:4}] + +result, _ := j.Parse("a,b\n1,2\n3,4") +// result: [] (empty, records were streamed) +// records: [map[a:1 b:2] map[a:3 b:4]] ``` ### Provide explicit field names -Set `Field.Names` when the CSV has no header row but you want +Set `field.names` when the CSV has no header row but you want map output with named fields: ```go -result, _ := csv.Parse("1,2,3\n4,5,6", csv.CsvOptions{ - Header: boolPtr(false), - Field: &csv.FieldOptions{Names: []string{"x", "y", "z"}}, +j := jsonic.Make() +j.UseDefaults(csv.Csv, csv.Defaults, map[string]any{ + "header": false, + "field": map[string]any{"names": []string{"x", "y", "z"}}, }) -// [{x:1 y:2 z:3} {x:4 y:5 z:6}] + +result, _ := j.Parse("1,2,3\n4,5,6") +// [map[x:1 y:2 z:3] map[x:4 y:5 z:6]] ``` ### Enforce exact field counts -Set `Field.Exact` to error when a row has more or fewer fields +Set `field.exact` to error when a row has more or fewer fields than the header: ```go -_, err := csv.Parse("a,b\n1,2,3", csv.CsvOptions{ - Field: &csv.FieldOptions{Exact: true}, +j := jsonic.Make() +j.UseDefaults(csv.Csv, csv.Defaults, map[string]any{ + "field": map[string]any{"exact": true}, }) + +_, err := j.Parse("a,b\n1,2,3") // err: unexpected extra field value ``` -### Create a reusable parser +### Reuse a configured parser -Use `MakeJsonic` to create a configured Jsonic instance you can -call repeatedly: +The Jsonic instance itself is reusable — call `Parse` on it as many +times as you need: ```go -j := csv.MakeJsonic(csv.CsvOptions{ - Number: boolPtr(true), -}) +j := jsonic.Make() +j.UseDefaults(csv.Csv, csv.Defaults, map[string]any{"number": true}) r1, _ := j.Parse("a,b\n1,2") r2, _ := j.Parse("x,y\n3,4") @@ -152,13 +193,29 @@ r2, _ := j.Parse("x,y\n3,4") ### Enable comment lines -Enable `Comment` to skip lines starting with `#`: +Enable `comment` to skip lines starting with `#`: + +```go +j := jsonic.Make() +j.UseDefaults(csv.Csv, csv.Defaults, map[string]any{"comment": true}) + +result, _ := j.Parse("a,b\n# skip\n1,2") +// [map[a:1 b:2]] +``` + +### Preserve empty records + +Blank lines are skipped by default. Set `record.empty` to preserve +them as empty-field records: ```go -result, _ := csv.Parse("a,b\n# skip\n1,2", csv.CsvOptions{ - Comment: boolPtr(true), +j := jsonic.Make() +j.UseDefaults(csv.Csv, csv.Defaults, map[string]any{ + "record": map[string]any{"empty": true}, }) -// [{a:1 b:2}] + +result, _ := j.Parse("a\n1\n\n2") +// [map[a:1] map[a:] map[a:2]] ``` @@ -168,18 +225,17 @@ result, _ := csv.Parse("a,b\n# skip\n1,2", csv.CsvOptions{ In **strict mode** (default), the CSV plugin disables Jsonic's built-in JSON parsing. All field values are treated as raw strings -unless `Number` or `Value` options are enabled. This matches the +unless `number` or `value` options are enabled. This matches the behaviour of standard CSV parsers. -In **non-strict mode** (`Strict: boolPtr(false)`), the plugin -preserves Jsonic's ability to parse JSON values. Fields can contain -objects, arrays, booleans, numbers, and quoted strings using Jsonic -syntax. Non-strict mode enables `Trim`, `Comment`, and `Number` by -default. +In **non-strict mode** (`"strict": false`), the plugin preserves +Jsonic's ability to parse JSON values. Fields can contain objects, +arrays, booleans, numbers, and quoted strings using Jsonic syntax. +Non-strict mode enables `trim`, `comment`, and `number` by default. ### How quoted fields work -The plugin includes a custom CSV string matcher that handles the +The plugin registers a custom CSV string matcher that handles the RFC 4180 double-quote escaping convention: - A field wrapped in double quotes can contain commas, newlines, @@ -187,78 +243,87 @@ RFC 4180 double-quote escaping convention: - A literal quote inside a quoted field is represented as `""`. - For example: `"a""b"` parses to `a"b`. +### How the Go plugin relates to the grammar file + +The plugin shares `csv-grammar.jsonic` with the TypeScript +implementation. The grammar file declares the `csv`, `newline`, +`record`, and `text` rules plus static options (`rule.start`, +`lex.emptyResult`, `error`, `hint`). Dynamic options that depend +on user input (tokens, IGNORE set, line separators, number/value +lexing, etc.) are applied in code after `j.Grammar(...)` so their +`TokenSet` override survives Grammar's internal `SetOptions`. + ## Reference -### `Parse` (Function) +### `Csv` (Plugin function) ```go -func Parse(src string, opts ...CsvOptions) ([]any, error) +func Csv(j *jsonic.Jsonic, options map[string]any) error ``` -Parse CSV text with the given options. Returns a slice of records. +The Jsonic plugin that installs CSV grammar and options. Register +with `j.UseDefaults(csv.Csv, csv.Defaults, overrides...)`. -### `MakeJsonic` (Function) +### `Defaults` (map) ```go -func MakeJsonic(opts ...CsvOptions) *jsonic.Jsonic +var Defaults map[string]any ``` -Create a reusable Jsonic instance configured for CSV parsing. +The default option set for the plugin. Pass it to `UseDefaults` +so user-supplied overrides are merged on top of the defaults. -### `CsvOptions` +### `Version` (string) -```go -type CsvOptions struct { - Object *bool // Return maps (true) or slices (false). Default: true - Header *bool // First row is header. Default: true - Trim *bool // Trim whitespace. Default: nil (false strict, true non-strict) - Comment *bool // Enable # comments. Default: nil (false strict, true non-strict) - Number *bool // Parse numbers. Default: nil (false strict, true non-strict) - Value *bool // Parse true/false/null. Default: nil - Strict *bool // Strict CSV mode. Default: true - Field *FieldOptions - Record *RecordOptions - String *StringOptions - Stream StreamFunc -} -``` +The module version string. -### `FieldOptions` +### Option keys -```go -type FieldOptions struct { - Separation string // Field separator. Default: "," - NonamePrefix string // Prefix for unnamed extra fields. Default: "field~" - Empty string // Value for empty fields. Default: "" - Names []string // Explicit field names. - Exact bool // Error on field count mismatch. Default: false -} -``` +Top-level keys (set on the options map passed to `UseDefaults`): -### `RecordOptions` +| Key | Type | Default | Notes | +|-----------|------------------|---------|----------------------------------------------------| +| `trim` | `bool` or `nil` | `nil` | `nil` → `false` strict / `true` non-strict | +| `comment` | `bool` or `nil` | `nil` | `nil` → `false` strict / `true` non-strict | +| `number` | `bool` or `nil` | `nil` | `nil` → `false` strict / `true` non-strict | +| `value` | `bool` or `nil` | `nil` | Parse `true`/`false`/`null` literals | +| `header` | `bool` | `true` | Treat first row as field names | +| `object` | `bool` | `true` | Emit maps (`true`) or slices (`false`) | +| `strict` | `bool` | `true` | Disable Jsonic syntax inside fields | +| `stream` | `func(string, any)` | `nil` | Streaming callback (see below) | -```go -type RecordOptions struct { - Separators string // Custom record separator characters. - Empty bool // Preserve empty lines as records. Default: false -} -``` +Nested `field` group: -### `StringOptions` +| Key | Type | Default | Notes | +|----------------------|------------|------------|----------------------------------------| +| `field.separation` | `string` | `nil` | Delimiter; `nil` uses `,` | +| `field.nonameprefix` | `string` | `"field~"` | Prefix for unnamed extra fields | +| `field.empty` | `any` | `""` | Value substituted for empty fields | +| `field.names` | `[]string` | `nil` | Explicit names (overrides header row) | +| `field.exact` | `bool` | `false` | Error on field count mismatch | -```go -type StringOptions struct { - Quote string // Quote character. Default: `"` - Csv *bool // Force CSV string mode (nil=auto). -} -``` +Nested `record` group: + +| Key | Type | Default | Notes | +|---------------------|-----------|---------|----------------------------------------| +| `record.separators` | `string` | `nil` | Custom record-separator characters | +| `record.empty` | `bool` | `false` | Preserve empty lines as records | + +Nested `string` group: + +| Key | Type | Default | Notes | +|----------------|-----------------|---------|---------------------------------------| +| `string.quote` | `string` | `"` | Quote character for CSV string mode | +| `string.csv` | `bool` or `nil` | `nil` | Force CSV string matcher; `nil`=auto | -### `StreamFunc` +### Streaming callback ```go -type StreamFunc func(what string, record any) +func(what string, record any) ``` -Callback for streaming CSV parsing. Called with `"start"`, `"record"`, -`"end"`, or `"error"`. +`what` is one of `"start"`, `"record"`, `"end"`, or `"error"`. +For `"record"`, `record` holds the parsed row (map or slice +according to `object`). For `"error"`, `record` holds the error +value. diff --git a/doc/csv-ts.md b/doc/csv-ts.md index 2e8f9b5..d684ad1 100644 --- a/doc/csv-ts.md +++ b/doc/csv-ts.md @@ -210,6 +210,18 @@ RFC 4180 double-quote escaping convention: - A literal quote inside a quoted field is represented as `""`. - For example: `"a""b"` parses to `a"b`. +### How the TypeScript plugin relates to the grammar file + +The plugin shares `csv-grammar.jsonic` with the Go implementation. +The grammar file declares the `csv`, `newline`, `record`, and +`text` rules plus static options (`rule.start`, `lex.emptyResult`, +`error`, `hint`). Dynamic options that depend on user input +(tokens, IGNORE set, line separators, number/value lexing, etc.) +are applied in code. The `list`, `elem`, and `val` rules are +modified in code rather than the grammar file because non-strict +mode must preserve Jsonic's default alternatives for embedded +JSON values like `[1,2]` and `{x:1}`. + ## Reference diff --git a/go/csv.go b/go/csv.go index 25abd86..706dc64 100644 --- a/go/csv.go +++ b/go/csv.go @@ -451,7 +451,7 @@ func Csv(j *jsonic.Jsonic, options map[string]any) error { ZZ := j.Token("#ZZ") VAL := j.TokenSet("VAL") - j.Rule("list", func(rs *jsonic.RuleSpec) { + j.Rule("list", func(rs *jsonic.RuleSpec, _ *jsonic.Parser) { rs.Clear() rs.AddBO(func(r *jsonic.Rule, ctx *jsonic.Context) { r.Node = make([]any, 0) @@ -466,7 +466,7 @@ func Csv(j *jsonic.Jsonic, options map[string]any) error { } }) - j.Rule("elem", func(rs *jsonic.RuleSpec) { + j.Rule("elem", func(rs *jsonic.RuleSpec, _ *jsonic.Parser) { rs.Clear() rs.Open = []*jsonic.AltSpec{ {S: [][]jsonic.Tin{{CA}}, B: 1, @@ -508,7 +508,7 @@ func Csv(j *jsonic.Jsonic, options map[string]any) error { }) }) - j.Rule("val", func(rs *jsonic.RuleSpec) { + j.Rule("val", func(rs *jsonic.RuleSpec, _ *jsonic.Parser) { rs.Clear() rs.AddBO(func(r *jsonic.Rule, ctx *jsonic.Context) { r.Node = jsonic.Undefined @@ -525,7 +525,7 @@ func Csv(j *jsonic.Jsonic, options map[string]any) error { if r.OS == 0 { r.Node = jsonic.Undefined } else { - r.Node = r.O0.ResolveVal() + r.Node = r.O0.ResolveVal(r, ctx) } } else { r.Node = r.Child.Node diff --git a/go/go.mod b/go/go.mod index f732323..18377d9 100644 --- a/go/go.mod +++ b/go/go.mod @@ -2,4 +2,4 @@ module github.com/jsonicjs/csv/go go 1.24.7 -require github.com/jsonicjs/jsonic/go v0.1.19-0.20260418194431-54100be22847 +require github.com/jsonicjs/jsonic/go v0.1.19 diff --git a/go/go.sum b/go/go.sum index b960e5a..4f66b30 100644 --- a/go/go.sum +++ b/go/go.sum @@ -1,4 +1,2 @@ -github.com/jsonicjs/jsonic/go v0.1.18 h1:OW15hjFisrw2n7HE6zDuQAikW8A5NUW8OyP4SCG2oFg= -github.com/jsonicjs/jsonic/go v0.1.18/go.mod h1:ObNKlCG7esWoi4AHCpdgkILvPINV8bpvkbCd4llGGUg= -github.com/jsonicjs/jsonic/go v0.1.19-0.20260418194431-54100be22847 h1:+utFlbRO7upKu+DLO9tjUzWHacbxwsyiuFcCkylV3IA= -github.com/jsonicjs/jsonic/go v0.1.19-0.20260418194431-54100be22847/go.mod h1:ObNKlCG7esWoi4AHCpdgkILvPINV8bpvkbCd4llGGUg= +github.com/jsonicjs/jsonic/go v0.1.19 h1:jEP+GSxMGKV+eTJEjuU0qRMUQ8GAIl1SRigc+mbZzVo= +github.com/jsonicjs/jsonic/go v0.1.19/go.mod h1:ObNKlCG7esWoi4AHCpdgkILvPINV8bpvkbCd4llGGUg=