-
Notifications
You must be signed in to change notification settings - Fork 32
Add auto encoder/decoder #30
Add auto encoder/decoder #30
Conversation
Ok, at the end I removed the |
I used rollup because I needed to read the generate JavaScript when creating the library. And webpack doesn't really fit that need :) Now, that most of the lib has been written it should be ok to use webpack instead. |
I wonder if the new implementation of And I do prefer the new implementation without the JavaScript files. 👍 |
We should add an option to specify if we want the json to use Also, is the Fable 2 reflection API allowing us to add attributes to record properties to do something like: type R = { [<PropName("foo")>] Bar of string } |
Indeed. I actually replaced Rollup with fable-splitter for the tests, so the code should still be readable (and also in multiple files).
I added a test for nested lists. Seems to work :)
I'll leave that as an exercise for you and other Thoth.Json contributors ;)
Nope, there's very little reflection info made available (only the Type fullname and generics, besides field and case info only for records and generics respectively) and attribute info cannot be accessed at runtime (you could use Anyways, the good news is I could enable automatic (de)serialization for .NET too! Unfortunately I couldn't follow the same approach as I was getting runtime errors when trying to cast values parsed with |
src/Thoth.Json.Net/Decode.fs
Outdated
@@ -460,3 476,11 @@ let optional key valDecoder fallback decoder = | |||
|
|||
let optionalAt path valDecoder fallback decoder = | |||
custom (optionalDecoder (at path value) valDecoder fallback) decoder | |||
|
|||
type Auto = |
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.
@alfonsogarciacaro Can you please explain me what this type do ?
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.
It's necessary to have a type in order to use static members for optional arguments (in Thoth.Json, ITypeResolver
). Here I'm just using it to have the same API surface as Thoth.Json, but I guess a module should also work (we don't need the injectable optional argument on the .NET side).
I will do it so I can better understand your code :)
That's unfortunate, we will need to make it clear that auto mode on .Net side will not validate the data. Is this runtime error limitation due to how .Net works ? |
Ah, I didn't think of that! Well, Newtonsoft.Json error reporting is quite good: you get the path and the location (line and column) of the issue in the JSON string. Though it's true we can improve some of the error messages. Fable erases generics at runtime, so it's possible to do a cast from |
@MangelMaxime We probably should add more tests and improve the error messages in the .Net converters, but for now I think this is ready to merge. I tested it with one of my work projects and it's working 🎉 so it'll be nice to have an alpha release of Thoth.Json compatible with Fable 2. |
@alfonsogarciacaro I removed But perhaps we can add the missing one to .Net version. Not sure how to do that however |
src/Thoth.Json/Decode.fs
Outdated
@@ -543,12 543,21 @@ let private mixedArray msg (decoders: Decoder<obj>[]) (values: obj[]): Result<ob | |||
| Error _ -> acc | |||
| Ok result -> decoder value |> Result.map (fun v -> v::result)) | |||
|
|||
let rec private autoDecodeRecordsAndUnions (t: System.Type): Decoder<obj> = | |||
let inline private lowerCase (s: string) = | |||
s |> Seq.mapi (fun i c -> match i with | 0 -> (System.Char.ToLower c) | _ -> c) |> System.String.Concat |
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.
Nice work! One suggestion though, this is traversing through all the chars just to lower the first one, slicing fits here nicely: (string s.[0]).ToLower() s.[1..]
. I'd also give more information in the function name, even if it's private: lowerFirstChar
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.
Or also: s.[..0].ToLowerInvariant() s.[1..]
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.
Yes I saw this problem about traversing all the chars and didn't know how to fix it :)
Will update using slicing.
Closing as this has been superseded by #38 |
This still needs some work but it's looking good :) Please have a try and let me know what you think, the new API and function names are just tentative (though we need a static member for optional arguments). I only implemented it in Fable side for now, but a similar approach should work for .NET too, though we will likely have issues with generic casting (
unbox< Decoder<obj> > int
). We will need to add an untyped interface (likeIDecoder
) or use something like the crates they talked about in latest F# eXchange.I also took chance to remove some of the JS code (either in its own file or in
Emit
attributes) and replace it with F# code, to make it more maintainable. I hope that's OK.Besides that, I replaced rollup because I haven't updated the plugin yet for Fable 2. And I had some issues with the
Thoth.Json.Net.fsproj
reference when compiling the tests for Fable so I added an MSBuild condition. But now that I think about it, maybe it's because I used theallFiles
option for fable-splitter and removing it may just be enough, hmmm 🤔