emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: New jrpc.el JSONRPC library


From: João Távora
Subject: Re: New jrpc.el JSONRPC library
Date: Tue, 29 May 2018 02:08:48 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

Eli Zaretskii <address@hidden> writes:

>> > Thanks, this sounds like a good addition.  Does it (or can it) work
>> > with the built-in JSON support we have on the master branch?
>> Not yet. I didn't know about that, but indeed it has to be on the
>> roadmap, so I'll start looking into it.
> Thanks, I think this is an important development direction.  We added
> JSON implementation in C for a good reason, so we'd like to have other
> core package be able to use that.

After having a look at json.c, I confirmed that it isn't designed to
work with property lists (plists). Is this for a very good technical
reason or just a personal preference for alists and hash-tables?

If json.c provided plist support it could more easily become a drop-in
replacement for json.el in the future. In my opinion, as I wrote
elsewhere, it would also assist in the destructuring of JSON objects in
elisp with cl-compatible lambda lists (cl-defmethod,
cl-destructuring-bind, etc..)

It appears to be very easy to add plist support to json-parse-string in
json.c. See the attached patch. If there are no great objections I can
add support for plist support to json-serialize as well. In this case it
would make sense to respect json.el's variable json-object-type.

Thanks,
João

diff --git a/src/json.c b/src/json.c
index b046d34f66..710d1cf888 100644
--- a/src/json.c
+++ b/src/json.c
@@ -605,6 +605,7 @@ OBJECT.  */)
 enum json_object_type {
   json_object_hashtable,
   json_object_alist,
+  json_object_plist
 };
 
 /* Convert a JSON object to a Lisp object.  */
@@ -692,6 +693,25 @@ json_to_lisp (json_t *json, enum json_object_type 
object_type)
               result = Fnreverse (result);
               break;
             }
+          case json_object_plist:
+            {
+              result = Qnil;
+              const char *key_str;
+              json_t *value;
+              json_object_foreach (json, key_str, value)
+                {
+                  /* No idea if using AUTO_STRING and Fconcat for
+                     making keywords is idiomatic, but seems to work
+                     nicely */
+                  AUTO_STRING (colon, ":");
+                  Lisp_Object key =
+                    Fintern (CALLN (Fconcat, colon, json_build_string 
(key_str))
+                             , Qnil);
+                  result = Fcons (json_to_lisp (value, object_type), result);
+                  result = Fcons (key, result);
+                }
+              break;
+            }
           default:
             /* Can't get here.  */
             emacs_abort ();
@@ -721,8 +741,10 @@ json_parse_object_type (ptrdiff_t nargs, Lisp_Object *args)
           return json_object_hashtable;
         else if (EQ (value, Qalist))
           return json_object_alist;
+        else if (EQ (value, Qplist))
+          return json_object_plist;
         else
-          wrong_choice (list2 (Qhash_table, Qalist), value);
+          wrong_choice (list3 (Qhash_table, Qalist, Qplist), value);
       }
     default:
       wrong_type_argument (Qplistp, Flist (nargs, args));
@@ -731,16 +753,17 @@ json_parse_object_type (ptrdiff_t nargs, Lisp_Object 
*args)
 
 DEFUN ("json-parse-string", Fjson_parse_string, Sjson_parse_string, 1, MANY,
        NULL,
-       doc: /* Parse the JSON STRING into a Lisp object.
-This is essentially the reverse operation of `json-serialize', which
-see.  The returned object will be a vector, hashtable, or alist.  Its
+       doc: /* Parse the JSON STRING into a Lisp object.  This is
+essentially the reverse operation of `json-serialize', which see.  The
+returned object will be a vector, hashtable, alist, or plist.  Its
 elements will be `:null', `:false', t, numbers, strings, or further
-vectors, hashtables, and alists.  If there are duplicate keys in an
-object, all but the last one are ignored.  If STRING doesn't contain a
-valid JSON object, an error of type `json-parse-error' is signaled.
-The keyword argument `:object-type' specifies which Lisp type is used
-to represent objects; it can be `hash-table' or `alist'.
-usage: (json-parse-string STRING &key (OBJECT-TYPE \\='hash-table))  */)
+vectors, hashtables, alists, or plists.  If there are duplicate keys
+in an object, all but the last one are ignored.  If STRING doesn't
+contain a valid JSON object, an error of type `json-parse-error' is
+signaled.  The keyword argument `:object-type' specifies which Lisp
+type is used to represent objects; it can be `hash-table', `alist' or
+`plist'.
+usage: (json-parse-string STRING &key (OBJECT-TYPE \\='hash-table)) */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
   ptrdiff_t count = SPECPDL_INDEX ();
@@ -912,6 +935,7 @@ syms_of_json (void)
 
   DEFSYM (QCobject_type, ":object-type");
   DEFSYM (Qalist, "alist");
+  DEFSYM (Qplist, "plist")
 
   defsubr (&Sjson_serialize);
   defsubr (&Sjson_insert);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]