digitalmars.D.learn - std.json cannot read an array floats back from file
- Yuri (19/19) Jul 02 2017 Hi there,
- Adam D. Ruppe (6/9) Jul 02 2017 I think it just read the json string of "1" as being an integer
- Yuri (4/15) Jul 03 2017 Yes, when accessing .integer instead of .floating then it works,
- Adam D. Ruppe (16/19) Jul 03 2017 Just write a helper function that casts it yourself:
- Yuri (4/23) Jul 03 2017 Thanks Adam, that will work for me. I wish though there was no
- ketmar (7/27) Jul 02 2017 'cause what you got back is `JSON_TYPE.INTEGER`. dunno why it is there a...
- Yuri (6/9) Jul 03 2017 I share your sentiment in relation to std.json, ketmar.
Hi there, consider the following simple use case: import std.json; float[] floats = [1,2,3]; JSONValue j = "{}".parseJSON; j.object["floats"] = floats; std.file.write("test.json", j.toString); JSONValue jj = readText("test.json").parseJSON; jj.object["floats"].array[1].floating.writeln; It is expected to print '2' in the console, however an exception is thrown: std.json.JSONException /build/ldc-I3nwWj/ldc-0.17.1/runtime/pho os/std/json.d(235): JSONValue is not a floating type while the below works fine: import std.json; float[] floats = [1,2,3]; JSONValue j = "{}".parseJSON; j.object["floats"] = floats; j.object["floats"].array[1].floating.writeln; any pointers to what could be going wrong?
Jul 02 2017
On Sunday, 2 July 2017 at 21:07:40 UTC, Yuri wrote:It is expected to print '2' in the console, however an exception is thrown: std.json.JSONException /build/ldc-I3nwWj/ldc-0.17.1/runtime/pho os/std/json.d(235): JSONValue is not a floating typeI think it just read the json string of "1" as being an integer instead of a float, so the reader thought it was integral instead of floating. It should prolly just transparently auto-convert, but it doesn't seem to. Try accessing the int instead and see waht happens.
Jul 02 2017
On Sunday, 2 July 2017 at 21:12:48 UTC, Adam D. Ruppe wrote:On Sunday, 2 July 2017 at 21:07:40 UTC, Yuri wrote:Yes, when accessing .integer instead of .floating then it works, unfortunately that is not suitable for the task at hand, it has to be a float.It is expected to print '2' in the console, however an exception is thrown: std.json.JSONException /build/ldc-I3nwWj/ldc-0.17.1/runtime/pho os/std/json.d(235): JSONValue is not a floating typeI think it just read the json string of "1" as being an integer instead of a float, so the reader thought it was integral instead of floating. It should prolly just transparently auto-convert, but it doesn't seem to. Try accessing the int instead and see waht happens.
Jul 03 2017
On Monday, 3 July 2017 at 13:26:52 UTC, Yuri wrote:Yes, when accessing .integer instead of .floating then it works, unfortunately that is not suitable for the task at hand, it has to be a float.Just write a helper function that casts it yourself: double numeric(JSONValue v) { if(v.type == JSON_VALUE.FLOAT) return v.floating; else if(v.type == JSON_VALUE.INTEGER) return v.integer; else if(v.type == JSON_VALUE.UINTEGER) // I think it has this too return v.uinteger; throw new Exception("not a numeric type, instead: " ~ to!string(v.type)); } and then you should be able to do jj.object["floats"].array[1].numeric.writeln; and have it return float regardless of if it is 1 or 1.0
Jul 03 2017
On Monday, 3 July 2017 at 13:34:50 UTC, Adam D. Ruppe wrote:On Monday, 3 July 2017 at 13:26:52 UTC, Yuri wrote:Thanks Adam, that will work for me. I wish though there was no need for jumping these hoops in a standard language lib but I guess it would be a topic for another discussion.Yes, when accessing .integer instead of .floating then it works, unfortunately that is not suitable for the task at hand, it has to be a float.Just write a helper function that casts it yourself: double numeric(JSONValue v) { if(v.type == JSON_VALUE.FLOAT) return v.floating; else if(v.type == JSON_VALUE.INTEGER) return v.integer; else if(v.type == JSON_VALUE.UINTEGER) // I think it has this too return v.uinteger; throw new Exception("not a numeric type, instead: " ~ to!string(v.type)); } and then you should be able to do jj.object["floats"].array[1].numeric.writeln; and have it return float regardless of if it is 1 or 1.0
Jul 03 2017
Yuri wrote:Hi there, consider the following simple use case: import std.json; float[] floats = [1,2,3]; JSONValue j = "{}".parseJSON; j.object["floats"] = floats; std.file.write("test.json", j.toString); JSONValue jj = readText("test.json").parseJSON; jj.object["floats"].array[1].floating.writeln; It is expected to print '2' in the console, however an exception is thrown: std.json.JSONException /build/ldc-I3nwWj/ldc-0.17.1/runtime/pho os/std/json.d(235): JSONValue is not a floating type while the below works fine: import std.json; float[] floats = [1,2,3]; JSONValue j = "{}".parseJSON; j.object["floats"] = floats; j.object["floats"].array[1].floating.writeln; any pointers to what could be going wrong?'cause what you got back is `JSON_TYPE.INTEGER`. dunno why it is there at all, as JSON has no "integers" per se, but it read as integer, and `.floating` failed type checking. so, write your own wrapper that will convert INTEGER/UINTEGER/FLOAT to `double`. i think this is the best solution (if there can be "best solution" with std.json at all).
Jul 02 2017
On Sunday, 2 July 2017 at 21:15:41 UTC, ketmar wrote:so, write your own wrapper that will convert INTEGER/UINTEGER/FLOAT to `double`. i think this is the best solution (if there can be "best solution" with std.json at all).I share your sentiment in relation to std.json, ketmar. On a side note, what would be a better way to serialize/deserialize objects in D if std.json does not cut it? It does not have to be JSON serialization although would be preferred.
Jul 03 2017
Yuri wrote:On Sunday, 2 July 2017 at 21:15:41 UTC, ketmar wrote:it depends of the types of your objects. simple json-like (de)serializer for objects with fixed layout can be done in very small amount of code[0]. that's what i am using (and it can *read* json into structs too, i'm actually using it to parse some jsons -- idgames API replies, for example). [0] http://repo.or.cz/iv.d.git/blob_plain/HEAD:/txtser.dso, write your own wrapper that will convert INTEGER/UINTEGER/FLOAT to `double`. i think this is the best solution (if there can be "best solution" with std.json at all).I share your sentiment in relation to std.json, ketmar. On a side note, what would be a better way to serialize/deserialize objects in D if std.json does not cut it? It does not have to be JSON serialization although would be preferred.
Jul 03 2017
On Monday, 3 July 2017 at 14:04:47 UTC, ketmar wrote:Yuri wrote:Thanks, ketmar, I'll have a look into the code, the objects I am dealing with are not particularly complex, that might work well enough.On Sunday, 2 July 2017 at 21:15:41 UTC, ketmar wrote:it depends of the types of your objects. simple json-like (de)serializer for objects with fixed layout can be done in very small amount of code[0]. that's what i am using (and it can *read* json into structs too, i'm actually using it to parse some jsons -- idgames API replies, for example). [0] http://repo.or.cz/iv.d.git/blob_plain/HEAD:/txtser.d[...]I share your sentiment in relation to std.json, ketmar. On a side note, what would be a better way to serialize/deserialize objects in D if std.json does not cut it? It does not have to be JSON serialization although would be preferred.
Jul 03 2017
Yuri wrote:On Monday, 3 July 2017 at 14:04:47 UTC, ketmar wrote:it doesn't matter if objects are complex or not; the only thing that matters is that you must really have *objects* that can be described by structs, not "freeform" json. i.e. txtser cannot deserialize json into dom-like tree structure, only deserialize structs/arrays/aas. but structs can contain other structs, and AA values can be structs too, and so on. i.e.: if you don't need arbitrary access to arbitrary json fields, but only have to deserialize something with known layout, txtser probably can do the job for you.Yuri wrote:Thanks, ketmar, I'll have a look into the code, the objects I am dealing with are not particularly complex, that might work well enough.On Sunday, 2 July 2017 at 21:15:41 UTC, ketmar wrote:it depends of the types of your objects. simple json-like (de)serializer for objects with fixed layout can be done in very small amount of code[0]. that's what i am using (and it can *read* json into structs too, i'm actually using it to parse some jsons -- idgames API replies, for example). [0] http://repo.or.cz/iv.d.git/blob_plain/HEAD:/txtser.d[...]I share your sentiment in relation to std.json, ketmar. On a side note, what would be a better way to serialize/deserialize objects in D if std.json does not cut it? It does not have to be JSON serialization although would be preferred.
Jul 03 2017