[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/compat 476aa10 62/99: Add json-* functions from 27.1
From: |
ELPA Syncer |
Subject: |
[elpa] externals/compat 476aa10 62/99: Add json-* functions from 27.1 |
Date: |
Sun, 17 Oct 2021 05:57:57 -0400 (EDT) |
branch: externals/compat
commit 476aa10a63f609c66a9f22dc352a0fbfe3e93670
Author: Philip Kaludercic <philipk@posteo.net>
Commit: Philip Kaludercic <philipk@posteo.net>
Add json-* functions from 27.1
---
compat-27.1.el | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
compat-tests.el | 34 ++++++++++++++++
2 files changed, 155 insertions(+)
diff --git a/compat-27.1.el b/compat-27.1.el
index 59c5c1d..46847bd 100644
--- a/compat-27.1.el
+++ b/compat-27.1.el
@@ -105,6 +105,127 @@ Letter-case is significant, but text properties are
ignored."
(when (and redisplay recenter-redisplay)
(redisplay)))
+;;;; Defined in json.c
+
+(declare-function json-encode-string "json" (object))
+(declare-function json-read-from-string "json" (string))
+(declare-function json-read "json" ())
+(defvar json-object-type)
+(defvar json-array-type)
+(defvar json-false)
+(defvar json-null)
+
+(compat-defun json-serialize (object &rest args)
+ "Return the JSON representation of OBJECT as a string.
+
+OBJECT must be t, a number, string, vector, hashtable, alist, plist,
+or the Lisp equivalents to the JSON null and false values, and its
+elements must recursively consist of the same kinds of values. t will
+be converted to the JSON true value. Vectors will be converted to
+JSON arrays, whereas hashtables, alists and plists are converted to
+JSON objects. Hashtable keys must be strings without embedded null
+characters and must be unique within each object. Alist and plist
+keys must be symbols; if a key is duplicate, the first instance is
+used.
+
+The Lisp equivalents to the JSON null and false values are
+configurable in the arguments ARGS, a list of keyword/argument pairs:
+
+The keyword argument `:null-object' specifies which object to use
+to represent a JSON null value. It defaults to `:null'.
+
+The keyword argument `:false-object' specifies which object to use to
+represent a JSON false value. It defaults to `:false'.
+
+In you specify the same value for `:null-object' and `:false-object',
+a potentially ambiguous situation, the JSON output will not contain
+any JSON false values."
+ (require 'json)
+ (let ((json-false (or (plist-get args :false-object) :false))
+ (json-null (or (plist-get args :null-object) :null)))
+ (json-encode-string object)))
+
+(compat-defun json-insert (object &rest args)
+ "Insert the JSON representation of OBJECT before point.
+This is the same as (insert (json-serialize OBJECT)), but potentially
+faster. See the function `json-serialize' for allowed values of
+OBJECT."
+ (insert (apply #'json-serialize object args)))
+
+(compat-defun json-parse-string (string &rest args)
+ "Parse the JSON STRING into a Lisp object.
+This is essentially the reverse operation of `json-serialize', which
+see. The returned object will be the JSON null value, the JSON false
+value, t, a number, a string, a vector, a list, a hashtable, an alist,
+or a plist. Its elements will be further objects of these types. If
+there are duplicate keys in an object, all but the last one are
+ignored. If STRING doesn't contain a valid JSON object, this function
+signals an error of type `json-parse-error'.
+
+The arguments ARGS are a list of keyword/argument pairs:
+
+The keyword argument `:object-type' specifies which Lisp type is used
+to represent objects; it can be `hash-table', `alist' or `plist'. It
+defaults to `hash-table'.
+
+The keyword argument `:array-type' specifies which Lisp type is used
+to represent arrays; it can be `array' (the default) or `list'.
+
+The keyword argument `:null-object' specifies which object to use
+to represent a JSON null value. It defaults to `:null'.
+
+The keyword argument `:false-object' specifies which object to use to
+represent a JSON false value. It defaults to `:false'."
+ (require 'json)
+ (condition-case err
+ (let ((json-object-type (or (plist-get args :object-type) 'hash-table))
+ (json-array-type (or (plist-get args :array-type) 'vector))
+ (json-false (or (plist-get args :false-object) :false))
+ (json-null (or (plist-get args :null-object) :null)))
+ (when (eq json-array-type 'array)
+ (setq json-array-type 'vector))
+ (json-read-from-string string))
+ (json-error (signal 'json-parse-error err))))
+
+(compat-defun json-parse-buffer (&rest args)
+ "Read JSON object from current buffer starting at point.
+Move point after the end of the object if parsing was successful.
+On error, don't move point.
+
+The returned object will be a vector, list, hashtable, alist, or
+plist. Its elements will be the JSON null value, the JSON false
+value, t, numbers, strings, or further vectors, lists, hashtables,
+alists, or plists. If there are duplicate keys in an object, all
+but the last one are ignored.
+
+If the current buffer doesn't contain a valid JSON object, the
+function signals an error of type `json-parse-error'.
+
+The arguments ARGS are a list of keyword/argument pairs:
+
+The keyword argument `:object-type' specifies which Lisp type is used
+to represent objects; it can be `hash-table', `alist' or `plist'. It
+defaults to `hash-table'.
+
+The keyword argument `:array-type' specifies which Lisp type is used
+to represent arrays; it can be `array' (the default) or `list'.
+
+The keyword argument `:null-object' specifies which object to use
+to represent a JSON null value. It defaults to `:null'.
+
+The keyword argument `:false-object' specifies which object to use to
+represent a JSON false value. It defaults to `:false'."
+ (require 'json)
+ (condition-case err
+ (let ((json-object-type (or (plist-get args :object-type) 'hash-table))
+ (json-array-type (or (plist-get args :array-type) 'vector))
+ (json-false (or (plist-get args :false-object) :false))
+ (json-null (or (plist-get args :null-object) :null)))
+ (when (eq json-array-type 'array)
+ (setq json-array-type 'vector))
+ (json-read))
+ (json-error (signal 'json-parse-buffer err))))
+
;;;; Defined in subr.el
(compat-advise setq-local (&rest pairs)
diff --git a/compat-tests.el b/compat-tests.el
index d52ff93..213c9a4 100644
--- a/compat-tests.el
+++ b/compat-tests.el
@@ -1262,5 +1262,39 @@ the compatibility function."
(should-not
(compat--and-let* (((= 5 6))) t)))
+(ert-deftest compat-json-parse-string ()
+ "Check if `compat--json-parse-string' was implemented properly."
+ (compat-test json-parse-string
+ (compat--should 0 "0")
+ (compat--should 1 "1")
+ (compat--should 0.5 "0.5")
+ (compat--should [1 2 3] "[1,2,3]")
+ (compat--should ["a" 2 3] "[\"a\",2,3]")
+ (compat--should [["a" 2] 3] "[[\"a\",2],3]")
+ (compat--should '(("a" 2) 3) "[[\"a\",2],3]" :array-type 'list)
+ (compat--should 'foo "null" :null-object 'foo)
+ (compat--should ["false" t] "[false, true]" :false-object "false"))
+ (let ((input "{\"key\":[\"abc\", 2], \"yek\": null}"))
+ (let ((obj (compat--json-parse-string input)))
+ (should (equal (gethash "key" obj) ["abc" 2]))
+ (should (equal (gethash "yek" obj) :null)))
+ (let ((obj (compat--json-parse-string input :object-type 'alist)))
+ (should (equal (cdr (assq 'key obj)) ["abc" 2]))
+ (should (equal (cdr (assq 'yek obj)) :null)))
+ (let ((obj (compat--json-parse-string input :object-type 'plist)))
+ (should (equal (plist-get obj :key) ["abc" 2]))
+ (should (equal (plist-get obj :yek) :null)))
+ (when (fboundp 'json-parse-string)
+ (let ((obj (json-parse-string input :object-type 'alist)))
+ (should (equal (cdr (assq 'key obj)) ["abc" 2]))
+ (should (equal (cdr (assq 'yek obj)) :null)))
+ (let ((obj (json-parse-string input :object-type 'plist)))
+ (should (equal (plist-get obj :key) ["abc" 2]))
+ (should (equal (plist-get obj :yek) :null)))
+ (let ((obj (json-parse-string input)))
+ (should (equal (gethash "key" obj) ["abc" 2]))
+ (should (equal (gethash "yek" obj) :null))))))
+
+
(provide 'compat-tests)
;;; compat-tests.el ends here
- [elpa] externals/compat 8f64282 49/99: Use compatibility functions in string-trim definition, (continued)
- [elpa] externals/compat 8f64282 49/99: Use compatibility functions in string-trim definition, ELPA Syncer, 2021/10/17
- [elpa] externals/compat e6b5f08 53/99: Load all compatibility code unconditionally, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 021ffd1 59/99: Handle legacy bytecode argument lists, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 956db9b 60/99: Improve handling of conditional compatibility definitions, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 9be46b0 16/99: Add check for Emacs 28 to compat-tests.el, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 10ef8f4 36/99: Declare string-trim-left and directory-name-p, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 9df8e0c 38/99: Add GitHub action file for CI, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 4364563 43/99: Use unprefixed symbols where possible, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 658db90 47/99: Simplify and-let* implementation, ELPA Syncer, 2021/10/17
- [elpa] externals/compat ad92d70 61/99: Add decoded-time-* functions from 27.1, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 476aa10 62/99: Add json-* functions from 27.1,
ELPA Syncer <=
- [elpa] externals/compat a0ea4ae 65/99: Call alist-get-full-elisp from alist-get-handle-testfn, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 4513631 70/99: Fix compat-func-arity advice handling, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 09bf8d8 75/99: Declare nadvice functions for compat-func-arity, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 80ab781 77/99: Use advice.el for advising functions previously to Emacs 24.4, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 20afc89 78/99: Add :cond checks to json-* functions in compat-27.1, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 72c0781 81/99: Mention Chris Wellons' article on lambdas and byte compilation, ELPA Syncer, 2021/10/17
- [elpa] externals/compat ee068f0 82/99: Revert back to manual advising, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 7bef68b 84/99: Mark regexp-opt as part of regexp-opt.el, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 7619f21 89/99: Display version number of manual advice docstring, ELPA Syncer, 2021/10/17
- [elpa] externals/compat 7245918 96/99: Fix handling of file-missing in require advice, ELPA Syncer, 2021/10/17