Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions FSharp.Data.sln
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.Csv.Core", "src
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.WorldBank.Core", "src\FSharp.Data.WorldBank.Core\FSharp.Data.WorldBank.Core.fsproj", "{A69D007B-EAF0-4866-A8B4-A2EDF2614E56}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.Toml.Core", "src\FSharp.Data.Toml.Core\FSharp.Data.Toml.Core.fsproj", "{B1C2D3E4-F5A6-7890-BCDE-F01234567890}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.Toml.Core.Tests", "tests\FSharp.Data.Toml.Core.Tests\FSharp.Data.Toml.Core.Tests.fsproj", "{A74DA8FF-2162-46D1-ACDA-AA3A51546685}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{8C038DD5-FB03-4E6D-B8F2-D66AE2E6DCC9}"
ProjectSection(SolutionItems) = preProject
docs\index.md = docs\index.md
Expand Down Expand Up @@ -156,6 +160,14 @@ Global
{A69D007B-EAF0-4866-A8B4-A2EDF2614E56}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A69D007B-EAF0-4866-A8B4-A2EDF2614E56}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A69D007B-EAF0-4866-A8B4-A2EDF2614E56}.Release|Any CPU.Build.0 = Release|Any CPU
{B1C2D3E4-F5A6-7890-BCDE-F01234567890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B1C2D3E4-F5A6-7890-BCDE-F01234567890}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B1C2D3E4-F5A6-7890-BCDE-F01234567890}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B1C2D3E4-F5A6-7890-BCDE-F01234567890}.Release|Any CPU.Build.0 = Release|Any CPU
{A74DA8FF-2162-46D1-ACDA-AA3A51546685}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A74DA8FF-2162-46D1-ACDA-AA3A51546685}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A74DA8FF-2162-46D1-ACDA-AA3A51546685}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A74DA8FF-2162-46D1-ACDA-AA3A51546685}.Release|Any CPU.Build.0 = Release|Any CPU
{D04AFA70-4A59-4E1C-AC41-BA0EA70140FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D04AFA70-4A59-4E1C-AC41-BA0EA70140FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D04AFA70-4A59-4E1C-AC41-BA0EA70140FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -174,6 +186,7 @@ Global
{A5B31ACC-56FB-4EC2-917F-BEB3754EF9AC} = {1F33D53A-C007-408C-AF6C-B7D62288F941}
{290FED0C-D7C8-486F-AACF-3D7A1304C863} = {1F33D53A-C007-408C-AF6C-B7D62288F941}
{750148EC-6A05-421D-96A4-E5AC9D18AF58} = {1F33D53A-C007-408C-AF6C-B7D62288F941}
{A74DA8FF-2162-46D1-ACDA-AA3A51546685} = {1F33D53A-C007-408C-AF6C-B7D62288F941}
{660DBCC8-F7F2-4301-A611-A2F2C97E369D} = {8C038DD5-FB03-4E6D-B8F2-D66AE2E6DCC9}
{E399369F-268F-4411-84CD-B868F9FE52EF} = {8C038DD5-FB03-4E6D-B8F2-D66AE2E6DCC9}
{0203D290-11AA-48DB-B1E6-156DFDCEEF80} = {8C038DD5-FB03-4E6D-B8F2-D66AE2E6DCC9}
Expand Down
6 changes: 3 additions & 3 deletions paket.lock
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ NUGET
NETStandard.Library.NETFramework (2.0.0-preview2-25405-01)
GITHUB
remote: fsprojects/FSharp.TypeProviders.SDK
src/ProvidedTypes.fs (ce34c1cc71096857b8342f1dedf93391addc9df6)
src/ProvidedTypes.fsi (ce34c1cc71096857b8342f1dedf93391addc9df6)
tests/ProvidedTypesTesting.fs (ce34c1cc71096857b8342f1dedf93391addc9df6)
src/ProvidedTypes.fs (ec4d4522cf4a2a7cd4f4d166ff053e6617dcf1c6)
src/ProvidedTypes.fsi (ec4d4522cf4a2a7cd4f4d166ff053e6617dcf1c6)
tests/ProvidedTypesTesting.fs (ec4d4522cf4a2a7cd4f4d166ff053e6617dcf1c6)
GROUP Benchmarks
RESTRICTION: == net8.0
NUGET
Expand Down
27 changes: 27 additions & 0 deletions src/AssemblyInfo.Toml.Core.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Auto-Generated by FAKE; do not edit
namespace System

open System.Reflection

[<assembly: AssemblyTitleAttribute("FSharp.Data.Toml.Core")>]
[<assembly: AssemblyProductAttribute("FSharp.Data")>]
[<assembly: AssemblyDescriptionAttribute("Library of F# type providers and data access tools")>]
[<assembly: AssemblyVersionAttribute("6.6.0.0")>]
[<assembly: AssemblyFileVersionAttribute("6.6.0.0")>]
do ()

module internal AssemblyVersionInformation =
[<Literal>]
let AssemblyTitle = "FSharp.Data.Toml.Core"

[<Literal>]
let AssemblyProduct = "FSharp.Data"

[<Literal>]
let AssemblyDescription = "Library of F# type providers and data access tools"

[<Literal>]
let AssemblyVersion = "6.6.0.0"

[<Literal>]
let AssemblyFileVersion = "6.6.0.0"
2 changes: 2 additions & 0 deletions src/FSharp.Data.DesignTime/FSharp.Data.DesignTime.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<Compile Include="WorldBank/WorldBankProvider.fs" />
<Compile Include="Html/HtmlGenerator.fs" />
<Compile Include="Html/HtmlProvider.fs" />
<Compile Include="Toml/TomlProvider.fs" />
<Compile Include="../AssemblyInfo.DesignTime.fs" />
<None Include="../Test.fsx" />
<None Include="paket.references" />
Expand All @@ -42,6 +43,7 @@
<ProjectReference Include="../FSharp.Data.Csv.Core/FSharp.Data.Csv.Core.fsproj" />
<ProjectReference Include="../FSharp.Data.Html.Core/FSharp.Data.Html.Core.fsproj" />
<ProjectReference Include="../FSharp.Data.WorldBank.Core/FSharp.Data.WorldBank.Core.fsproj" />
<ProjectReference Include="../FSharp.Data.Toml.Core/FSharp.Data.Toml.Core.fsproj" />
<ProjectReference Include="../FSharp.Data.Runtime.Utilities/FSharp.Data.Runtime.Utilities.fsproj" />
</ItemGroup>
<Import Project="..\..\.paket\Paket.Restore.targets" />
Expand Down
143 changes: 143 additions & 0 deletions src/FSharp.Data.DesignTime/Toml/TomlProvider.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
namespace ProviderImplementation

open System
open System.IO
open FSharp.Core.CompilerServices
open ProviderImplementation
open ProviderImplementation.ProvidedTypes
open ProviderImplementation.ProviderHelpers
open FSharp.Data
open FSharp.Data.Runtime
open FSharp.Data.Runtime.BaseTypes
open FSharp.Data.Runtime.StructuralTypes
open FSharp.Data.Runtime.StructuralInference
open System.Net

// ----------------------------------------------------------------------------------------------

#nowarn "10001"

[<TypeProvider>]
type public TomlProvider(cfg: TypeProviderConfig) as this =
inherit
DisposableTypeProviderForNamespaces(cfg, assemblyReplacementMap = [ "FSharp.Data.DesignTime", "FSharp.Data" ])

do AssemblyResolver.init ()
let asm = System.Reflection.Assembly.GetExecutingAssembly()
let ns = "FSharp.Data"

let tomlProvTy =
ProvidedTypeDefinition(asm, ns, "TomlProvider", None, hideObjectMethods = true, nonNullable = true)

let buildTypes (typeName: string) (args: obj[]) =

// Enable TLS 1.2 for samples requested through https.
ServicePointManager.SecurityProtocol <- ServicePointManager.SecurityProtocol ||| SecurityProtocolType.Tls12

let tpType =
ProvidedTypeDefinition(asm, ns, typeName, None, hideObjectMethods = true, nonNullable = true)

let sample = args.[0] :?> string
let rootName = args.[1] :?> string

let rootName =
if String.IsNullOrWhiteSpace rootName then
"Root"
else
NameUtils.singularize rootName

let cultureStr = args.[2] :?> string
let encodingStr = args.[3] :?> string
let resolutionFolder = args.[4] :?> string
let resource = args.[5] :?> string
let inferenceMode = args.[6] :?> InferenceMode
let preferDateOnly = args.[7] :?> bool
let useOriginalNames = args.[8] :?> bool

let inferenceMode' = InferenceMode'.FromPublicApi(inferenceMode, true)
let cultureInfo = TextRuntime.GetCulture cultureStr
let unitsOfMeasureProvider = ProviderHelpers.unitsOfMeasureProvider

let getSpec _ value =

let tomlValue =
use _holder = IO.logTime "Parsing" sample
TomlValue.Parse(value)

let sampleJson = tomlValue.ToJsonValue()

let inferedType =
use _holder = IO.logTime "Inference" sample

let rawInfered =
JsonInference.inferType unitsOfMeasureProvider inferenceMode' cultureInfo true "" sampleJson

#if NET6_0_OR_GREATER
if preferDateOnly && ProviderHelpers.runtimeSupportsNet6Types cfg.RuntimeAssembly then
rawInfered
else
StructuralInference.downgradeNet6Types rawInfered
#else
rawInfered
#endif

use _holder = IO.logTime "TypeGeneration" sample

let ctx =
JsonGenerationContext.Create(
cultureStr,
tpType,
unitsOfMeasureProvider,
inferenceMode',
?useOriginalNames = Some useOriginalNames
)

let result = JsonTypeBuilder.generateJsonType ctx false false rootName inferedType

{ GeneratedType = tpType
RepresentationType = result.ConvertedType
CreateFromTextReader = fun reader -> result.Convert <@@ TomlDocument.Create(%reader) @@>
CreateListFromTextReader = None
CreateFromTextReaderForSampleList = fun reader -> result.Convert <@@ TomlDocument.Create(%reader) @@>
CreateFromValue =
Some(typeof<JsonValue>, (fun value -> result.Convert <@@ JsonDocument.Create(%value, "") @@>)) }

generateType "TOML" (Sample sample) getSpec this cfg encodingStr resolutionFolder resource typeName None

let parameters =
[ ProvidedStaticParameter("Sample", typeof<string>, parameterDefaultValue = "")
ProvidedStaticParameter("RootName", typeof<string>, parameterDefaultValue = "Root")
ProvidedStaticParameter("Culture", typeof<string>, parameterDefaultValue = "")
ProvidedStaticParameter("Encoding", typeof<string>, parameterDefaultValue = "")
ProvidedStaticParameter("ResolutionFolder", typeof<string>, parameterDefaultValue = "")
ProvidedStaticParameter("EmbeddedResource", typeof<string>, parameterDefaultValue = "")
ProvidedStaticParameter(
"InferenceMode",
typeof<InferenceMode>,
parameterDefaultValue = InferenceMode.BackwardCompatible
)
ProvidedStaticParameter("PreferDateOnly", typeof<bool>, parameterDefaultValue = false)
ProvidedStaticParameter("UseOriginalNames", typeof<bool>, parameterDefaultValue = false) ]

let helpText =
"""<summary>Typed representation of a TOML document.</summary>
<param name='Sample'>Location of a TOML sample file or a string containing a sample TOML document.</param>
<param name='RootName'>The name to be used for the root type. Defaults to <c>Root</c>.</param>
<param name='Culture'>The culture used for parsing numbers and dates. Defaults to the invariant culture.</param>
<param name='Encoding'>The encoding used to read the sample. Defaults to UTF8 for files.</param>
<param name='ResolutionFolder'>A directory that is used when resolving relative file references (at design time and in hosted execution).</param>
<param name='EmbeddedResource'>When specified, the type provider first attempts to load the sample from the specified resource
(e.g. 'MyCompany.MyAssembly, resource_name.toml'). This is useful when exposing types generated by the type provider.</param>
<param name='InferenceMode'>Possible values:
| NoInference -> Inference is disabled. All values are inferred as the most basic type.
| ValuesOnly -> Types of values are inferred from the Sample (default).
| ValuesAndInlineSchemasHints -> Types are inferred from both values and inline schema hints.
| ValuesAndInlineSchemasOverrides -> Same as ValuesAndInlineSchemasHints, but value inferred types are ignored when an inline schema is present.
</param>
<param name='PreferDateOnly'>When true on .NET 6+, date-only strings are inferred as DateOnly and time-only strings as TimeOnly. Defaults to false.</param>
<param name='UseOriginalNames'>When true, TOML key names are used as-is for generated property names instead of being normalized to PascalCase. Defaults to false.</param>"""

do tomlProvTy.AddXmlDoc helpText
do tomlProvTy.DefineStaticParameters(parameters, buildTypes)

do this.AddNamespace(ns, [ tomlProvTy ])
26 changes: 26 additions & 0 deletions src/FSharp.Data.Toml.Core/FSharp.Data.Toml.Core.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
<OtherFlags>$(OtherFlags) --warnon:1182 --nowarn:10001 --nowarn:44</OtherFlags>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<PackageIcon>logo.png</PackageIcon>
<!-- always have tailcalls on for design time compiler add-in to allow repo to compile in DEBUG, see https://github.com/fsprojects/FSharp.Data/issues/1410 -->
<Tailcalls>true</Tailcalls>
</PropertyGroup>
<ItemGroup>
<Compile Include="TomlValue.fs" />
<Compile Include="TomlDocument.fs" />
<Compile Include="../AssemblyInfo.Toml.Core.fs" />
<None Include="../../docs/img/logo.png" Pack="true" PackagePath="" />
<None Include="paket.references" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../FSharp.Data.Http/FSharp.Data.Http.fsproj" />
<ProjectReference Include="../FSharp.Data.Json.Core/FSharp.Data.Json.Core.fsproj" />
<ProjectReference Include="../FSharp.Data.Runtime.Utilities/FSharp.Data.Runtime.Utilities.fsproj" />
</ItemGroup>
<Import Project="..\..\.paket\Paket.Restore.targets" />
</Project>
67 changes: 67 additions & 0 deletions src/FSharp.Data.Toml.Core/TomlDocument.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// --------------------------------------------------------------------------------------
// TOML type provider - runtime document type
// --------------------------------------------------------------------------------------

namespace FSharp.Data.Runtime.BaseTypes

open System.ComponentModel
open System.IO
open FSharp.Data
open FSharp.Data.Runtime.BaseTypes

#nowarn "10001"

/// <summary>Underlying representation of types generated by TomlProvider</summary>
[<StructuredFormatDisplay("{JsonValue}")>]
type TomlDocument =

private
{ Toml: TomlValue
BackingJson: IJsonDocument }

interface IJsonDocument with
member x.JsonValue = x.BackingJson.JsonValue
member x.Path() = x.BackingJson.Path()

member x.CreateNew(value, pathIncrement) =
{ Toml = x.Toml
BackingJson = x.BackingJson.CreateNew(value, pathIncrement) }

/// The underlying TOML value
member x.TomlValue = x.Toml

/// The JSON value backing this document (used by the type provider runtime)
member x.JsonValue = x.BackingJson.JsonValue

/// <exclude />
[<EditorBrowsableAttribute(EditorBrowsableState.Never)>]
[<CompilerMessageAttribute("This method is intended for use in generated code only.",
10001,
IsHidden = true,
IsError = false)>]
override x.ToString() = x.TomlValue.ToString()

/// <exclude />
[<EditorBrowsableAttribute(EditorBrowsableState.Never)>]
[<CompilerMessageAttribute("This method is intended for use in generated code only.",
10001,
IsHidden = true,
IsError = false)>]
static member Create(tomlValue: TomlValue, path: string) : IJsonDocument =
let jsonValue = tomlValue.ToJsonValue()
let backing = JsonDocument.Create(jsonValue, path)

{ Toml = tomlValue
BackingJson = backing }

/// <exclude />
[<EditorBrowsableAttribute(EditorBrowsableState.Never)>]
[<CompilerMessageAttribute("This method is intended for use in generated code only.",
10001,
IsHidden = true,
IsError = false)>]
static member Create(reader: TextReader) : IJsonDocument =
use reader = reader
let text = reader.ReadToEnd()
let tomlValue = TomlValue.Parse(text)
TomlDocument.Create(tomlValue, "")
Loading
Loading