rs-diff/src/mdiff.rs

126 lines
2.7 KiB
Rust

pub struct Res {
pub count: usize,
pub added: bool,
pub removed: bool,
pub value: String,
}
#[derive(PartialEq, Debug)]
pub enum Mode {
INIT,
BOTH,
LEFT,
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(),
added: if mode == Mode::RIGHT { true } else { false },
removed: if mode == Mode::LEFT { true } else { false },
value: s.clone(),
}
}
pub fn diff_chars(s1: &str, s2: &str) -> Vec<Res> {
let mut mode = Mode::INIT;
let mut s: String = String::new();
let mut result: Vec<Res> = Vec::new();
for d in diff::chars(s1, s2) {
match d {
diff::Result::Left(l) => {
if mode != Mode::LEFT && mode != Mode::INIT {
result.push(get_res(&s, mode));
s.clear();
}
mode = Mode::LEFT;
s.push(l);
}
diff::Result::Right(r) => {
if mode != Mode::RIGHT && mode != Mode::INIT {
result.push(get_res(&s, mode));
s.clear();
}
mode = Mode::RIGHT;
s.push(r);
}
diff::Result::Both(l, _) => {
if mode != Mode::BOTH && mode != Mode::INIT {
result.push(get_res(&s, mode));
s.clear();
}
mode = Mode::BOTH;
s.push(l);
}
}
}
if s.len() > 0 {
result.push(get_res(&s, mode));
s.clear();
}
result
}
pub fn diff_lines(s1: &str, s2: &str) -> Vec<Res> {
let mut result: Vec<Res> = 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
}