diff --git a/__test__/index.spec.js b/__test__/index.spec.js index f36194d..3fc875d 100644 --- a/__test__/index.spec.js +++ b/__test__/index.spec.js @@ -1,11 +1,14 @@ const test = require('ava') -const { diff } = require('../index') +const { diffChars } = require('../index') -test('diff', (t) => { +test('diff chars', (t) => { const left = 'asd' const right = 'asd' - const result = diff(left, right) - console.log(result) + const result = diffChars(left, right) t.is(result.length, 1) + t.is(result[0].count, 3) + t.is(result[0].value, 'asd') + t.is(result[0].added, false) + t.is(result[0].removed, false) }) diff --git a/index.d.ts b/index.d.ts index aa31e57..a79daa6 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2,3 +2,8 @@ export const diffChars: ( left: string, right: string, ) => [{ count: number; value: string; added: boolean; removed: boolean }] + +export const diffLines: ( + left: string, + right: string, +) => [{ count: number; value: string; added: boolean; removed: boolean }] diff --git a/index.js b/index.js index e0c7789..1f42359 100644 --- a/index.js +++ b/index.js @@ -1,12 +1,12 @@ -const path = require("path"); const { loadBinding } = require("@node-rs/helper"); try { // __dirname means load native addon from current dir // 'index' means native addon name is `index` // the value of this two arguments was decided by `build` script in `package.json` - module.exports = loadBinding(path.join(__dirname, "index", "@mtfos/rs-diff")); + module.exports = loadBinding(__dirname, "index", "@mtfos/rs-diff"); } catch (e) { + console.log(e); try { module.exports = require(`@mtfos/rs-diff-${process.platform}`); } catch (e) { diff --git a/package-lock.json b/package-lock.json index 5d22953..a06419f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -99,6 +99,18 @@ } } }, + "@mtfos/rs-diff-darwin": { + "version": "0.0.6", + "resolved": "https://npm.trj.tw/@mtfos%2frs-diff-darwin/-/rs-diff-darwin-0.0.6.tgz", + "integrity": "sha512-Qhu9vfTdUoIGcJl4uuaeb4fjU64RNozqmfGZzdMtzruOZmI0sLZJInBm4ZjtVXGjowrtuzeLtqNB+e0a0cbCRA==", + "optional": true + }, + "@mtfos/rs-diff-linux": { + "version": "0.0.6", + "resolved": "https://npm.trj.tw/@mtfos%2frs-diff-linux/-/rs-diff-linux-0.0.6.tgz", + "integrity": "sha512-wQwnstELnuVH/6BXtrgDG7SmJtlM4UO13MK0Q+zUFvr7IOdOVdX8oqet/4WEOtful7iid2KlYWnu0xXJG2XIyQ==", + "optional": true + }, "@node-rs/helper": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@node-rs/helper/-/helper-0.4.0.tgz", diff --git a/package.json b/package.json index 5c4be8e..9accb6d 100644 --- a/package.json +++ b/package.json @@ -50,4 +50,4 @@ "@mtfos/rs-diff-darwin": "^0.0.6", "@mtfos/rs-diff-linux": "^0.0.6" } -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index 59af173..7a33f81 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,6 +17,7 @@ register_module!(example, init); fn init(module: &mut Module) -> Result<()> { module.create_named_method("diffChars", diff_char)?; + module.create_named_method("diffLines", diff_line)?; Ok(()) } @@ -32,7 +33,34 @@ fn diff_char(ctx: CallContext) -> Result { let mut idx = 0; for it in res.iter() { let mut item = ctx.env.create_object().unwrap(); - + + item.set_named_property( + "count", + ctx.env.create_int64(it.count.try_into().unwrap()).unwrap(), + )?; + item.set_named_property("value", ctx.env.create_string(&it.value).unwrap())?; + item.set_named_property("added", ctx.env.get_boolean(it.added).unwrap())?; + item.set_named_property("removed", ctx.env.get_boolean(it.removed).unwrap())?; + + obj.set_element(idx, item)?; + idx += 1; + } + + Ok(obj) +} + +#[js_function(2)] +fn diff_line(ctx: CallContext) -> Result { + let str1: String = ctx.get::(0)?.try_into()?; + let str2: String = ctx.get::(1)?.try_into()?; + let res = mdiff::diff_lines(str1.as_str(), str2.as_str()); + + let mut obj = ctx.env.create_array_with_length(res.len()).unwrap(); + let mut idx = 0; + + for it in res.iter() { + let mut item = ctx.env.create_object().unwrap(); + item.set_named_property( "count", ctx.env.create_int64(it.count.try_into().unwrap()).unwrap(), diff --git a/src/mdiff.rs b/src/mdiff.rs index 9cbeeff..1b6531c 100644 --- a/src/mdiff.rs +++ b/src/mdiff.rs @@ -13,6 +13,14 @@ pub enum Mode { RIGHT, } +fn get_line_res(s: &String, mode: Mode) -> Res { + Res { + count: s.split('\n').count(), + added: if mode == Mode::RIGHT { true } else { false }, + removed: if mode == Mode::LEFT { true } else { false }, + value: s.clone(), + } +} fn get_res(s: &String, mode: Mode) -> Res { Res { count: s.chars().count(), @@ -64,3 +72,54 @@ pub fn diff_chars(s1: &str, s2: &str) -> Vec { result } + +pub fn diff_lines(s1: &str, s2: &str) -> Vec { + let mut result: Vec = Vec::new(); + let mut mode = Mode::INIT; + let mut s: String = String::new(); + + for d in diff::lines(s1, s2) { + match d { + diff::Result::Left(l) => { + if mode != Mode::LEFT && mode != Mode::INIT { + result.push(get_line_res(&s, mode)); + s.clear(); + } + mode = Mode::LEFT; + if s.len() > 0 { + s.push('\n') + } + s.push_str(l); + } + diff::Result::Right(r) => { + if mode != Mode::RIGHT && mode != Mode::INIT { + result.push(get_line_res(&s, mode)); + s.clear(); + } + mode = Mode::RIGHT; + if s.len() > 0 { + s.push('\n') + } + s.push_str(r); + } + diff::Result::Both(l, _) => { + if mode != Mode::BOTH && mode != Mode::INIT { + result.push(get_line_res(&s, mode)); + s.clear() + } + mode = Mode::BOTH; + if s.len() > 0 { + s.push('\n') + } + s.push_str(l); + } + } + } + + if s.len() > 0 { + result.push(get_line_res(&s, mode)); + s.clear(); + } + + result +}