Skip to content

[Repo Assist] Add TOML type provider (TomlProvider)#1652

Draft
github-actions[bot] wants to merge 7 commits intomainfrom
repo-assist/fix-issue-1650-toml-type-provider-cb9fc3e6dabf0af2
Draft

[Repo Assist] Add TOML type provider (TomlProvider)#1652
github-actions[bot] wants to merge 7 commits intomainfrom
repo-assist/fix-issue-1650-toml-type-provider-cb9fc3e6dabf0af2

Conversation

@github-actions
Copy link
Contributor

🤖 This is an automated pull request from Repo Assist.

Implements the feature requested in #1650 — a new TomlProvider type provider for FSharp.Data.

What this adds

FSharp.Data.TomlProvider lets you write code like:

type Config = FSharp.Data.TomlProvider<"config.toml">
let config = Config.GetSample()
printfn "%s" config.Title
printfn "%s" config.Owner.Name
printfn "%A" config.Owner.Dob  // typed as System.DateTimeOffset

Architecture

New project: FSharp.Data.Toml.Core

  • TomlValue — a discriminated union representing all TOML value types: String, Integer, Float, Boolean, OffsetDateTime, LocalDateTime, LocalDate, LocalTime, Array, Table
  • TOML parser — a hand-written recursive-descent parser supporting:
    • All TOML value types including first-class date/time types
    • Tables [header] and arrays-of-tables [[header]]
    • Dotted keys (a.b.c = value) and inline tables { key = value }
    • Multiline basic strings ("""...""") and multiline literal strings ('''...''')
    • Hex (0x), octal (0o), binary (0b) integer literals
    • Special float values (inf, -inf, nan)
  • TomlDocument — wraps TomlValue and implements IJsonDocument by converting TOML values to their JSON equivalents (dates → ISO 8601 strings), enabling the existing JSON type inference and runtime code to be reused

Modified: FSharp.Data.DesignTime

  • TomlProvider — new type provider that parses TOML samples and calls into the JSON generator for type generation. Supports Sample, RootName, Culture, Encoding, ResolutionFolder, EmbeddedResource, InferenceMode, PreferDateOnly, UseOriginalNames static parameters.

Design decisions

The key insight is that TOML maps naturally onto JSON's type system. By converting TomlValueJsonValue at the boundary, we can reuse all of the existing JSON inference, code generation, and runtime infrastructure. TOML's first-class date/time types are serialized to ISO 8601 strings so the inference engine correctly detects them as DateTimeOffset, DateTime, DateOnly, or TimeOnly.

Test Status

  • FSharp.Data.Toml.Core builds (both netstandard2.0 and net8.0)
  • FSharp.Data.DesignTime builds with the new TomlProvider
  • ✅ All 488 existing design-time tests pass
  • ✅ 2 new TOML signature tests pass (generated expected file included)
  • The new expected signature file shows TOML features working correctly:
    • owner.dob inferred as System.DateTimeOffset
    • products (from [[products]]) inferred as an array ✓
    • color field (present in only some items) inferred as string option

Known limitations / future work

  • TOML spec compliance: the parser handles the common cases but edge cases (e.g. surrogate pair unicode escapes in multiline strings, all corner cases of the TOML 1.0 spec) may need additional work

  • No inline TOML schema support (unlike the JSON provider's typeof<> syntax)

  • TomlValue does not yet have a serializer (write-back to TOML text)

  • No dedicated FSharp.Data.Toml NuGet package metadata — would need a new .nuspec / packaging project

  • Fixes Add a TOML type provider #1650

Generated by Repo Assist for issue #1650

To install this workflow, run gh aw add githubnext/agentics/workflows/repo-assist.md@b87234850bf9664d198f28a02df0f937d0447295. View source at https://github.com/githubnext/agentics/tree/b87234850bf9664d198f28a02df0f937d0447295/workflows/repo-assist.md.

Implements a new TomlProvider type provider for FSharp.Data that parses
TOML documents and provides strongly-typed access to their contents.

Architecture:
- FSharp.Data.Toml.Core: new runtime library containing
  - TomlValue: discriminated union representing all TOML value types
    (String, Integer, Float, Boolean, OffsetDateTime, LocalDateTime,
     LocalDate, LocalTime, Array, Table)
  - A hand-written recursive-descent TOML parser supporting:
    - All TOML value types including dates, times and datetime offsets
    - Tables [header] and arrays-of-tables [[header]]
    - Dotted keys (a.b.c = value)
    - Inline tables { key = value }
    - Multiline basic strings and literal strings
    - Hex/octal/binary integer literals
    - Special float values (inf, -inf, nan)
  - TomlDocument: wraps TomlValue and implements IJsonDocument by
    converting TOML values to JSON values, enabling reuse of the
    existing JSON type inference and runtime infrastructure
- FSharp.Data.DesignTime: new TomlProvider type provider
  that uses the TOML parser for sample loading and the existing
  JSON generator for code generation

TOML date/time values are serialized to ISO 8601 strings before
JSON inference, allowing the inference engine to correctly detect
them as DateTimeOffset, DateTime, or TimeSpan types.

Closes #1650

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dsyme
Copy link
Contributor

dsyme commented Feb 25, 2026

/repo-assist We need a new assembly of tests FSharp.Data.Toml.Core.Tests testing everything in src/FSharp.Data.Toml.Core thoroughly especially parsing

…ix parser bugs (local date/time detection, uppercase hex integers)

- New test project tests/FSharp.Data.Toml.Core.Tests/ with thorough coverage of:
  - All TomlValue union cases and ToJsonValue conversions
  - String parsing: basic, literal, multiline, escape sequences, unicode escapes
  - Numeric parsing: integers (decimal/hex/octal/binary/underscores), floats (inf/nan/exponent)
  - Date/time parsing: OffsetDateTime, LocalDateTime, LocalDate, LocalTime
  - Array parsing: empty, typed, trailing comma, multiline, nested, comments
  - Inline table parsing
  - Table headers [key] and [[array-of-tables]]
  - Dotted keys (a.b.c = value)
  - Error cases: duplicate keys, unterminated strings/arrays, invalid escapes
  - TryParse, Load from Stream/TextReader
  - TomlDocument.Create
  - _Print formatting

- Fix parser bugs discovered by tests:
  - isDateLike condition now handles date-only (YYYY-MM-DD) and time-only (HH:MM:SS) values
  - Uppercase hex characters (A-F) now collected during token scanning
  - TimeSpan format strings corrected for TryParseExact (use hh\:mm\:ss not HH:mm:ss)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Contributor Author

Commit pushed: bac15ba

Generated by Repo Assist

@github-actions
Copy link
Contributor Author

🤖 This is an automated response from Repo Assist.

Done! I've added the new FSharp.Data.Toml.Core.Tests project to the PR branch with 95 comprehensive tests covering everything in src/FSharp.Data.Toml.Core.

What was added

New project: tests/FSharp.Data.Toml.Core.Tests/

Test coverage

Area Tests
TomlValue union cases All 10 cases
ToJsonValue conversions String, Integer, Float, Boolean, Array, Table, all date/time types
Basic scalar parsing Strings, integers, floats, booleans
Integer formats Decimal, hex (0xff/0xFF), octal (0o), binary (0b), underscores, negative, + prefix
Float formats Plain, exponent, underscores, inf, -inf, +inf, nan
String escapes \t, \n, \r, \\, \", \uXXXX, \UXXXXXXXX
Multiline strings Basic with line continuation, literal
Date/time parsing OffsetDateTime (with Z, with fraction, with offset), LocalDateTime, LocalDate, LocalTime, fractional seconds
Arrays Empty, integers, strings, trailing comma, multiline, nested, with comments
Inline tables Empty and non-empty
Table headers Single [key], multiple, dotted [a.b.c]
Array-of-tables [[products]] with sub-tables
Dotted keys a.b = 1, multi-level
Quoted keys Keys with spaces
Error cases Duplicate keys, duplicate table headers, unterminated strings/arrays, invalid escapes
TryParse Valid and invalid input
Load From Stream and TextReader
TomlDocument Create from TomlValue and TextReader, JSON record shape
_Print All union case formatting

Parser bugs fixed (discovered by tests)

  1. Local date (1979-05-27) not parsed — the isDateLike condition required colons/T, but date-only values have neither. Fixed by detecting date-only tokens (hasDash && not hasColon && not hasTorSpace && not hasDecimalOrExp) separately.

  2. Local time (07:32:00) not parsed — times have colons but no dashes, so weren't classified as date-like. Fixed by adding a isTime = not hasDash && hasColon branch.

  3. Uppercase hex integers (0xFF) failed — only lowercase a–f were included in the token character set. Added A, B, C, D, F (uppercase).

  4. TimeSpan.TryParseExact format strings wrong — used "HH:mm:ss" (DateTime format) instead of @"hh\:mm\:ss" (TimeSpan format). Fixed the 8 time format strings.

All 95 tests pass. ✅

Generated by Repo Assist for issue #1652

To install this workflow, run gh aw add githubnext/agentics/workflows/repo-assist.md@f2c5cf1e4af58e09a93ba0703c6bf084711b265f. View source at https://github.com/githubnext/agentics/tree/f2c5cf1e4af58e09a93ba0703c6bf084711b265f/workflows/repo-assist.md.

@dsyme
Copy link
Contributor

dsyme commented Feb 26, 2026

/repo-assist fix the build and test failures

…erType

The JsonInference.inferType function gained a new 'allowEmptyValues' bool
parameter between 'cultureInfo' and 'parentName'. Update the call in
TomlProvider.fs to pass 'true' (equivalent to 'not preferOptionals' default).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Contributor Author

Commit pushed: eaa28f6

Generated by Repo Assist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a TOML type provider

1 participant