From 5cf17ea4420d45027453f45b556601c8851faac3 Mon Sep 17 00:00:00 2001 From: Yikai Zhao Date: Sun, 31 Dec 2023 20:21:48 +0800 Subject: [PATCH] add native-json-parser module for comparison --- .dir-locals.el | 4 + Cargo.lock | 168 ++++++++++++++++++++++++++++++++- Cargo.toml | 7 ++ examples/native-json-parser.rs | 53 +++++++++++ 4 files changed, 227 insertions(+), 5 deletions(-) create mode 100644 .dir-locals.el create mode 100644 examples/native-json-parser.rs diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000..d247aa2 --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,4 @@ +;;; Directory Local Variables -*- no-byte-compile: t; -*- +;;; For more information see (info "(emacs) Directory Variables") + +((rust-mode . ((lsp-rust-analyzer-proc-macro-enable . nil)))) diff --git a/Cargo.lock b/Cargo.lock index 24f0004..3b25200 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "anyhow" -version = "1.0.77" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9d19de80eff169429ac1e9f48fffb163916b448a44e8e046186232046d9e1f9" +checksum = "ca87830a3e3fb156dc96cfbd31cb620265dd053be734723f22b760d6cc3c3051" [[package]] name = "bitflags" @@ -26,17 +26,96 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "ctor" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "emacs" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6797a940189d353de79bec32abe717aeeecd79a08236e84404c888354e040665" +dependencies = [ + "anyhow", + "ctor", + "emacs-macros", + "emacs_module", + "once_cell", + "rustc_version", + "thiserror", +] + [[package]] name = "emacs-lsp-booster" version = "0.1.0" dependencies = [ "anyhow", + "emacs", "lazy_static", "serde_json", "smallvec", "tempfile", ] +[[package]] +name = "emacs-macros" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69656fdfe7c2608b87164964db848b5c3795de7302e3130cce7131552c6be161" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "emacs_module" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3067bc974045ed2c6db333bd4fc30d3bdaafa6421a9a889fa7b2826b6f7f2fa" + [[package]] name = "errno" version = "0.3.8" @@ -53,6 +132,18 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "itoa" version = "1.0.10" @@ -77,11 +168,17 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + [[package]] name = "proc-macro2" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" +checksum = "a293318316cf6478ec1ad2a21c49390a8d5b5eae9fab736467d93fbc0edc29c5" dependencies = [ "unicode-ident", ] @@ -104,6 +201,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.28" @@ -123,6 +229,21 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + [[package]] name = "serde" version = "1.0.193" @@ -140,7 +261,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.43", ] [[package]] @@ -160,6 +281,23 @@ version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.43" @@ -184,6 +322,26 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "thiserror" +version = "1.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2cd5904763bad08ad5513ddbb12cf2ae273ca53fa9f68e843e236ec6dfccc09" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcf4a824cce0aeacd6f38ae6f24234c8e80d68632338ebaa1443b5df9e29e19" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.43", +] + [[package]] name = "unicode-ident" version = "1.0.12" diff --git a/Cargo.toml b/Cargo.toml index efdab9a..af48b55 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,10 @@ anyhow = "1.0" lazy_static = "1.4" smallvec = "1.11" tempfile = "3.9" + +[[example]] +name = "native-json-parser" +crate-type = ["cdylib"] + +[dev-dependencies] +emacs = "0.18" diff --git a/examples/native-json-parser.rs b/examples/native-json-parser.rs new file mode 100644 index 0000000..188e268 --- /dev/null +++ b/examples/native-json-parser.rs @@ -0,0 +1,53 @@ +use emacs::{defun, Env, Result, Value, IntoLisp}; +use serde_json as json; + +// Emacs won't load the module without this. +emacs::plugin_is_GPL_compatible!(); + +// Register the initialization hook that Emacs will call when it loads the module. +#[emacs::module] +fn init(env: &Env) -> Result> { + env.message("Done loading!") +} + +fn json_to_lisp<'a>(env: &'a Env, val: &json::Value) -> Result> { + match val { + &json::Value::Null | &json::Value::Bool(false) => + ().into_lisp(env), + &json::Value::Bool(true) => + true.into_lisp(env), + &json::Value::Number(ref num) => + if num.is_f64() { + num.as_f64().unwrap().into_lisp(env) + } else if num.is_i64() { + num.as_i64().unwrap().into_lisp(env) + } else { + num.as_u64().unwrap().into_lisp(env) + }, + &json::Value::String(ref s) => + s.into_lisp(env), + &json::Value::Array(ref arr) => { + let vals = arr.iter().map(|x| json_to_lisp(env, x)).collect::>>()?; + env.vector(&vals) + }, + &json::Value::Object(ref map) => { + let mut vals: Vec> = Vec::new(); + for (k, v) in map { + vals.push(env.intern(&format!(":{}", k))?); + vals.push(json_to_lisp(env, v)?); + } + env.list(&vals) + }, + } +} + + +#[defun] +fn parse(env: &Env, s: String) -> Result> { + let start = std::time::Instant::now(); + let json_val = json::from_str(&s)?; + let end = std::time::Instant::now(); + env.message(format!("json parsing took {:?}", end.duration_since(start)))?; + + json_to_lisp(env, &json_val) +}