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 |
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 |
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 |
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 |
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 |
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 > |
Free forum by Nabble | Edit this page |