> On 14 Mar 2016, at 09:33, p...@highoctane.be wrote: > > JSON is so pervasive that a base Pharo image should have things named after > it. > STON is supercool but there is no JSON name in it, that's an issue for me.
I added a class facade STONJSON to make this more explicit (with tests): === Name: STON-Core-SvenVanCaekenberghe.70 Author: SvenVanCaekenberghe Time: 15 March 2016, 5:07:59.236863 pm UUID: c990d2ab-a407-4935-b489-c55139fdd665 Ancestors: STON-Core-SvenVanCaekenberghe.69 Improve class comments Add STONJSON facade class to make it more explicit that you can use STON for simple JSON parsing and generation Add STONJSONTests to test JSON compatibility === Name: STON-Tests-SvenVanCaekenberghe.62 Author: SvenVanCaekenberghe Time: 15 March 2016, 5:08:19.634401 pm UUID: 097090ae-a1ca-4401-86b0-07d7d446a9dc Ancestors: STON-Tests-SvenVanCaekenberghe.61 Improve class comments Add STONJSON facade class to make it more explicit that you can use STON for simple JSON parsing and generation Add STONJSONTests to test JSON compatibility === This is the STON class comment === STON implements serialization and materialization using the Smalltalk Object Notation format. I am a class side facade offering a high level API to write and read objects using STON. U s a g e Basic operations #toString: #fromString: STON toString: DisplayScreen boundingBox. STON fromString: 'Rectangle{#origin:Point[0,0],#corner:Point[1920,1030]}'. STON toString: { DateAndTime now. Float pi. 1 to: 10 by: 2. 3 days }. STON fromString: '[DateAndTime[''2016-03-15T13:57:59.462422+01:00''],3.141592653589793,Interval{#start:1,#stop:10,#step:2},Duration{#nanos:0,#seconds:259200}]' You can also read from or write to streams #fromStream: #put:onStream: There is also the option to do pretty printing (indenting, multi line output) #toStringPretty: #put:onStreamPretty: STON is more or less a superset of JSON and is backwards compatible with JSON while parsing, and can be compatible with it while writing. The important differences (and the whole reason why STON exists in the first place) are - class information (except for lists (Array) and maps (Dictionary)) - proper handling of shared and circular references - more Smalltalk like syntax (Symbols with #, single qouted Strings, nil instead of null) - more defined special types (Date, Time, DataAndTime, ByteArray, Point) Parsing JSON is done using #fromString: or #fromStream: with the results being composed of Arrays and Dictionaries. Writing objects as JSON is done using: #toJsonString[Pretty]: #put:asJsonOnStream[Pretty]: Note that you can only write Arrays and Dictionaries ! For a much more sophisticated JSON parser/writer implementation, have a look at NeoJSON. Like JSON, STON does not allow for comments. However, a preprocessor option can skip C style comments before parsing. I also define some contants used in the implementation: the class used as list, map and association, as well as the optional class name key (used when reading objects using an unknown class). I m p l e m e n t a t i o n The 2 key methods are #stonOn: #fromSton: which work together with STONWriter and STONReader; read their class comments for all configuration options (you can use the #reader and #writer methods to avoid referring to these classes directly). Several methods are used to support and/or control the implementation #stonName - defines the external name for a class #stonAllInstVarNames - defines which instance variable to write #stonContainSubObjects - shortcut looking into objects for subobjects #stonShouldWriteNilInstVars - option to skip writing nil valued instance variables S y n t a x value primitive-value object-value reference nil primitive-value number true false symbol string object-value object map list object classname map classname list reference @ int-index-previous-object-value map {} { members } members pair pair , members pair string : value symbol : value number : value list [] [ elements ] elements value value , elements string '' ' chars ' chars char char chars char any-printable-ASCII-character- except-'-"-or-\ \' \" \\ \/ \b \f \n \r \t \u four-hex-digits symbol # chars-limited # ' chars ' chars-limited char-limited char-limited chars-limited char-limited a-z A-Z 0-9 - _ . / classname uppercase-alpha-char alphanumeric-char number int int frac int exp int frac exp int digit digit1-9 digits - digit - digit1-9 digits frac . digits exp e digits digits digit digit digits e e e+ e- E E+ E- === And this is the STONJSON class comment === I am STONJSON, a class side facade to use STON as a simple JSON parser/writer. STON is more or less a superset of JSON and is backwards compatible with JSON while parsing, and can be compatible with it while writing. The important differences (and the whole reason why STON exists in the first place) are - class information (except for lists (Array) and maps (Dictionary)) - proper handling of shared and circular references - more Smalltalk like syntax (Symbols with #, single qouted Strings, nil instead of null) - more defined special types (Date, Time, DataAndTime, ByteArray, Point) Parsing JSON is done using #fromString: #fromStream: with the results being composed of Arrays and Dictionaries. Writing objects as JSON is done using #toString[Pretty]: #put:onStream[Pretty]: Note that you can only write Arrays and Dictionaries ! Shared and circular references will be noted and signalled using an exception. E x a m p l e s STONJSON toString: { 1. -1. Float pi. true. 'JSON' }. STONJSON fromString: '[1,-1,3.141592653589793,true,"JSON"]'. STONJSON toStringPretty: { #foo->1. #bar->2 } asDictionary. STONJSON fromString: '{"foo":1,"bar":2,"sub":{"a":true,"b":false},"flags":[1,8,32]}'. For a much more sophisticated JSON parser/writer implementation, have a look at NeoJSON. === > What would be a good way to do that? I wonder. Maybe we need some kind of central registry, maybe. Because the main goal would be to able to switch one implementation for another, but that would only work if their interfaces and behaviour match. Now, different implementations might share some API, but certainly will differ in other places, because they each offer different features. Sven