Update jupyter--encode for new Emacs JSON API.

The old Emacs JSON API (for versions <= 27.2 at time of commit) was
structured in a way that replacing the symbol-function of json-encode
worked to get custom encoding for certain object types used by
emacs-jupyter. In the later API, the function json--print plays the
recursive role of json-encode. The code here works in either version,
and is simplified so that future updates to the API are easier to
accomodate.
This commit is contained in:
Yuri D. Lensky 2021-03-29 18:42:58 -07:00 committed by Nathaniel Nicandro
parent 3f54271e40
commit 9285480715

View file

@ -152,38 +152,34 @@ If PART is a list whose first element is the symbol,
is non-nil. If it is nil, then set the list's second element to is non-nil. If it is nil, then set the list's second element to
the result of calling `jupyter--encode' on the third element and the result of calling `jupyter--encode' on the third element and
return the result." return the result."
(if (eq (car-safe part) 'message-part) (let ((json-recursive-encoder-sym (if (fboundp 'json--print) 'json--print 'json-encode)))
(cl-destructuring-bind (_ encoded-rep decoded-rep) part (unwind-protect
(or encoded-rep (setf (nth 1 part) (jupyter--encode decoded-rep)))) (progn
(cl-letf (((symbol-function 'json-encode) (add-function :around (symbol-function json-recursive-encoder-sym) #'jupyter--json-encode-preproc)
(lambda (object) (encode-coding-string
(cond ((memq object (list t json-null json-false)) (cond
(json-encode-keyword object)) ((stringp part) part)
((stringp object) (json-encode-string object)) (t (json-encode part)))
((keywordp object) 'utf-8 t))
;; Handle `jupyter-message-type' (remove-function (symbol-function json-recursive-encoder-sym) #'jupyter--json-encode-preproc))))
(let ((msg-type (plist-get jupyter-message-types object)))
(json-encode-string (defun jupyter--json-encode-preproc (old-json-recursive-encoder object)
(or msg-type (substring (symbol-name object) 1))))) (let (msg-type)
((symbolp object) (json-encode-string (symbol-name object))) (cl-flet ((json-encode
((numberp object) (json-encode-number object)) (object)
((arrayp object) (json-encode-array object)) (jupyter--json-encode-preproc old-json-recursive-encoder object)))
((hash-table-p object) (json-encode-hash-table object)) (cond
((listp object) ((eq (car-safe object) 'message-part)
(cond (cl-destructuring-bind (_ encoded-rep decoded-rep) object
((eq (car object) 'message-part) (or encoded-rep (setf (nth 1 object) (json-encode decoded-rep)))))
(jupyter--encode object)) ((and (keywordp object)
;; Turn time objects into ISO 8601 time strings (setf msg-type (plist-get jupyter-message-types object)))
((and (= (length object) 4) (json-encode msg-type))
(cl-every #'integerp object)) ((and (listp object)
(jupyter-encode-time object)) (= (length object) 4)
(t (json-encode-list object)))) (cl-every #'integerp object))
(t (signal 'json-error (list object))))))) (jupyter-encode-time object))
(encode-coding-string (t (funcall old-json-recursive-encoder object))))))
(cond
((stringp part) part)
(t (json-encode part)))
'utf-8 t))))
(defun jupyter--decode (part) (defun jupyter--decode (part)
"Decode a message PART. "Decode a message PART.