mirror of
https://github.com/Smaug123/WoofWare.Myriad
synced 2025-10-08 13:38:39 +00:00
Compare commits
2 Commits
WoofWare.M
...
WoofWare.M
Author | SHA1 | Date | |
---|---|---|---|
|
b53b410feb | ||
|
398cd04a2a |
@@ -204,6 +204,12 @@ module JsonRecordTypeWithBothJsonSerializeExtension =
|
|||||||
|
|
||||||
node.Add ("enum", (input.Enum |> SomeEnum.toJsonNode))
|
node.Add ("enum", (input.Enum |> SomeEnum.toJsonNode))
|
||||||
|
|
||||||
|
node.Add (
|
||||||
|
"timestamp",
|
||||||
|
(input.Timestamp
|
||||||
|
|> (fun field -> field.ToString "o" |> System.Text.Json.Nodes.JsonValue.Create<string>))
|
||||||
|
)
|
||||||
|
|
||||||
node :> _
|
node :> _
|
||||||
namespace ConsumePlugin
|
namespace ConsumePlugin
|
||||||
|
|
||||||
@@ -418,6 +424,19 @@ module JsonRecordTypeWithBothJsonParseExtension =
|
|||||||
|
|
||||||
/// Parse from a JSON node.
|
/// Parse from a JSON node.
|
||||||
static member jsonParse (node : System.Text.Json.Nodes.JsonNode) : JsonRecordTypeWithBoth =
|
static member jsonParse (node : System.Text.Json.Nodes.JsonNode) : JsonRecordTypeWithBoth =
|
||||||
|
let arg_20 =
|
||||||
|
(match node.["timestamp"] with
|
||||||
|
| null ->
|
||||||
|
raise (
|
||||||
|
System.Collections.Generic.KeyNotFoundException (
|
||||||
|
sprintf "Required key '%s' not found on JSON object" ("timestamp")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
| v -> v)
|
||||||
|
.AsValue()
|
||||||
|
.GetValue<string> ()
|
||||||
|
|> System.DateTimeOffset.Parse
|
||||||
|
|
||||||
let arg_19 =
|
let arg_19 =
|
||||||
SomeEnum.jsonParse (
|
SomeEnum.jsonParse (
|
||||||
match node.["enum"] with
|
match node.["enum"] with
|
||||||
@@ -685,6 +704,7 @@ module JsonRecordTypeWithBothJsonParseExtension =
|
|||||||
IntMeasureOption = arg_17
|
IntMeasureOption = arg_17
|
||||||
IntMeasureNullable = arg_18
|
IntMeasureNullable = arg_18
|
||||||
Enum = arg_19
|
Enum = arg_19
|
||||||
|
Timestamp = arg_20
|
||||||
}
|
}
|
||||||
namespace ConsumePlugin
|
namespace ConsumePlugin
|
||||||
|
|
||||||
@@ -804,3 +824,21 @@ module HeaderAndValueJsonParseExtension =
|
|||||||
Header = arg_0
|
Header = arg_0
|
||||||
Value = arg_1
|
Value = arg_1
|
||||||
}
|
}
|
||||||
|
namespace ConsumePlugin
|
||||||
|
|
||||||
|
/// Module containing JSON parsing extension members for the Foo type
|
||||||
|
[<AutoOpen>]
|
||||||
|
module FooJsonParseExtension =
|
||||||
|
/// Extension methods for JSON parsing
|
||||||
|
type Foo with
|
||||||
|
|
||||||
|
/// Parse from a JSON node.
|
||||||
|
static member jsonParse (node : System.Text.Json.Nodes.JsonNode) : Foo =
|
||||||
|
let arg_0 =
|
||||||
|
match node.["message"] with
|
||||||
|
| null -> None
|
||||||
|
| v -> HeaderAndValue.jsonParse v |> Some
|
||||||
|
|
||||||
|
{
|
||||||
|
Message = arg_0
|
||||||
|
}
|
||||||
|
@@ -49,6 +49,7 @@ type JsonRecordTypeWithBoth =
|
|||||||
IntMeasureOption : int<measure> option
|
IntMeasureOption : int<measure> option
|
||||||
IntMeasureNullable : int<measure> Nullable
|
IntMeasureNullable : int<measure> Nullable
|
||||||
Enum : SomeEnum
|
Enum : SomeEnum
|
||||||
|
Timestamp : DateTimeOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
[<WoofWare.Myriad.Plugins.JsonSerialize true>]
|
[<WoofWare.Myriad.Plugins.JsonSerialize true>]
|
||||||
@@ -67,6 +68,7 @@ type HeaderAndValue =
|
|||||||
}
|
}
|
||||||
|
|
||||||
[<WoofWare.Myriad.Plugins.JsonSerialize true>]
|
[<WoofWare.Myriad.Plugins.JsonSerialize true>]
|
||||||
|
[<WoofWare.Myriad.Plugins.JsonParse true>]
|
||||||
type Foo =
|
type Foo =
|
||||||
{
|
{
|
||||||
Message : HeaderAndValue option
|
Message : HeaderAndValue option
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ApiSurface" Version="4.0.41" />
|
<PackageReference Include="ApiSurface" Version="4.0.42" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/>
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/>
|
||||||
<PackageReference Include="NUnit" Version="4.1.0"/>
|
<PackageReference Include="NUnit" Version="4.1.0"/>
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
||||||
|
@@ -92,6 +92,7 @@ module TestJsonSerde =
|
|||||||
let! intMeasureOption = Arb.generate
|
let! intMeasureOption = Arb.generate
|
||||||
let! intMeasureNullable = Arb.generate
|
let! intMeasureNullable = Arb.generate
|
||||||
let! someEnum = Gen.choose (0, 1)
|
let! someEnum = Gen.choose (0, 1)
|
||||||
|
let! timestamp = Arb.generate
|
||||||
|
|
||||||
return
|
return
|
||||||
{
|
{
|
||||||
@@ -115,6 +116,7 @@ module TestJsonSerde =
|
|||||||
IntMeasureOption = intMeasureOption
|
IntMeasureOption = intMeasureOption
|
||||||
IntMeasureNullable = intMeasureNullable
|
IntMeasureNullable = intMeasureNullable
|
||||||
Enum = enum<SomeEnum> someEnum
|
Enum = enum<SomeEnum> someEnum
|
||||||
|
Timestamp = timestamp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +134,80 @@ module TestJsonSerde =
|
|||||||
|
|
||||||
property |> Prop.forAll (Arb.fromGen outerGen) |> Check.QuickThrowOnFailure
|
property |> Prop.forAll (Arb.fromGen outerGen) |> Check.QuickThrowOnFailure
|
||||||
|
|
||||||
|
[<Test>]
|
||||||
|
let ``Single example of big record`` () =
|
||||||
|
let guid = Guid.Parse "dfe24db5-9f8d-447b-8463-4c0bcf1166d5"
|
||||||
|
|
||||||
|
let data =
|
||||||
|
{
|
||||||
|
A = 3
|
||||||
|
B = "hello!"
|
||||||
|
C = [ 1 ; -9 ]
|
||||||
|
D =
|
||||||
|
{
|
||||||
|
Thing = guid
|
||||||
|
Map = Map.ofList []
|
||||||
|
ReadOnlyDict = readOnlyDict []
|
||||||
|
Dict = dict []
|
||||||
|
ConcreteDict = Dictionary ()
|
||||||
|
}
|
||||||
|
E = [| "I'm-a-string" |]
|
||||||
|
Arr = [| -18883 ; 9100 |]
|
||||||
|
Byte = 87uy<measure>
|
||||||
|
Sbyte = 89y<measure>
|
||||||
|
I = 199993345<measure>
|
||||||
|
I32 = -485832<measure>
|
||||||
|
I64 = -13458625689L<measure>
|
||||||
|
U = 458582u<measure>
|
||||||
|
U32 = 857362147u<measure>
|
||||||
|
U64 = 1234567892123414596UL<measure>
|
||||||
|
F = 8833345667.1<measure>
|
||||||
|
F32 = 1000.98f<measure>
|
||||||
|
Single = 0.334f<measure>
|
||||||
|
IntMeasureOption = Some 981<measure>
|
||||||
|
IntMeasureNullable = Nullable -883<measure>
|
||||||
|
Enum = enum<SomeEnum> 1
|
||||||
|
Timestamp = DateTimeOffset (2024, 07, 01, 17, 54, 00, TimeSpan.FromHours 1.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
let expected =
|
||||||
|
"""{
|
||||||
|
"a": 3,
|
||||||
|
"b": "hello!",
|
||||||
|
"c": [1, -9],
|
||||||
|
"d": {
|
||||||
|
"it\u0027s-a-me": "dfe24db5-9f8d-447b-8463-4c0bcf1166d5",
|
||||||
|
"map": {},
|
||||||
|
"readOnlyDict": {},
|
||||||
|
"dict": {},
|
||||||
|
"concreteDict": {}
|
||||||
|
},
|
||||||
|
"e": ["I\u0027m-a-string"],
|
||||||
|
"arr": [-18883, 9100],
|
||||||
|
"byte": 87,
|
||||||
|
"sbyte": 89,
|
||||||
|
"i": 199993345,
|
||||||
|
"i32": -485832,
|
||||||
|
"i64": -13458625689,
|
||||||
|
"u": 458582,
|
||||||
|
"u32": 857362147,
|
||||||
|
"u64": 1234567892123414596,
|
||||||
|
"f": 8833345667.1,
|
||||||
|
"f32": 1000.98,
|
||||||
|
"single": 0.334,
|
||||||
|
"intMeasureOption": 981,
|
||||||
|
"intMeasureNullable": -883,
|
||||||
|
"enum": 1,
|
||||||
|
"timestamp": "2024-07-01T17:54:00.0000000\u002B01:00"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|> fun s -> s.ToCharArray ()
|
||||||
|
|> Array.filter (fun c -> not (Char.IsWhiteSpace c))
|
||||||
|
|> fun s -> new String (s)
|
||||||
|
|
||||||
|
JsonRecordTypeWithBoth.toJsonNode(data).ToJsonString () |> shouldEqual expected
|
||||||
|
JsonRecordTypeWithBoth.jsonParse (JsonNode.Parse expected) |> shouldEqual data
|
||||||
|
|
||||||
[<Test>]
|
[<Test>]
|
||||||
let ``Guids are treated just like strings`` () =
|
let ``Guids are treated just like strings`` () =
|
||||||
let guidStr = "b1e7496e-6e79-4158-8579-a01de355d3b2"
|
let guidStr = "b1e7496e-6e79-4158-8579-a01de355d3b2"
|
||||||
|
@@ -33,7 +33,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ApiSurface" Version="4.0.41"/>
|
<PackageReference Include="ApiSurface" Version="4.0.42"/>
|
||||||
<PackageReference Include="FsCheck" Version="2.16.6"/>
|
<PackageReference Include="FsCheck" Version="2.16.6"/>
|
||||||
<PackageReference Include="FsUnit" Version="6.0.0"/>
|
<PackageReference Include="FsUnit" Version="6.0.0"/>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/>
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/>
|
||||||
|
@@ -192,6 +192,10 @@ module internal JsonParseGenerator =
|
|||||||
node
|
node
|
||||||
|> asValueGetValue propertyName "string"
|
|> asValueGetValue propertyName "string"
|
||||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "DateTime" ; "Parse" ])
|
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "DateTime" ; "Parse" ])
|
||||||
|
| DateTimeOffset ->
|
||||||
|
node
|
||||||
|
|> asValueGetValue propertyName "string"
|
||||||
|
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "DateTimeOffset" ; "Parse" ])
|
||||||
| NumberType typeName -> parseNumberType options propertyName node typeName
|
| NumberType typeName -> parseNumberType options propertyName node typeName
|
||||||
| PrimitiveType typeName -> asValueGetValueIdent propertyName typeName node
|
| PrimitiveType typeName -> asValueGetValueIdent propertyName typeName node
|
||||||
| OptionType ty ->
|
| OptionType ty ->
|
||||||
|
@@ -38,6 +38,17 @@ module internal JsonSerializeGenerator =
|
|||||||
SynExpr.createLongIdent [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonValue" ; "Create" ]
|
SynExpr.createLongIdent [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonValue" ; "Create" ]
|
||||||
|> SynExpr.typeApp [ fieldType ]
|
|> SynExpr.typeApp [ fieldType ]
|
||||||
|> fun e -> e, false
|
|> fun e -> e, false
|
||||||
|
| DateTimeOffset ->
|
||||||
|
// fun field -> field.ToString("o") |> JsonValue.Create<string>
|
||||||
|
let create =
|
||||||
|
SynExpr.createLongIdent [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonValue" ; "Create" ]
|
||||||
|
|> SynExpr.typeApp [ SynType.named "string" ]
|
||||||
|
|
||||||
|
SynExpr.createIdent "field"
|
||||||
|
|> SynExpr.callMethodArg "ToString" (SynExpr.CreateConst "o")
|
||||||
|
|> SynExpr.pipeThroughFunction create
|
||||||
|
|> SynExpr.createLambda "field"
|
||||||
|
|> fun e -> e, false
|
||||||
| NullableType ty ->
|
| NullableType ty ->
|
||||||
// fun field -> if field.HasValue then {serializeNode ty} field.Value else JsonValue.Create null
|
// fun field -> if field.HasValue then {serializeNode ty} field.Value else JsonValue.Create null
|
||||||
let inner, innerIsJsonNode = serializeNode ty
|
let inner, innerIsJsonNode = serializeNode ty
|
||||||
|
@@ -241,6 +241,15 @@ module internal SynTypePatterns =
|
|||||||
| _ -> None
|
| _ -> None
|
||||||
| _ -> None
|
| _ -> None
|
||||||
|
|
||||||
|
let (|DateTimeOffset|_|) (fieldType : SynType) =
|
||||||
|
match fieldType with
|
||||||
|
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
|
||||||
|
match ident |> List.map (fun i -> i.idText) with
|
||||||
|
| [ "System" ; "DateTimeOffset" ]
|
||||||
|
| [ "DateTimeOffset" ] -> Some ()
|
||||||
|
| _ -> None
|
||||||
|
| _ -> None
|
||||||
|
|
||||||
let (|Uri|_|) (fieldType : SynType) =
|
let (|Uri|_|) (fieldType : SynType) =
|
||||||
match fieldType with
|
match fieldType with
|
||||||
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
|
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
|
||||||
|
24
nix/deps.nix
24
nix/deps.nix
@@ -3,8 +3,8 @@
|
|||||||
{fetchNuGet}: [
|
{fetchNuGet}: [
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "ApiSurface";
|
pname = "ApiSurface";
|
||||||
version = "4.0.41";
|
version = "4.0.42";
|
||||||
sha256 = "03kfa5ngmgkik9lc58sp8s9rrh9g40hhgjnrv662ks0d0y2i9i89";
|
sha256 = "0azjv64bbbhc4rndbjhcmqxxg1bkf1v3ym3x34zmsbz0lr1hy6pv";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "fantomas";
|
pname = "fantomas";
|
||||||
@@ -193,23 +193,23 @@
|
|||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NuGet.Common";
|
pname = "NuGet.Common";
|
||||||
version = "6.10.0";
|
version = "6.10.1";
|
||||||
sha256 = "0nizrnilmlcqbm945293h8q3wfqfchb4xi8g50x4kjn0rbpd1kbh";
|
sha256 = "1z69k0j727jcwrxzmvnixdac84lb9706iabqs8mrns8j7kbmw1ns";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NuGet.Configuration";
|
pname = "NuGet.Configuration";
|
||||||
version = "6.10.0";
|
version = "6.10.1";
|
||||||
sha256 = "1aqaknaawnqx4mnvx9qw73wvj48jjzv0d78dzwl7m9zjlrl9myhz";
|
sha256 = "0qy2bdi3dz6fdw7qbv77fg956idm9d9733j8b1pcrcj9pfayys26";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NuGet.Frameworks";
|
pname = "NuGet.Frameworks";
|
||||||
version = "6.10.0";
|
version = "6.10.1";
|
||||||
sha256 = "0hrd8y31zx9a0wps49czw0qgbrakb49zn3abfgylc9xrq990zkqk";
|
sha256 = "1p8d701fhbqv2r8vqmj948af9xvz2fd3273803cdrjy3a2wykmq1";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NuGet.Packaging";
|
pname = "NuGet.Packaging";
|
||||||
version = "6.10.0";
|
version = "6.10.1";
|
||||||
sha256 = "18s53cvrf51lihmaqqdf48p2qi6ky1l48jv0hvbp76cxwdg7rba4";
|
sha256 = "0zl8xfzvd1yij2ln6iwy6cz8qfwlbyyqlin872ab5y58ws61a2x2";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NuGet.Protocol";
|
pname = "NuGet.Protocol";
|
||||||
@@ -218,8 +218,8 @@
|
|||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NuGet.Versioning";
|
pname = "NuGet.Versioning";
|
||||||
version = "6.10.0";
|
version = "6.10.1";
|
||||||
sha256 = "1x19njx4x0sw9fz8y5fibi15xfsrw5avir0cx0599yd7p3ykik5g";
|
sha256 = "0lji7g6abnpmhzlgvni8wlb7l62n4180v3sphp4494wi0gn7ds4c";
|
||||||
})
|
})
|
||||||
(fetchNuGet {
|
(fetchNuGet {
|
||||||
pname = "NUnit";
|
pname = "NUnit";
|
||||||
|
Reference in New Issue
Block a user