Giter Site home page Giter Site logo

json-tools's Introduction

JSON Tools for R6RS Scheme

Collection of JSON utilities.

JSON is lightweight data format and widely used. It is convenient to have a library which can handle it.

The expected JSON structure mapping is like this;

  • JSON map -> vector
  • JSON array -> list
  • JSON boolean -> boolean
  • JSON null -> 'null
  • JSON string -> string
  • JSON number -> number

Above mapping is used json module from Chicken's egg. (except the null mapping).

As an extension, JSON Tools also handles binary type which mapped to Scheme's bytevector. If S-expression JSON representation contains bytevector, it will be mapped to JSON binary.

JSON Tools

JSON Tools provides utilities for JSON. The most of the procedures implicitly converts given S-expression JSON structure to provided JSON types. Followings are the provided types;

  • <json:node> - abstract type for JSON nodes
  • <json:map> - associative array
  • <json:map-entry> - entry of <json:map>
  • <json:array> - array
  • <json:string> - string
  • <json:number> - number
  • <json:boolean> - boolean
  • <json:null> - null
  • <json:binary> - extension for Scheme bytevector

The selectors return following nodeset type;

  • <json:nodeset> - set of nodes defined above.

Constructors

In some case, you may need to use constructors to make sure the node type is indeed you are expecting. For example, there is no way to detect the difference between JSON array and JSON map entry if it's still S-expression.

(json:node o) Converts given o to suitable JSON node. If the o is already a JSON node then it won't re-convert.

(json:map vector) Converts given vector to <json:map> object.

(json:map-entry pair) Converts given pair to <json:map-entry> object.

(json:map-array list) Converts given list to <json:map-array> object.

(json:string string) Converts given string to <json:string> object.

(json:number number) Converts given number to <json:number> object.

(json:boolean boolean) Converts given boolean to <json:boolean> object.

(json:binary bytevector) Converts given bytevector to <json:binary> object.

(json:null null) Converts given null to <json:null> object. The null must be a symbol null.

(json:nodeset nodes ...) Converts given nodes to <json:nodeset> object. The returning value has no duplicated nodes.

(json:as-nodeset o) Converts given o to <json:nodeset> object. If the o is already a JSON nodeset then it won't re-convert.

(json:empty-nodeset ) Returns empty nodeset.

Predicates

(json:node? o) Returns #t if given o is one of the JSON node.

(json:map? o) Returns #t if given o is JSON map.

(json:map-entry? o) Returns #t if given o is JSON map entry.

(json:array? o) Returns #t if given o is JSON array.

(json:string? o) Returns #t if given o is JSON string.

(json:number? o) Returns #t if given o is JSON number.

(json:boolean? o) Returns #t if given o is JSON boolean.

(json:binary? o) Returns #t if given o is JSON binary.

(json:null? o) Returns #t if given o is JSON null.

(json:nodeset? o) Returns #t if given o is JSON nodeset.

(json:empty-nodeset? o) Returns #t if given o is JSON nodeset and doesn't contain any node.

Accessors

(json:node-value node) Retrieves original node value from given node.

(json:map-ref map key) (json:map-ref map key default) Retrieves JSON map value from given JSON map map associated with key. The returning value is JSON node.

When the value does not exist and if the default is specified then it will return default as its value.

When the value does not exist and if the default is not specified then it will raise an error.

(json:map-entry-key map-entry) (json:map-entry-value map-entry) Retrieves JSON map entry's key or value. The returning value is JSON node.

(json:array-elements array) Returns all array elements of array.

(json:array-ref array n) (json:array-ref array n default) Retrieves _n_th JSON array element from given JSON array array. The returning value is JSON node.

When the n is out of range and if the default is specified then it will return default as its value.

When the n is out of range and if the default is not specified then it will raise an error.

(json:nodeset-set nodeset) Returns all nodes of given nodeset.

(json:nodeset->list nodeset) Returns all nodes of given nodeset as S-expression.

Others

(json:map-size map) Returns size of given map.

(json:array-length array) Returns size of given array.

(json:union-nodeset nodeset-list) Returns a nodeset merged from nodeset-list. The returning value doesn't contain duplicate nodes.

Selectors

To be documented

JSON Select

As JSON query, this library (will) provide JSONSelect which is based on jsonselect.org with S-expression selector.

NOTE: original implementation doesn't match with map entries however this consider it as a node so this may return the different result.

Language support

level Selector Description
[X] 1 * Any node
[X] 1 T A node of type T, where T is one string, number, object, array, boolean, binary, or null
[X] 1 T.key A node of type T which is the child of an object and is the value its parents key property
[X] 1 T."complex key" Same as previous, but with property name specified as a JSON string
[X] 1 T:root A node of type T which is the root of the JSON document
[p] 1 T:nth-child(n) A node of type T which is the nth child of an array parent
[X] 1 T:first-child A node of type T which is the first child of an array parent (equivalent to T:nth-child(1))
[X] 1 T U A node of type U with an ancestor of type T
[X] 1 T > U A node of type U with a parent of type T
[X] 1 S1, S2 Any node which matches either selector S1 or S2
[p] 2 T:nth-last-child(n) A node of type T which is the nth child of an array parent counting from the end
[X] 2 T:last-child A node of type T which is the last child of an array parent (equivalent to T:nth-last-child(1))
[X] 2 T:only-child A node of type T which is the only child of an array parent
[X] 2 T:empty A node of type T which is an array or object with no child
[X] 2 T ~ U A node of type U with a sibling of type T
[X] 3 T:expr(E) A node of type T with a value that satisfies the expression E
[x] 3 T:has(S) A node of type T which has a child node satisfying the selector S
[x] 3 T:val(V) A node of type T with a value that is equal to V
[x] 3 T:contains(S) A node of type T with a string value contains the substring S

Types:

The original specification specifies following types;

  • object
  • array
  • number
  • string
  • boolean
  • null

As an extension, JSON Tools can handle following type as well;

  • binary

The binary type described above however can be only searched by type name.

Notations:

  • X: the same as original implementation
  • p: nth-child related only supports number as n
  • x: To make it close to original, comparison happens both node value and map entry value. This is because map entry is a node in this implementation and to retrive sibling properly.

Required SRFI

Following SRFIs are used in JSON tools and select;

  • SRFI-1 - list
  • SRFI-13 - string
  • SRFI-14 - character sets

Supporting implementations

  • Sagittarius Scheme 0.5.0 (or later)
  • Mosh 0.2.7
  • Ypsilon 0.9.6-update3
  • Racket (plt-r6rs)

I believe it's not difficult to port to other R6RS implementations as long as it supports the required SRFI.

NOTE: Mosh contains own porting for (json) however it has different mark as JOSN null and I think it's a design bug since it makes empty array and null indistinguishable.

NOTE: For Racket, ext/packrat.sls for some reason must be installed using --install option.

Your contribution or testing is always welcome!

json-tools's People

Contributors

ktakashi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

json-tools's Issues

Re-structure the external library

Currently, (json) needs to be provided by implementations. However, it's rather inconvenient. So add (text json) or a similar library to provider JSON read/write.

NOTE: it's better not to use (text json) for Sagittarius so could be (text json io) or so.

Crashes when reading emojis

Hello Takashi!

\uNNNN escapes in JSON are in UTF-16, but interpret-string-unicode-escape passes them to integer->char. A demonstration:

> (string->utf16 "๐Ÿ˜บ")
#vu8(#xD8 #x3D #xDE #x3A)

In Node this gives back the emoji:

> "\uD83D\uDE3A"
'๐Ÿ˜บ'

And with json-tools it crashes:

> (print-radix 16)
> (json-read (open-string-input-port "\"\\uD83D\\uDE3A\""))
Exception in integer->char: #xD83D is not a valid unicode scalar value
Type (debug) to enter the debugger.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.