neo json and valueSchema for integer attributes ...

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

neo json and valueSchema for integer attributes ...

marten
I have a class with an instance attribute "x" and this one contains an
integer value.

No when exporting this to json I want to write a string instead of this
number to the json string ...

neoJsonMapping: mapper
  mapper for: self do: [ :mapping |
    (mapping mapInstVar: #x to: 'x') valueSchema: #AsString.
  ].

  mapper for: #AsString customDo: [ :mapping |
    mapping encoder: [ :anInteger | x asString ].
    mapping decoder: [ :aString | ... ] ].

But whatever I do ... only numbers are written out ... and yes of course
I could add additional accessors doing the conversion.

--
Marten Feldtmann

Reply | Threaded
Open this post in threaded view
|

Re: neo json and valueSchema for integer attributes ...

NorbertHartl

Am 21.02.2014 um 07:50 schrieb [hidden email]:

> I have a class with an instance attribute "x" and this one contains an
> integer value.
>
> No when exporting this to json I want to write a string instead of this
> number to the json string ...
>
> neoJsonMapping: mapper
>  mapper for: self do: [ :mapping |
>    (mapping mapInstVar: #x to: 'x') valueSchema: #AsString.
>  ].
>
>  mapper for: #AsString customDo: [ :mapping |
>    mapping encoder: [ :anInteger | x asString ].
>    mapping decoder: [ :aString | ... ] ].
>
> But whatever I do ... only numbers are written out ... and yes of course
> I could add additional accessors doing the conversion.

Try

        mapping
                mapProperty: #num
                        getter:  [ :object | (object perform: #num) asString ]
                        setter: [ :object :value |  object perform: #num asMutator with: value asNumber ]  ]

Norbert


Reply | Threaded
Open this post in threaded view
|

Re: neo json and valueSchema for integer attributes ...

Sven Van Caekenberghe-2

On 21 Feb 2014, at 09:18, Norbert Hartl <[hidden email]> wrote:

> Am 21.02.2014 um 07:50 schrieb [hidden email]:
>
>> I have a class with an instance attribute "x" and this one contains an
>> integer value.
>>
>> No when exporting this to json I want to write a string instead of this
>> number to the json string ...
>>
>> neoJsonMapping: mapper
>> mapper for: self do: [ :mapping |
>>   (mapping mapInstVar: #x to: 'x') valueSchema: #AsString.
>> ].
>>
>> mapper for: #AsString customDo: [ :mapping |
>>   mapping encoder: [ :anInteger | x asString ].
>>   mapping decoder: [ :aString | ... ] ].
>>
>> But whatever I do ... only numbers are written out ... and yes of course
>> I could add additional accessors doing the conversion.
>
> Try
>
> mapping
> mapProperty: #num
> getter:  [ :object | (object perform: #num) asString ]
> setter: [ :object :value |  object perform: #num asMutator with: value asNumber ]  ]
>
> Norbert

That is right, Norbert, thanks.

Here is a snippet you can execute in the console:

String streamContents: [ :out |
  (NeoJSONWriter on: out)
    for: Point do: [ :mapping |
      mapping
        mapProperty: #x
        getter: [ :object | object x asString ]
        setter: [ :object :value | object setX: value asNumber setY: object y ].
      mapping
        mapProperty: #y
        getter: [ :object | object y asString ]
        setter: [ :object :value | object setX: object x setY: value asNumber ] ];
  nextPut: 1@2 ].

(NeoJSONReader on: '{"x":"1","y":"2"}' readStream)
  for: Point do: [ :mapping |
    mapping
      mapProperty: #x
      getter: [ :object | object x asString ]
      setter: [ :object :value | object setX: value asNumber setY: object y ].
    mapping
      mapProperty: #y
      getter: [ :object | object y asString ]
      setter: [ :object :value | object setX: object x setY: value asNumber ] ];
   nextAs: Point.

It is a bit forced since Point has no #x: or #y: mutators by design, but you get the idea.

Sven
Reply | Threaded
Open this post in threaded view
|

Re: neo json and valueSchema for integer attributes ...

marten
Hmm, I think that something is definitly missing here.

The same code but instead of using #AsString I use DateAndTime and it
works as expected - and that's what I would expect: use for that
property mapping a valueSchema named "AsString".

It seems to work for all classes, when there is no predefined encoding
available in the running system:Integer has a mathod, DateAndTime not.

Is there any reason why is works that way ?

Marten





Am 21.02.2014 12:07, schrieb Sven Van Caekenberghe:

>
> On 21 Feb 2014, at 09:18, Norbert Hartl <[hidden email]> wrote:
>
>> Am 21.02.2014 um 07:50 schrieb [hidden email]:
>>
>>> I have a class with an instance attribute "x" and this one contains an
>>> integer value.
>>>
>>> No when exporting this to json I want to write a string instead of this
>>> number to the json string ...
>>>
>>> neoJsonMapping: mapper
>>> mapper for: self do: [ :mapping |
>>>   (mapping mapInstVar: #x to: 'x') valueSchema: #AsString.
>>> ].
>>>
>>> mapper for: #AsString customDo: [ :mapping |
>>>   mapping encoder: [ :anInteger | x asString ].
>>>   mapping decoder: [ :aString | ... ] ].
>>>
>>> But whatever I do ... only numbers are written out ... and yes of course
>>> I could add additional accessors doing the conversion.
>>


--
Marten Feldtmann

Reply | Threaded
Open this post in threaded view
|

Re: neo json and valueSchema for integer attributes ...

Sven Van Caekenberghe-2
Hi Marten,

There is indeed something currently not completely implemented: #valueSchema: and #nextAs: were added afterwards for reading (for example a collection of Points), the use of this concept for writing is simply not there. (compare NeoJSONPropertyMapping>>#readObject:from: to NeoJSONPropertyMapping>>#writeObject:on:)

I will think about this a bit first.

On the other hand, I am not so sure your solution is good, because you cannot write a generic #AsString for reading (going from String to ?). So I would suggest one of the other solutions mentioned in this thread.

Thanks for the feedback.

Sven

On 21 Feb 2014, at 13:56, [hidden email] wrote:

> Hmm, I think that something is definitly missing here.
>
> The same code but instead of using #AsString I use DateAndTime and it
> works as expected - and that's what I would expect: use for that
> property mapping a valueSchema named "AsString".
>
> It seems to work for all classes, when there is no predefined encoding
> available in the running system:Integer has a mathod, DateAndTime not.
>
> Is there any reason why is works that way ?
>
> Marten
>
>
>
>
>
> Am 21.02.2014 12:07, schrieb Sven Van Caekenberghe:
>>
>> On 21 Feb 2014, at 09:18, Norbert Hartl <[hidden email]> wrote:
>>
>>> Am 21.02.2014 um 07:50 schrieb [hidden email]:
>>>
>>>> I have a class with an instance attribute "x" and this one contains an
>>>> integer value.
>>>>
>>>> No when exporting this to json I want to write a string instead of this
>>>> number to the json string ...
>>>>
>>>> neoJsonMapping: mapper
>>>> mapper for: self do: [ :mapping |
>>>>  (mapping mapInstVar: #x to: 'x') valueSchema: #AsString.
>>>> ].
>>>>
>>>> mapper for: #AsString customDo: [ :mapping |
>>>>  mapping encoder: [ :anInteger | x asString ].
>>>>  mapping decoder: [ :aString | ... ] ].
>>>>
>>>> But whatever I do ... only numbers are written out ... and yes of course
>>>> I could add additional accessors doing the conversion.
>>>
>
>
> --
> Marten Feldtmann


Reply | Threaded
Open this post in threaded view
|

Re: neo json and valueSchema for integer attributes ...

Sven Van Caekenberghe-2
Hi Marten,

It took a while, but I implemented a new feature that should solve your issue.

You can now do the following:

String streamContents: [ :out |
 (NeoJSONWriter on: out)
   for: #StringAsHex customDo: [ :mapping |
     mapping
       encoder: [ :x | x asByteArray hex asUppercase ];
       decoder: [ :x | (ByteArray readHexFrom: x) asString ] ];
   nextPut: 'Foo bar!' as: #StringAsHex ].

(NeoJSONReader on: '"466F6F2062617221"' readStream)
   for: #StringAsHex customDo: [ :mapping |
     mapping
       encoder: [ :x | x asByteArray hex asUppercase ];
       decoder: [ :x | (ByteArray readHexFrom: x) asString ] ];
   nextAs: #StringAsHex.

As well as:

String streamContents: [ :out |
 (NeoJSONWriter on: out)
   for: Point do: [ :mapping |
     (mapping
       mapProperty: #x
       getter: [ :object | object x ]
       setter: [ :object :value | object setX: value setY: object y ])
       valueSchema: #AsString.
     (mapping
       mapProperty: #y
       getter: [ :object | object y ]
       setter: [ :object :value | object setX: object x setY: value ])
       valueSchema: #AsString ];
   for: #AsString customDo: [ :mapping |
     mapping
       encoder: [ :x | x asString ];
       decoder: [ :x | x asNumber ] ];
   nextPut: 1@2 ].

(NeoJSONReader on: '{"x":"1","y":"2"}' readStream)
   for: Point do: [ :mapping |
     (mapping
       mapProperty: #x
       getter: [ :object | object x ]
       setter: [ :object :value | object setX: value setY: object y ])
       valueSchema: #AsString.
     (mapping
       mapProperty: #y
       getter: [ :object | object y ]
       setter: [ :object :value | object setX: object x setY: value ])
       valueSchema: #AsString ];
   for: #AsString customDo: [ :mapping |
     mapping
       encoder: [ :x | x asString ];
       decoder: [ :x | x asNumber ] ];
   nextAs: Point.

In #bleedingEdge of NeoJSON:

===
Name: Neo-JSON-Core-SvenVanCaekenberghe.26
Author: SvenVanCaekenberghe
Time: 24 March 2014, 12:18:21.026173 pm
UUID: 41d2075d-bca4-4c08-bdf8-ed0c8da9bcf2
Ancestors: Neo-JSON-Core-SvenVanCaekenberghe.25

Added new feature NeoJSONWriter>>#nextPutAs: symmetrical to NeoJSONReader>>#next:as:

More specifically NeoJSONPropertyMapping>>#writeObjectOn: now respects the valueSchema if it exists using NeoJSONStreamingWriter>>#writeKey:value:as: and NeoJSONWriter>>#encodeKey:value:as:

Made both the reader and writer blocks in NeoJSONCustomMapping optional with a fallback to default behavior

Refactoring: added NeoJSONMapping abstract superclass above NeoJSONObjectMapping and NeoJSONCustomMapping to better clarify the design
===
Name: Neo-JSON-Tests-SvenVanCaekenberghe.24
Author: SvenVanCaekenberghe
Time: 24 March 2014, 12:19:53.503067 pm
UUID: 4c7461c1-82ea-4126-8b5c-ef307168120a
Ancestors: Neo-JSON-Tests-SvenVanCaekenberghe.23

Added new feature NeoJSONWriter>>#nextPutAs: symmetrical to NeoJSONReader>>#next:as:

Added 4 unit test to exercise the new options
===

Regards,

Sven

On 21 Feb 2014, at 15:00, Sven Van Caekenberghe <[hidden email]> wrote:

> Hi Marten,
>
> There is indeed something currently not completely implemented: #valueSchema: and #nextAs: were added afterwards for reading (for example a collection of Points), the use of this concept for writing is simply not there. (compare NeoJSONPropertyMapping>>#readObject:from: to NeoJSONPropertyMapping>>#writeObject:on:)
>
> I will think about this a bit first.
>
> On the other hand, I am not so sure your solution is good, because you cannot write a generic #AsString for reading (going from String to ?). So I would suggest one of the other solutions mentioned in this thread.
>
> Thanks for the feedback.
>
> Sven
>
> On 21 Feb 2014, at 13:56, [hidden email] wrote:
>
>> Hmm, I think that something is definitly missing here.
>>
>> The same code but instead of using #AsString I use DateAndTime and it
>> works as expected - and that's what I would expect: use for that
>> property mapping a valueSchema named "AsString".
>>
>> It seems to work for all classes, when there is no predefined encoding
>> available in the running system:Integer has a mathod, DateAndTime not.
>>
>> Is there any reason why is works that way ?
>>
>> Marten
>>
>>
>>
>>
>>
>> Am 21.02.2014 12:07, schrieb Sven Van Caekenberghe:
>>>
>>> On 21 Feb 2014, at 09:18, Norbert Hartl <[hidden email]> wrote:
>>>
>>>> Am 21.02.2014 um 07:50 schrieb [hidden email]:
>>>>
>>>>> I have a class with an instance attribute "x" and this one contains an
>>>>> integer value.
>>>>>
>>>>> No when exporting this to json I want to write a string instead of this
>>>>> number to the json string ...
>>>>>
>>>>> neoJsonMapping: mapper
>>>>> mapper for: self do: [ :mapping |
>>>>> (mapping mapInstVar: #x to: 'x') valueSchema: #AsString.
>>>>> ].
>>>>>
>>>>> mapper for: #AsString customDo: [ :mapping |
>>>>> mapping encoder: [ :anInteger | x asString ].
>>>>> mapping decoder: [ :aString | ... ] ].
>>>>>
>>>>> But whatever I do ... only numbers are written out ... and yes of course
>>>>> I could add additional accessors doing the conversion.
>>>>
>>
>>
>> --
>> Marten Feldtmann
>