feat: add qjs

This commit is contained in:
2020-11-28 13:59:12 +08:00
parent 208169d999
commit 295e097e91
4 changed files with 96 additions and 1 deletions

View File

@@ -17,5 +17,6 @@ clap = "2.33"
toml = "0.5" toml = "0.5"
rust_util = "0.6" rust_util = "0.6"
regex = "1.4" regex = "1.4"
quick-js = { git = "https://git.hatter.ink/public-collect/quickjs-rs.git" }

View File

@@ -1,6 +1,8 @@
use clap::{App, Arg, ArgMatches}; use clap::{App, Arg, ArgMatches};
use crate::cmd::CommandError; use crate::cmd::CommandError;
use crate::template::CommitMsgCheck;
use crate::template_regex::CommitMsgCheckRegex; use crate::template_regex::CommitMsgCheckRegex;
use crate::template_quickjs::CommitMsgCheckQuickJs;
pub struct CommandImpl; pub struct CommandImpl;
@@ -15,7 +17,24 @@ impl CommandImpl {
information!("Verbose count: {}", verbose_count); information!("Verbose count: {}", verbose_count);
information!(r#"Print using command line: information!(r#"Print using command line:
commit-msg usage"#); commit-msg usage"#);
CommitMsgCheckRegex::new_default(); let a = CommitMsgCheckRegex::new_default();
let b = CommitMsgCheckQuickJs::new_from_js(r##"
function check(a) {
return false;
}
function hint() {
return "hello";
}
"##).expect("err");
if !a.check("a") {
a.print_hint();
}
if !b.check("b") {
b.print_hint();
}
Ok(()) Ok(())
} }
} }

View File

@@ -7,6 +7,7 @@ mod cmd_usage;
mod cmd_install; mod cmd_install;
mod template; mod template;
mod template_regex; mod template_regex;
mod template_quickjs;
use clap::App; use clap::App;
use cmd::{Command, CommandError}; use cmd::{Command, CommandError};

74
src/template_quickjs.rs Normal file
View File

@@ -0,0 +1,74 @@
use quick_js::{Context, JsValue};
use quick_js::console::{Level, ConsoleBackend};
use rust_util::XResult;
use crate::template::CommitMsgCheck;
pub struct CommitMsgCheckQuickJs {
context: Context,
}
impl CommitMsgCheck for CommitMsgCheckQuickJs {
fn check(&self, msg: &str) -> bool {
match self.context.eval(&format!("check('{}')", encode_str(msg))) {
Err(e) => {
failure!("Run JS function #check(msg) faield: {}", e);
false
},
Ok(JsValue::Bool(val)) => val,
Ok(JsValue::Null) => false,
Ok(JsValue::Int(val)) => val == 1,
Ok(JsValue::Float(val)) => val == 1.0,
Ok(JsValue::String(val)) => val == "1",
others => {
warning!("Run JS function #check(msg) return value unknown: {:?}", others);
false
},
}
}
fn print_hint(&self) {
match self.context.eval("hint()") {
Err(e) => failure!("Run JS function #hint() faield: {}", e),
Ok(JsValue::String(val)) => println!("[USAGE] {}", val),
others => println!("[USAGE] {:?}", others),
}
}
}
struct ConsoleBackendImpl;
impl ConsoleBackend for ConsoleBackendImpl {
fn log(&self, level: Level, values: Vec<JsValue>) {
println!("[{:>5}] - {:?}", format!("{:?}", level).to_uppercase(), values);
}
}
impl CommitMsgCheckQuickJs {
pub fn new_from_js(js: &str) -> XResult<Self> {
let context = Context::builder().memory_limit(16 * 1024 * 1024)
.console(ConsoleBackendImpl{})
.build()?;
context.eval(js)?;
Ok(Self{
context,
})
}
}
fn encode_str(s: &str) -> String {
let mut ret = String::with_capacity(s.len() + 10);
for c in s.chars() {
if c == '\\' || c == '\'' {
ret.push('\\');
ret.push(c);
} else if c == '\n' {
ret.push_str("\\n");
} else if c == '\r' {
ret.push_str("\\r");
} else if c == '\t' {
ret.push_str("\\t");
} else {
ret.push(c);
}
}
ret
}