Comments (12)
With #115 merged, I believe all outstanding issues raised here have a way to be solved.
from jason.
@DarkMarmot I find myself in a similar situation that requires decimals in json to not be strings.
I have applied a similar solution to yours, but I loose the decimal places I had specified.For example where I have
Decimal.new("1000.00"
), Jason returns it just1000
Please do you have a solution for this?
Thanks
After having failed to get other parties to change their standards -- and seeing that libraries in other languages like C# support this functionality, I feel it's a real issue for Elixir to have a pretty "standard" library that doesn't have a way to support this.
If Jason doesn't move to do so, I will open source a fork of it that handles this (I had really wanted to avoid that route, but it seems like enough people need it that it should be out there).
The easiest hack I found to preserve the data (though, ideally, it should be configurable at parse I think) -- is to hack the library in decoder.ex
, preserving floats at strings:
defp try_parse_float(string, _token, _skip) do
string
# :erlang.binary_to_float(string)
# catch
# :error, :badarg ->
# token_error(token, skip)
end
I ended up needing to store an intermediate data format for my use case, which Jason happily supports with encoder protocols, e.g.:
defmodule MyProject.Decimal do
defstruct value: nil
def new(value) when is_binary(value) do
%MyProject.Decimal{value: value}
end
end
defimpl Jason.Encoder, for: MyProject.Decimal do
def encode(decimal, _opts) do
Decimal.to_string(Decimal.new(decimal.value), :normal)
end
end
P.S. --Hopefully I haven't left something out. I did that a while ago and I'm having trouble doing code comparison because of mix format issues with special characters in the Jason lib from that time...
from jason.
Did you do manage to do it without forking?
What I meant is that I used Decimal.to_float() on my code, which was not that much of an inconvenience because I was doing some transform / data marshaling and not using the "jason data" straight.
So I didn't fork it because my use case was simpler and needed once (so far).
Yeah, I was building a library so I needed to support to/from JSON roundtrips with identical results. Having decoding options would really facilitate this for edge case needs I think.
from jason.
Nevermind -- I think I have a solution! :)
Using the helpful code from issue 71 -- one can wrap Decimal in a custom module to implement the protocol as an override! yay! :)
defimpl Jason.Encoder, for: FHIR.Decimal do
def encode(decimal, _opts) do
Decimal.to_string(decimal.decimal, :normal)
end
end
from jason.
So, I found I needed to hack the Decoder a tiny bit in order to read numbers as strings (otherwise, numeric information is lost...)
I'd love to have this as an option (I know, a terrible and evil option) in Jason and would happily submit a PR if you're amenable.
Otherwise, I fear I'll have to create a fork to host a Lossless_Jason for everyone who's trapped with the aberrant horrors of "standards" like FHIR. :(
from jason.
P.S. I enjoyed digging through your code! lots of tricks and syntax I hadn't used before! :)
from jason.
Could be useful for some fields, like that (broken) new medical spec, for numbers to be read from and to Decimal instead of BEAM floats with a given option or new code path to call?
from jason.
Did you ever find a way to make it work?
edit: I made my own intermediary step with Decimal.to_float()
from jason.
Did you ever find a way to make it work?
edit: I made my own intermediary step with Decimal.to_float()
Yeah, I created a local fork of Jason that could handle it (it was only a one line change -- I still feel it would've been a nice config option as other libraries/languages do support it).
Did you do manage to do it without forking?
I brought it up with the FHIR community and ended up irritating a bunch of people :(
from jason.
@DarkMarmot I find myself in a similar situation that requires decimals in json to not be strings.
I have applied a similar solution to yours, but I loose the decimal places I had specified.
For example where I have Decimal.new("1000.00"
), Jason returns it just 1000
Please do you have a solution for this?
Thanks
from jason.
Did you do manage to do it without forking?
What I meant is that I used Decimal.to_float() on my code, which was not that much of an inconvenience because I was doing some transform / data marshaling and not using the "jason data" straight.
So I didn't fork it because my use case was simpler and needed once (so far).
from jason.
It also appears that some work is going into this now. Wish this hadn't been denied as a feature back when... but hope:
#115
from jason.
Related Issues (20)
- Jason fails to encode HOT 1
- Better error messaging on invalid escapes
- Issue decoding particular string HOT 5
- fails to install in rebar3 HOT 2
- Proposal: Consistent number decoding
- Configure Jason to parse keys as atoms by default for Phoenix HOT 2
- Support JSON Canonical Scheme (JCS) - RFC 8785 HOT 2
- Json file can not be decoded HOT 1
- Heads up: Jason will be an ExDoc dependency HOT 1
- Map key validity/order in Elixir 1.14 HOT 3
- Misformatted README HOT 1
- Lists with numbers can parse to ASCII whitespace HOT 2
- Support for escape: :binary_safe HOT 4
- Change behaviour of Float HOT 1
- Why '/' not valid in JSON key? HOT 2
- Better error message on invalid `@derive Jason.Encoder` options HOT 1
- Status of v1.5? HOT 2
- Plan for Jason library after Erlang/OTP 27 added native support to JSON parsing HOT 2
- Compiler warnings with Elixir v1.17.0-rc.0 HOT 2
- @derive Jason.Encoder fails with a :_ (single underscore) struct field HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from jason.