-
Notifications
You must be signed in to change notification settings - Fork 32
added Converter #145
base: master
Are you sure you want to change the base?
added Converter #145
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
module Thoth.Json.Net.Converters | ||
|
||
open Newtonsoft.Json | ||
open Newtonsoft.Json.Linq | ||
|
||
type Converter (?isCamelCase : bool, ?extra: ExtraCoders) = | ||
inherit JsonConverter() | ||
|
||
override __.CanConvert(t) = true | ||
|
||
override __.WriteJson(writer, value, _) = | ||
let t = value.GetType() | ||
let encoder = Encode.Auto.generateEncoderCached(t, ?isCamelCase=isCamelCase, ?extra=extra) | ||
(encoder value).WriteTo(writer) | ||
writer.Flush() | ||
|
||
override __.ReadJson(reader, t, _, _) = | ||
let decoder = Decode.Auto.generateDecoderCachedByType(t, ?isCamelCase=isCamelCase, ?extra=extra) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would use the version which use the generic type here too (same as above) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, it is not like above. t is of System.Type (and not generic as the value) |
||
let json = JObject.Load(reader).ToString() | ||
Decode.fromString decoder json | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should use |
||
|> function | ||
| Ok value -> value | ||
| Error er -> failwith er | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,24 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<PropertyGroup> | ||
<Description>Elm-inspired encoder and decoder for JSON targetting .Net and NetCore runtime</Description> | ||
<PackageProjectUrl>https://github.com/MangelMaxime/Thoth</PackageProjectUrl> | ||
<PackageLicenseUrl>https://github.com/MangelMaxime/Thoth/blob/master/LICENSE.md</PackageLicenseUrl> | ||
<RepositoryUrl>https://github.com/MangelMaxime/Thoth</RepositoryUrl> | ||
<PackageTags>fsharp;json</PackageTags> | ||
<Authors>Maxime Mangel</Authors> | ||
<Version>3.0.0-beta-002</Version> | ||
</PropertyGroup> | ||
<PropertyGroup> | ||
<TargetFrameworks>netstandard2.0;net46</TargetFrameworks> | ||
<GenerateDocumentationFile>true</GenerateDocumentationFile> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="Types.fs" /> | ||
<Compile Include="Decode.fs" /> | ||
<Compile Include="Encode.fs" /> | ||
<Compile Include="Extra.fs" /> | ||
</ItemGroup> | ||
<Import Project="..\..\.paket\Paket.Restore.targets" /> | ||
</PropertyGroup> | ||
<PropertyGroup> | ||
<TargetFrameworks>netstandard2.0;net46</TargetFrameworks> | ||
<GenerateDocumentationFile>true</GenerateDocumentationFile> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="Types.fs" /> | ||
<Compile Include="Decode.fs" /> | ||
<Compile Include="Encode.fs" /> | ||
<Compile Include="Extra.fs" /> | ||
<Compile Include="Converters.fs" /> | ||
</ItemGroup> | ||
<Import Project="..\..\.paket\Paket.Restore.targets" /> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
Usage | ||
|
||
```fsharp | ||
|
||
open Thoth.Json.WebApi | ||
|
||
[<WithThothJsonNet>] | ||
type FableController () = | ||
inherit ApiController () | ||
|
||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
namespace Thoth.Json.WebApi | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this belongs to Thoth.Json.Net You are adding There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the new package Thoth.Json.WepApi. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it. Thoth.Json,Giraffe is now also in its own repository :-) |
||
|
||
open System.Web.Http.Controllers | ||
open System.Net.Http.Formatting | ||
open Newtonsoft.Json | ||
open Thoth.Json.Net | ||
|
||
type WithThothJsonNetAttribute(?isCamelCase : bool, ?extra : ExtraCoders) = | ||
inherit System.Attribute() | ||
interface IControllerConfiguration with | ||
member __.Initialize((controllerSettings : HttpControllerSettings), _) = | ||
let converter = | ||
Thoth.Json.Net.Converters.Converter(?isCamelCase = isCamelCase, ?extra = extra) | ||
let thothFormatter = | ||
JsonMediaTypeFormatter | ||
(SerializerSettings = JsonSerializerSettings(Converters = [| converter |])) | ||
controllerSettings.Formatters.Clear() | ||
controllerSettings.Formatters.Add thothFormatter |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<OutputType>Library</OutputType> | ||
<TargetFramework>net46</TargetFramework> | ||
<DebugType>portable</DebugType> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<ProjectReference Include="../Thoth.Json.Net/Thoth.Json.Net.fsproj" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Compile Include="Thoth.Json.WebApi.fs" /> | ||
</ItemGroup> | ||
<Import Project="..\..\.paket\Paket.Restore.targets" /> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
FSharp.Core | ||
|
||
group WebApi | ||
Microsoft.AspNet.WebApi | ||
Microsoft.AspNet.WebApi.Core | ||
Microsoft.AspNet.WebApi.Client | ||
Newtonsoft.Json |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
module Tests.Converter | ||
|
||
open Newtonsoft.Json | ||
open Expecto | ||
open Util.Testing | ||
|
||
let encodeWithConverter<'T> (converter: JsonConverter) (space: int) (value: obj) : string = | ||
let format = if space = 0 then Formatting.None else Formatting.Indented | ||
let settings = JsonSerializerSettings(Converters = [|converter|], | ||
Formatting = format, | ||
DateTimeZoneHandling = DateTimeZoneHandling.Utc ) | ||
JsonConvert.SerializeObject(value, settings) | ||
|
||
let decodeStringWithConverter<'T> (converter: JsonConverter) (json: string): Result<'T, string> = | ||
try | ||
JsonConvert.DeserializeObject<'T>(json, converter) |> Ok | ||
with ex -> | ||
Error("Given an invalid JSON: " + ex.Message) | ||
|
||
|
||
type MyUnion = Foo of int | ||
|
||
type Record2 = | ||
{ a : float | ||
b : float } | ||
|
||
type Record9 = | ||
{ a: int | ||
b: string | ||
c: (bool * int) list | ||
d: MyUnion | ||
e: Map<string, Record2> | ||
f: System.DateTime | ||
} | ||
|
||
let tests : Test = | ||
testList "Thoth.Json.Converter" [ | ||
|
||
testList "Basic" [ | ||
testCase "roundtrip works" <| fun _ -> | ||
let converter = Thoth.Json.Net.Converters.Converter false | ||
let json = | ||
{ a = 5 | ||
b = "bar" | ||
c = [false, 3; true, 5; false, 10] | ||
d = Foo 14 | ||
e = Map [("oh", { a = 2.; b = 2. }); ("ah", { a = -1.5; b = 0. })] | ||
f = System.DateTime.Now | ||
} |> encodeWithConverter converter 4 | ||
let result = decodeStringWithConverter converter json | ||
match result with | ||
| Error er -> failwith er | ||
| Ok r2 -> | ||
equal 5 r2.a | ||
equal "bar" r2.b | ||
equal [false, 3; true, 5; false, 10] r2.c | ||
equal (Foo 14) r2.d | ||
equal -1.5 (Map.find "ah" r2.e).a | ||
equal 2. (Map.find "oh" r2.e).b | ||
] | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
FSharp.Core | ||
Expecto | ||
Newtonsoft.Json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will fails if
value
isNone
. See for the solutionThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm.
If I write
override __.WriteJson(writer, (value : 'T), _) =
, value must be an object and can't be a value type anymore.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MangelMaxime , please ignore last comment. the value must be an obj, otherwise it cannnot be represented as Json. And for the very same reason the value cannot be simply
None
. Simplest value should be ``[| None |].
However, it still doesn't work . If code is changed to
WriteTo fails in tests with
System.ArgumentException: "Could not determine JSON object type for type Record9."