Recent

Author Topic: ezjson - JSON serialize / deserialize with attributes  (Read 1630 times)

mr-highball

  • Full Member
  • ***
  • Posts: 214
    • Highball Github
ezjson - JSON serialize / deserialize with attributes
« on: January 03, 2020, 12:49:26 am »
Hey everyone, hope everyone had a good start to the new year  :D
The past few days I've been working on JSON serialization / deserialization using custom attributes. These work by attaching two types of decorators to either your classes / interfaces or to properties of classes / interfaces.
Each decorator simply takes a name to be used when when serializing

JsonObject('objectName')
JsonProperty('propertyName')

Once you have your decorated objects, you can then call one of two generic methods,
EZSerialize<T>(...) (outputs json)
EZDeSerialize<T>(...) (input json)

An example is worth a 1000 words, so here you go,

Code: Pascal  [Select][+][-]
  1.   { TTestDecorated }
  2.   (*
  3.     a simple object decorated with a custom name to be used when serializing and
  4.     deserializing, as well as some simple typed properties to include in
  5.     serialization
  6.   *)
  7.   [JsonObject('myTestObject')]
  8.   TTestDecorated = class(TObject)
  9.   private
  10.     FTest : String;
  11.     FTestInt : Integer;
  12.   published
  13.     [JsonProperty('test')]
  14.     property Test : String read FTest write FTest;
  15.  
  16.     [JsonProperty('testInteger')]
  17.     property TestInt : Integer read FTestInt write FTestInt;
  18.   end;
  19.  
  20.   ...
  21.  
  22. procedure TestSimple;  
  23. var
  24.   LTest : TTestDecorated;
  25.   LJSON,
  26.   LError : String;
  27. begin
  28.   //setting a value on our test
  29.   LTest := TTestDecorated.Create;
  30.   LTest.Test := 'a test';
  31.  
  32.   //calling serialize
  33.   if not (EZSerialize<TTestDecorated>(LTest, LJSON, LError)) then
  34.     raise Exception.Create(LError) //failed to serialize
  35.   else
  36.     WriteLn(LJSON); //success
  37. end;
  38.  

the output from above is below,
{ "myTestObject" : { "test" : "a value", "testInteger" : 0 } }

Nested object or interface properties can also be used in conjunction with standard types, here's another example (minus the calling code for brevity)

Code: Pascal  [Select][+][-]
  1. TTestComplex = class(TObject)
  2.   private
  3.     FDecorated: TTestDecorated;
  4.     FNonDecorated: TTestNonDecorated;
  5.   public
  6.     constructor Create;
  7.     destructor Destroy; override;
  8.   published
  9.     [JsonProperty('decorated')]
  10.     property Decorated : TTestDecorated read FDecorated;
  11.  
  12.     [JsonProperty('nonDecorated')]
  13.     property NonDecorated : TTestNonDecorated read FNonDecorated;
  14.   end;
  15.  

and here's the output when serialized,

{ "TestComplex" : { "decorated" : { "test" : "a value", "testInteger" : 0 }, "nonDecorated" : { "test" : "" } } }

I'm actively working on this, and right now only serialization has been implemented (still working on deserialize  :-[ ) but I thought someone might find some use or could provide a second set of eyes.

here's the repo, https://github.com/mr-highball/ezjson

Cheers 🍻
« Last Edit: January 03, 2020, 01:06:00 am by mr-highball »

mr-highball

  • Full Member
  • ***
  • Posts: 214
    • Highball Github
Re: ezjson - JSON serialize / deserialize with attributes
« Reply #1 on: February 11, 2020, 04:32:01 pm »
running into some rtti issues, that are stalling finishing this library up reported here -> https://bugs.freepascal.org/view.php?id=36651

serialize "should" be ok, and deserialize is in a rough draft state but isn't properly working (either misunderstanding on my part or bug)

the bug report has my test cases and descriptions of each,
if anyone can help out and look over that would be nice :)

mr-highball

  • Full Member
  • ***
  • Posts: 214
    • Highball Github
Re: ezjson - JSON serialize / deserialize with attributes
« Reply #2 on: February 29, 2020, 03:37:22 pm »
Shoutout to @Pascaldragon for helping me with this and for pointing out my wrong usage of typeinfo method  :-[

Pushed a new commit which seems to be working for both serializing and deserializing. Deserializing code is currently on written for standard types (not objects / interfaces) but support for that will be added soon now that I have a path forward.

Slawek

  • New Member
  • *
  • Posts: 13
Re: ezjson - JSON serialize / deserialize with attributes
« Reply #3 on: October 09, 2020, 11:59:01 am »
Hi,
I noticed you are using JsonObject and JsonProperty in your class like [JsonObject('myTestObject')] and [JsonProperty('test')].
But in Lazarus I can't compile it.
I am getting a syntax error: Fatal: Syntax error, "IMPLEMENTATION" expected but "[" found
What does the compiler need to accept this syntax?
Regards, Slawek

mr-highball

  • Full Member
  • ***
  • Posts: 214
    • Highball Github
Re: ezjson - JSON serialize / deserialize with attributes
« Reply #4 on: October 09, 2020, 07:10:14 pm »
Hi @slawek, first if you're trying to use the ezjson decorators you'd need to git clone my repo and add the src path to your project "other units". If you're just trying to play with custom attributes you'd need the latest fpc/lazarus since they were a new addition.
https://wiki.freepascal.org/Custom_Attributes

Hope this helps!

Slawek

  • New Member
  • *
  • Posts: 13
Re: ezjson - JSON serialize / deserialize with attributes
« Reply #5 on: October 10, 2020, 01:57:46 am »
Hi,
Thank you for the quick reply. I'm just learning JSON in Lazarus. I have Lazarus 2.0.10 with FPC 3.2.0 64bit. Revision of SVN 63526. Date 07-07-2020.
I found this article first: https://community.idera.com/developer-tools/programming-languages/f/delphi-language/69467/json---converting-array-of-custom-records-to-json-text
I used the {$modeswitch prefixedattributes} directive, but that doesn't work either.

mr-highball

  • Full Member
  • ***
  • Posts: 214
    • Highball Github
Re: ezjson - JSON serialize / deserialize with attributes
« Reply #6 on: October 10, 2020, 03:49:57 am »
That version should be new enough, but since ezjson is non-standard, are you certain you have pulled down the git repo and included it in the search path? Also, please post a bit of code so I can look over your syntax and try it locally

Slawek

  • New Member
  • *
  • Posts: 13
Re: ezjson - JSON serialize / deserialize with attributes
« Reply #7 on: October 10, 2020, 09:47:24 am »
I haven't used ezjson yet.
I just wanted to compile sample programs from https://wiki.freepascal.org/Custom_Attributes
Unfortunately, I get errors like:
tcustomattr.lpr(4,2) Warning: Illegal compiler switch "PREFIXEDATTRIBUTES+"
tcustomattr.lpr(7,25) Error: Identifier not found "TCustomAttribute"
tcustomattr.lpr(7,41) Error: class type expected, but got "<erroneous type>"
tcustomattr.lpr(15,4) Fatal: Syntax error, "BEGIN" expected but "[" found
testattributes.lpr(19,31) Error: Identifier not found "TCustomAttribute"
testattributes.lpr(19,47) Error: class type expected, but got "<erroneous type>"
testattributes.lpr(38,4) Fatal: Syntax error, "BEGIN" expected but "[" found

I also have FPC 3.2.0 on Linux (Fedora 32) and I get the same errors as on Windows.

Thought you could help me since you use these attributes. I still don't understand why it doesn't work for me.
« Last Edit: October 10, 2020, 09:50:50 am by Slawek »

PascalDragon

  • Hero Member
  • *****
  • Posts: 2418
  • Compiler Developer
Re: ezjson - JSON serialize / deserialize with attributes
« Reply #8 on: October 10, 2020, 12:13:07 pm »
I also have FPC 3.2.0 on Linux (Fedora 32) and I get the same errors as on Windows.

Custom attributes are only available in the development version 3.3.1.

Slawek

  • New Member
  • *
  • Posts: 13
Re: ezjson - JSON serialize / deserialize with attributes
« Reply #9 on: October 10, 2020, 12:20:33 pm »
Yes, I just found this information too. Thanks for your confirmation.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2418
  • Compiler Developer
Re: ezjson - JSON serialize / deserialize with attributes
« Reply #10 on: October 10, 2020, 12:25:26 pm »
I have now highlighted that in the wiki article you linked.

mr-highball

  • Full Member
  • ***
  • Posts: 214
    • Highball Github
Re: ezjson - JSON serialize / deserialize with attributes
« Reply #11 on: October 10, 2020, 10:01:07 pm »
Ahh sorry was misunderstanding. We'll for getting the latest versions of fpc/lazarus a very easy tool is fpcupdeluxe (I use it all of the time)
https://github.com/LongDirtyAnimAlf/fpcupdeluxe

Just go to the "releases" tab and select the version for your OS and with a few clicks you can have a separate installation for trunk.

 

TinyPortal © 2005-2018