Skip to content
Merged
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
19 changes: 17 additions & 2 deletions src/FSharp.Data.Csv.Core/CsvInference.fs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ let internal inferCellType
missingValues
inferenceMode
strictBooleans
preferFloats
cultureInfo
unit
(value: string)
Expand All @@ -140,7 +141,15 @@ let internal inferCellType
InferedType.Null
else
let inferedType =
StructuralInference.getInferedTypeFromString unitsOfMeasureProvider inferenceMode cultureInfo value unit
if preferFloats then
StructuralInference.getInferedTypeFromStringPreferFloats
unitsOfMeasureProvider
inferenceMode
cultureInfo
value
unit
else
StructuralInference.getInferedTypeFromString unitsOfMeasureProvider inferenceMode cultureInfo value unit

if strictBooleans then
// With StrictBooleans=true, only "true"/"false" trigger bool inference.
Expand Down Expand Up @@ -305,6 +314,7 @@ let internal inferType
missingValues
inferenceMode
strictBooleans
preferFloats
cultureInfo
assumeMissingValues
preferOptionals
Expand Down Expand Up @@ -358,6 +368,7 @@ let internal inferType
missingValues
inferenceMode
strictBooleans
preferFloats
cultureInfo
unit
value
Expand Down Expand Up @@ -456,6 +467,7 @@ let internal inferColumnTypes
missingValues
inferenceMode
strictBooleans
preferFloats
cultureInfo
assumeMissingValues
preferOptionals
Expand All @@ -469,6 +481,7 @@ let internal inferColumnTypes
missingValues
inferenceMode
strictBooleans
preferFloats
cultureInfo
assumeMissingValues
preferOptionals
Expand Down Expand Up @@ -497,7 +510,8 @@ type CsvFile with
assumeMissingValues,
preferOptionals,
unitsOfMeasureProvider,
?strictBooleans
?strictBooleans,
?preferFloats
) =

let headerNamesAndUnits, schema =
Expand All @@ -511,6 +525,7 @@ type CsvFile with
missingValues
inferenceMode
(defaultArg strictBooleans false)
(defaultArg preferFloats false)
cultureInfo
assumeMissingValues
preferOptionals
Expand Down
7 changes: 5 additions & 2 deletions src/FSharp.Data.DesignTime/Csv/CsvProvider.fs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type public CsvProvider(cfg: TypeProviderConfig) as this =
let preferDateOnly = args.[16] :?> bool
let strictBooleans = args.[17] :?> bool
let useOriginalNames = args.[18] :?> bool
let preferFloats = args.[19] :?> bool

// This provider already has a schema mechanism, so let's disable inline schemas.
let inferenceMode = InferenceMode'.ValuesOnly
Expand Down Expand Up @@ -116,7 +117,8 @@ type public CsvProvider(cfg: TypeProviderConfig) as this =
assumeMissingValues,
preferOptionals,
unitsOfMeasureProvider,
strictBooleans
strictBooleans,
preferFloats
)
#if NET6_0_OR_GREATER
if preferDateOnly && ProviderHelpers.runtimeSupportsNet6Types cfg.RuntimeAssembly then
Expand Down Expand Up @@ -241,7 +243,8 @@ type public CsvProvider(cfg: TypeProviderConfig) as this =
ProvidedStaticParameter("EmbeddedResource", typeof<string>, parameterDefaultValue = "")
ProvidedStaticParameter("PreferDateOnly", typeof<bool>, parameterDefaultValue = false)
ProvidedStaticParameter("StrictBooleans", typeof<bool>, parameterDefaultValue = false)
ProvidedStaticParameter("UseOriginalNames", typeof<bool>, parameterDefaultValue = false) ]
ProvidedStaticParameter("UseOriginalNames", typeof<bool>, parameterDefaultValue = false)
ProvidedStaticParameter("PreferFloats", typeof<bool>, parameterDefaultValue = false) ]

let helpText =
"""<summary>Typed representation of a CSV file.</summary>
Expand Down
1 change: 1 addition & 0 deletions src/FSharp.Data.Html.Core/HtmlInference.fs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ let internal inferColumns parameters (headerNamesAndUnits: _[]) rows =
parameters.MissingValues
parameters.InferenceMode
false
false
parameters.CultureInfo
assumeMissingValues
parameters.PreferOptionals
Expand Down
9 changes: 7 additions & 2 deletions src/FSharp.Data.Runtime.Utilities/StructuralInference.fs
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ let inferPrimitiveType
(unitsOfMeasureProvider: IUnitsOfMeasureProvider)
(inferenceMode: InferenceMode')
(cultureInfo: CultureInfo)
(preferFloats: bool)
(value: string)
(desiredUnit: Type option)
=
Expand Down Expand Up @@ -573,7 +574,7 @@ let inferPrimitiveType
makePrimitive typeof<DateOnly>
#endif
| Parse TextConversions.AsDateTime date when not (isFakeDate date value) -> makePrimitive typeof<DateTime>
| Parse TextConversions.AsDecimal _ -> makePrimitive typeof<decimal>
| Parse TextConversions.AsDecimal _ when not preferFloats -> makePrimitive typeof<decimal>
| Parse (TextConversions.AsFloat [||] false) _ -> makePrimitive typeof<float>
| Parse asGuid _ -> makePrimitive typeof<Guid>
| _ -> None
Expand Down Expand Up @@ -622,7 +623,11 @@ let inferPrimitiveType
/// Infers the type of a simple string value
[<Obsolete("This API will be made internal in a future release. Please file an issue at https://github.com/fsprojects/FSharp.Data/issues/1458 if you need this public.")>]
let getInferedTypeFromString unitsOfMeasureProvider inferenceMode cultureInfo value unit =
inferPrimitiveType unitsOfMeasureProvider inferenceMode cultureInfo value unit
inferPrimitiveType unitsOfMeasureProvider inferenceMode cultureInfo false value unit

/// Infers the type of a simple string value, preferring float over decimal
let internal getInferedTypeFromStringPreferFloats unitsOfMeasureProvider inferenceMode cultureInfo value unit =
inferPrimitiveType unitsOfMeasureProvider inferenceMode cultureInfo true value unit

#if NET6_0_OR_GREATER
/// Replaces DateOnly → DateTime and TimeOnly → TimeSpan throughout an InferedType tree.
Expand Down
4 changes: 2 additions & 2 deletions tests/FSharp.Data.DesignTime.Tests/InferenceTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ let internal unitsOfMeasureProvider = ProviderHelpers.unitsOfMeasureProvider

let internal inferType (csv:CsvFile) inferRows missingValues cultureInfo schema assumeMissingValues preferOptionals =
let headerNamesAndUnits, schema = parseHeaders csv.Headers csv.NumberOfColumns schema unitsOfMeasureProvider
inferType headerNamesAndUnits schema (csv.Rows |> Seq.map (fun x -> x.Columns)) inferRows missingValues inferenceMode false cultureInfo assumeMissingValues preferOptionals unitsOfMeasureProvider
inferType headerNamesAndUnits schema (csv.Rows |> Seq.map (fun x -> x.Columns)) inferRows missingValues inferenceMode false false cultureInfo assumeMissingValues preferOptionals unitsOfMeasureProvider

let internal toRecord fields = InferedType.Record(None, fields, false)

Expand Down Expand Up @@ -411,7 +411,7 @@ let ``Doesn't infer 12-002 as a date``() =

[<Test>]
let ``Doesn't infer ad3mar as a date``() =
StructuralInference.inferPrimitiveType unitsOfMeasureProvider inferenceMode CultureInfo.InvariantCulture "ad3mar" None
StructuralInference.inferPrimitiveType unitsOfMeasureProvider inferenceMode CultureInfo.InvariantCulture false "ad3mar" None
|> should equal (InferedType.Primitive(typeof<string>, None, false, false))

[<Test>]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ type internal CsvProviderArgs =
EmbeddedResource : string
PreferDateOnly : bool
StrictBooleans : bool
UseOriginalNames : bool }
UseOriginalNames : bool
PreferFloats : bool }

type internal XmlProviderArgs =
{ Sample : string
Expand Down Expand Up @@ -106,7 +107,8 @@ type internal TypeProviderInstantiation =
box x.EmbeddedResource
box x.PreferDateOnly
box x.StrictBooleans
box x.UseOriginalNames |]
box x.UseOriginalNames
box x.PreferFloats |]
| Xml x ->
(fun cfg -> new XmlProvider(cfg) :> TypeProviderForNamespaces),
[| box x.Sample
Expand Down Expand Up @@ -246,7 +248,8 @@ type internal TypeProviderInstantiation =
EmbeddedResource = ""
PreferDateOnly = false
StrictBooleans = false
UseOriginalNames = false }
UseOriginalNames = false
PreferFloats = false }
| "Xml" ->
Xml { Sample = args.[1]
SampleIsList = args.[2] |> bool.Parse
Expand Down
18 changes: 18 additions & 0 deletions tests/FSharp.Data.Tests/CsvProvider.fs
Original file line number Diff line number Diff line change
Expand Up @@ -766,3 +766,21 @@ let ``CsvProvider Row With* methods do not mutate the original row`` () =
let row = csv.Rows |> Seq.head
let _ = row.WithName("Charlie")
row.Name |> should equal "Alice"

// Tests for PreferFloats static parameter (issue #838)
let [<Literal>] csvWithDecimals = "Name,Price,Rate\nAlice,9.99,1.5\nBob,12.50,2.7"

type CsvPreferFloats = CsvProvider<csvWithDecimals, PreferFloats = true>
type CsvDefaultDecimal = CsvProvider<csvWithDecimals>

[<Test>]
let ``CsvProvider PreferFloats=true infers float instead of decimal`` () =
let row = CsvPreferFloats.GetSample().Rows |> Seq.head
row.Price |> should equal 9.99
row.Rate |> should equal 1.5

[<Test>]
let ``CsvProvider PreferFloats=false (default) infers decimal for decimal values`` () =
let row = CsvDefaultDecimal.GetSample().Rows |> Seq.head
row.Price |> should equal 9.99m
row.Rate |> should equal 1.5m
Loading