Skip to content

Commit

Permalink
add native-json-parser module for comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
blahgeek committed Dec 31, 2023
1 parent 5700285 commit 5cf17ea
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 5 deletions.
4 changes: 4 additions & 0 deletions .dir-locals.el
Original file line number Diff line number Diff line change
@@ -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))))
168 changes: 163 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
53 changes: 53 additions & 0 deletions examples/native-json-parser.rs
Original file line number Diff line number Diff line change
@@ -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<Value<'_>> {
env.message("Done loading!")
}

fn json_to_lisp<'a>(env: &'a Env, val: &json::Value) -> Result<Value<'a>> {
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::<Result<Vec<_>>>()?;
env.vector(&vals)
},
&json::Value::Object(ref map) => {
let mut vals: Vec<Value<'a>> = 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<Value<'_>> {
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)
}

0 comments on commit 5cf17ea

Please sign in to comment.