Chris Muller uploaded a new version of JSON to project The Trunk: http://source.squeak.org/trunk/JSON-cmm.62.mcz
==================== Summary ====================
Name: JSON-cmm.62 Author: cmm Time: 24 February 2024, 1:21:44.121899 am UUID: 8a043f53-c158-4a2a-b29a-0fb20d53d6a9 Ancestors: JSON-cmm.61
- Prefix json extension methods to indicate they're intended for Json outputs. - Better comments, implementations and tests for new path accessing functions. - Fix and a test an Array of Associations to be a Json object.
=============== Diff against JSON-cmm.61 ===============
Item was removed: - ----- Method: Collection>>atPath: (in category '*json') ----- - atPath: anArray - "Assume I'm a set of nested HashedCollections and/or SequenceableCollections. Answer the object at the path of indices and/or keys identified in anArray." - ^ self - atPath: anArray - ifLost: [ : last | self error: 'path lost after' , last asString ]!
Item was removed: - ----- Method: Collection>>atPath:ifLost: (in category '*json') ----- - atPath: anArray ifLost: aBlock - "Assume I'm a set of nested HashedCollections and/or SequenceableCollections. Answer the object at the path of indices and/or keys identified in anArray. If the full path specified by anArray isn't present, cull aBlock with the last element present along the path." - | last | - ^ (self - path: anArray - do: [ : elem : node | last := node ]) - ifNil: [ aBlock cull: last ] - ifNotNil: [ last ]!
Item was added: + ----- Method: Collection>>jsonAtPath: (in category '*json') ----- + jsonAtPath: anArray + "Assume I'm Json output. Answer the object at the path of indices and/or keys identified in anArray. If the full path specified by anArray isn't found, signal an Error." + ^ self + jsonAtPath: anArray + ifLost: [ : last | self error: 'path lost after index ' , last asString ]!
Item was added: + ----- Method: Collection>>jsonAtPath:ifLost: (in category '*json') ----- + jsonAtPath: anArray ifLost: aBlock + "Assume I'm a Json object. Answer the sub-object at the path of indices and/or keys identified in anArray. If the full path specified by anArray isn't present, stop, and answer the value of aBlock culled with the index of the element within anArray that isn't found." + | last index | + index := 0. + ^ (self + jsonPath: anArray + do: + [ : elem : node | index := index + 1. + last := node ]) + ifNil: [ aBlock cull: index+1] + ifNotNil: [ last ]!
Item was added: + ----- Method: Collection>>jsonPath:do: (in category '*json') ----- + jsonPath: anArray do: aBlock + "Assume I'm a Json output. Value aBlock with each object along the path of keys and/or indices identified in anArray. If a path element isn't found, stop, and return nil, otherwise, return self." + | current | + current := self. + anArray do: + [ : eachKey | "Json doesn't have Characters, allow pathing into Json objects only." + (current isArray or: [ current isDictionary ]) + ifTrue: + [ current + at: eachKey + ifPresent: + [ : eachValue | aBlock + value: eachKey + value: eachValue. + current := eachValue ] + ifAbsent: [ ^ nil ] ] + ifFalse: [ ^ nil ] ]. + ^ self!
Item was added: + ----- Method: Collection>>jsonWriteListOn: (in category '*json') ----- + jsonWriteListOn: aStream + "By default, use array braces " + aStream nextPut: $[. + + self do: [:each | + each jsonWriteOn: aStream + ] separatedBy: [ aStream nextPut: $, ]. + + aStream nextPut: $]!
Item was added: + ----- Method: Collection>>jsonWriteObjectOn: (in category '*json') ----- + jsonWriteObjectOn: aStream + + | needComma | + needComma := false. + aStream nextPut: ${. + self associationsDo: [ :assoc | + needComma + ifTrue: [ aStream nextPut: $, ] + ifFalse: [ needComma := true ]. + assoc key jsonWriteOn: aStream. + aStream nextPut: $:. + assoc value jsonWriteOn: aStream ]. + aStream nextPut: $}.!
Item was changed: ----- Method: Collection>>jsonWriteOn: (in category '*json') ----- jsonWriteOn: aStream + (self notEmpty and: [self anyOne isVariableBinding]) + ifTrue: [ self jsonWriteObjectOn: aStream ] + ifFalse: [ self jsonWriteListOn: aStream ]! - "By default, use array braces " - aStream nextPut: $[. - - self do: [:each | - each jsonWriteOn: aStream - ] separatedBy: [ aStream nextPut: $, ]. - - aStream nextPut: $]!
Item was removed: - ----- Method: Collection>>path:do: (in category '*json') ----- - path: anArray do: aBlock - "Assume I'm a set of nested HashedCollections and/or SequenceableCollections. Value aBlock with each object along the path of indices and/or keys identified in anArray. If a path element isn't found, stop, and return nil, otherwise, return self." - anArray - inject: self - into: - [ : dictOrArray : pathElem | dictOrArray - at: pathElem - ifPresent: [ : node | aBlock value: pathElem value: node ] - ifAbsent: [ ^ nil ] ]. - ^ self!
Item was added: + ----- Method: JsonTests>>testNonDictionaryJsonObject (in category 'tests') ----- + testNonDictionaryJsonObject + self + render: {'a' -> 1. 'b' -> 2} + equals: '{"a":1,"b":2}'!
Item was added: + ----- Method: JsonTests>>testPathAccess (in category 'tests') ----- + testPathAccess + | json lost | json := Json readFrom: '{ + "smalltalk" : { + "platformName":"unix", + "classes" : [ + { "id" : 3557, "name":"Integer" }, + { "id" : 3558, "name":"Float" }, + { "id" : 3559, "name":"Fraction" } + ] + } + }' readStream. + self assert: (json jsonAtPath: #('smalltalk' 'platformName')) = 'unix'. + "With array in the path." + self assert: (json jsonAtPath: #('smalltalk' 'classes' 1 'id')) = 3557. + self assert: (json jsonAtPath: #('smalltalk' 'classes' 2 'name')) = 'Float'. + "No pathing into byte objects, only Json objects." + self + should: [json jsonAtPath: #('smalltalk' 'classes' 2 'name' "Not allowed --->" 1)] + raise: Error. + "Key not found." + self + should: [ json jsonAtPath: #('smalltalk' 'wordSize') ] + raise: Error. + lost := false. + json + jsonAtPath: #('smalltalk' 'wordSize') + ifLost: [ : lostPosition | lost := true. self assert: lostPosition = 2 ]. + self assert: lost. + "Index OOB" + self + should: [ json jsonAtPath: #('smalltalk' 'classes' 99) ] + raise: Error. + lost := false. + json + jsonAtPath: #('smalltalk' 'classes' 99) + ifLost: [ : lostPosition | lost := true. self assert: lostPosition = 3 ]. + self assert: lost!
packages@lists.squeakfoundation.org