-
-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Work on the unification of Thoth.Json and Thoth.Json.Net #175
Comments
This sounds great! Please let me know if any help is required. I have an almost complete implementation of the Auto module (reflection) that may help. |
Thank you for proposing. Currently, I have the manual API done for both encoder and decoder. And will definitely need help and feedback on the implementation. For example, my plan is to make
My idea by making |
I think this makes sense so that existing users can stay on the old approach.
My view is the shorter names are better - and a JS version of these seems unlikely! In terms of project structure, one of the pain-points before was having to work across two repos. This will of course become worse with more "back-ends". Any thoughts on maintaining the official packages in one place? With AoT compilation becoming more important, I think the "auto" module should also be spun out of the core. This means that reflection is opt-in, and allows more to be built on top of |
Well it is not only JavaScript but also Python, Rust, and any future target that Fable will support. But I do agree, that the chance of having a conflict in the name of the libraries is very low. TBH currently, I am using the short version name for the packages.
There are indeed all going under the same repository. This is a bit of a mess right now, but this idea is you have the different libraries under The idea is that we want to write the exact same source code for each target to make sure that they support the same features sets. Some different can exists for things that are platform specific like the invalid JSON exception but 99% of tests should use the same code.
If we are to move it to a separate package it probably means that we will need to duplicate the number of packages.
Personally, I am ok with moving it separate packages because it will show that this is an opt-in feature. And this means that features like CEs DSLs, codec, will be treated in the same way. They are additions to the manual API. |
Is there a WIP branch for this? |
Hello @njlr, The manual APIs packages have already been created and pushed to NuGet.
To use the new API, you need to open And then open I was working on updating the documentation before making an announcement and as always had to prioritise other stuff (and was kind of expecting Eleventy v3 to be released soon but it has not been the case 😅). Should have some time available in the coming weeks to finish that and have it off my mind. I think I have a local branch to work on the Auto API but I will need to take a look to see in what state it is currently in. |
Thanks, I was able to play around with it: #r "nuget: Thoth.Json.Core, 0.2.1"
#r "nuget: Thoth.Json.Newtonsoft, 0.1.0"
open Thoth.Json.Core
type Book =
{
Title : string
Year : int
Author : string
}
[<RequireQualifiedAccess>]
module Book =
let encode : Encoder<Book> =
fun x ->
Encode.object
[
"title", Encode.string x.Title
"year", Encode.int x.Year
"author", Encode.string x.Author
]
let decode : Decoder<Book> =
Decode.object
(fun get ->
{
Title = get.Required.Field "title" Decode.string
Year = get.Required.Field "year" Decode.int
Author = get.Required.Field "author" Decode.string
})
open Thoth.Json.Newtonsoft
[<RequireQualifiedAccess>]
module Decode =
let unsafeFromString decoder json =
match Decode.fromString decoder json with
| Ok x -> x
| Error error -> failwith error
let book =
{
Title = "The Monkey Wrench Gang"
Year = 1975
Author = "Edward Abbey"
}
let json =
book
|> Book.encode
|> Encode.toString 2
printfn $"%s{json}"
let decoded =
json
|> Decode.unsafeFromString Book.decode
printfn $"%A{decoded}" One suggestion to make upgrading easier would be for the |
Maybe I hit a bug? #r "nuget: Thoth.Json.Core, 0.2.1"
#r "nuget: Thoth.Json.Newtonsoft, 0.1.0"
open Thoth.Json.Core
open Thoth.Json.Newtonsoft
let json =
Encode.int16 -7s
|> Encode.toString 0
printfn $"%s{json}"
// 4294967289 |
I have tidied up the auto code I have and ported it to It largely unifies Fable and .NET, aside from cases where Fable's reflection capabilities are limited (here erasure can be used instead). If it's useful, I can help integrate thoth-org. Thanks! |
Perhaps, F#/Newtonsoft doesn't like all the type casting happening?
Thoth.Json/packages/Thoth.Json.Newtonsoft/Encode.fs Lines 33 to 37 in 606f885
Thoth.Json.Core unify all the integral values to Thanks for looking into the Auto API, I will have a look at it. |
Perhaps this is a good time to make a breaking change? #r "nuget: System.Text.Json, 8.0.3"
open System.Text.Json
let json = JsonSerializer.Serialize(-7s)
printfn $"%s{json}"
// -7 I don't think users would expect overflow for |
Oh you mean, I made a mistakes by converting a Depends on what you mean by breaking changes, the JSON representation cannot be changed compared to Thoth.Json because I know some people who stored the JSON databases meaning we need to be backward compatible at least for the JSON representation. API wise, it is possible to have breaking changes indeed Thoth.Json.Core is released as 0.x which is a beta version. |
On this type: [<RequireQualifiedAccess; NoComparison>]
type Json =
| String of string
| Char of char
| DecimalNumber of float
| Null
| Boolean of bool
| Object of (string * Json) seq
| Array of Json[]
// Thoth.Json as an abritrary limit to the size of numbers
| IntegralNumber of uint32
| Unit I wonder where a negative
It's interesting to see how other libraries handle this. yojson allows for an FSharp.Data uses Newtonsoft has The JSON spec leaves it up to the implementation 🤷 |
I wonder if Before: type Encoder<'T> = 'T -> Json After: type IEncodable =
abstract member Encode<'JsonValue> :
helpers: IEncoderHelpers<'JsonValue> -> 'JsonValue
type Encoder<'T> = 'T -> IEncodable
// Probably won't work as-is, just a sketch
The Worth noting that the JSON type for encoding and decoding may be different (see thoth-org/Thoth.Json.Net#52 (comment)) |
I don't remember the exact problem but I was not able to do it because of how the generics types are resolved with F#. I think, the generics leaked too far in the caller code leading to issues / code being not friendly. Sorry, I don't exactly remember the situation it was a few months ago. Using the current The compiler now helps him identify that he needs to call
This should not be a problem because I will just need to remember this fact when creating type ICodecHelpers<'DecodeJsonValue, 'EncodeJsonValue> =
inherit IDecoderHelpers<'DecodeJsonValue>
inherit IEncoderHelpers<'EncodeJsonValue>
// or
type ICodecHelpers<'DecodeJsonValue, 'EncodeJsonValue> =
abstract decoderHelpers: IDecoderHelpers<'DecodeJsonValue>
abstract encoderHelpers: IEncoderHelpers<'EncodeJsonValue> And so here we need to make the distinction between both generic types. |
I think the trick is to have two types I made a draft PR to show what I mean here: #188 It's quite a small impact change overall. |
Here is an implementation of "Auto" that is agnostic to the JSON backend: #189 |
@njlr Thank you I would make some time during this week to look at all the PRs you sent. The one reworking the manual API looked good last time I checked and will probably be released this week. For the Auto API, I need to look into more as this is a more tricky API IHMO and also because there are improvements that I want to add compared to the legacy behaviour. I will also take the time to make yet another macro list of what I would like to have done before considering the new Thoth.Json "stable" in order to push the that stable release forward. Thank you again for all the time you are investing in this project. |
That sounds good! Next on my list was a System JSON backend, but will wait for your list to avoid overlap. |
Nowadays, I leaning to having a Thoth.Json package which contains the logic of the decoders and then have different backend package which implements an interface to provide support for
Fable.Core.JS.JSON
,Newtonsoft
,System.Text.Json
, etc.The text was updated successfully, but these errors were encountered: