patch.rs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. use std::{cmp::Ordering, io};
  2. use colored::Colorize;
  3. use serde::{Deserialize, Serialize};
  4. use darkfi::util::{
  5. serial::{Decodable, Encodable, SerialDecodable, SerialEncodable, VarInt},
  6. Timestamp,
  7. };
  8. use crate::str_to_chars;
  9. #[derive(PartialEq, Eq, Serialize, Deserialize, Clone, Debug)]
  10. pub enum OpMethod {
  11. Delete(u64),
  12. Insert(String),
  13. Retain(u64),
  14. }
  15. #[derive(PartialEq, Eq, Serialize, Deserialize, Clone, Debug)]
  16. pub struct OpMethods(pub Vec<OpMethod>);
  17. #[derive(PartialEq, Eq, SerialEncodable, SerialDecodable, Serialize, Deserialize, Clone, Debug)]
  18. pub struct Patch {
  19. pub path: String,
  20. pub author: String,
  21. pub id: String,
  22. pub base: String,
  23. pub timestamp: Timestamp,
  24. pub workspace: String,
  25. ops: OpMethods,
  26. }
  27. impl std::string::ToString for Patch {
  28. fn to_string(&self) -> String {
  29. if self.ops.0.is_empty() {
  30. return self.base.clone()
  31. }
  32. let mut st = vec![];
  33. st.extend(str_to_chars(&self.base));
  34. let st = &mut st.iter();
  35. let mut new_st: Vec<&str> = vec![];
  36. for op in self.ops.0.iter() {
  37. match op {
  38. OpMethod::Retain(n) => {
  39. for c in st.take(*n as usize) {
  40. new_st.push(c);
  41. }
  42. }
  43. OpMethod::Delete(n) => {
  44. for _ in 0..*n {
  45. st.next();
  46. }
  47. }
  48. OpMethod::Insert(insert) => {
  49. let chars = str_to_chars(insert);
  50. new_st.extend(chars);
  51. }
  52. }
  53. }
  54. new_st.join("")
  55. }
  56. }
  57. impl Patch {
  58. pub fn new(path: &str, id: &str, author: &str, workspace: &str) -> Self {
  59. Self {
  60. path: path.to_string(),
  61. id: id.to_string(),
  62. ops: OpMethods(vec![]),
  63. base: String::new(),
  64. workspace: workspace.to_string(),
  65. author: author.to_string(),
  66. timestamp: Timestamp::current_time(),
  67. }
  68. }
  69. pub fn add_op(&mut self, method: &OpMethod) {
  70. match method {
  71. OpMethod::Delete(n) => {
  72. if *n == 0 {
  73. return
  74. }
  75. if let Some(OpMethod::Delete(i)) = self.ops.0.last_mut() {
  76. *i += n;
  77. } else {
  78. self.ops.0.push(method.to_owned());
  79. }
  80. }
  81. OpMethod::Insert(insert) => {
  82. if insert.is_empty() {
  83. return
  84. }
  85. if let Some(OpMethod::Insert(s)) = self.ops.0.last_mut() {
  86. *s += insert;
  87. } else {
  88. self.ops.0.push(OpMethod::Insert(insert.to_owned()));
  89. }
  90. }
  91. OpMethod::Retain(n) => {
  92. if *n == 0 {
  93. return
  94. }
  95. if let Some(OpMethod::Retain(i)) = self.ops.0.last_mut() {
  96. *i += n;
  97. } else {
  98. self.ops.0.push(method.to_owned());
  99. }
  100. }
  101. }
  102. }
  103. fn insert(&mut self, st: &str) {
  104. self.add_op(&OpMethod::Insert(st.into()));
  105. }
  106. fn retain(&mut self, n: u64) {
  107. self.add_op(&OpMethod::Retain(n));
  108. }
  109. fn delete(&mut self, n: u64) {
  110. self.add_op(&OpMethod::Delete(n));
  111. }
  112. pub fn set_ops(&mut self, ops: OpMethods) {
  113. self.ops = ops;
  114. }
  115. pub fn extend_ops(&mut self, ops: OpMethods) {
  116. self.ops.0.extend(ops.0);
  117. }
  118. pub fn ops(&self) -> OpMethods {
  119. self.ops.clone()
  120. }
  121. //
  122. // these two functions are imported from this library
  123. // https://github.com/spebern/operational-transform-rs
  124. // with some major modification
  125. //
  126. // TODO need more work to get better performance with iterators
  127. pub fn transform(&self, other: &Self) -> Self {
  128. let mut new_patch = Self::new(&self.path, &self.id, &self.author, "");
  129. new_patch.base = self.base.clone();
  130. let mut ops1 = self.ops.0.iter().cloned();
  131. let mut ops2 = other.ops.0.iter().cloned();
  132. let mut op1 = ops1.next();
  133. let mut op2 = ops2.next();
  134. loop {
  135. match (&op1, &op2) {
  136. (None, None) => break,
  137. (None, Some(op)) => {
  138. new_patch.add_op(op);
  139. op2 = ops2.next();
  140. continue
  141. }
  142. (Some(op), None) => {
  143. new_patch.add_op(op);
  144. op1 = ops1.next();
  145. continue
  146. }
  147. _ => {}
  148. }
  149. match (op1.as_ref().unwrap(), op2.as_ref().unwrap()) {
  150. (OpMethod::Insert(s), _) => {
  151. new_patch.retain(str_to_chars(s).len() as _);
  152. op1 = ops1.next();
  153. }
  154. (_, OpMethod::Insert(s)) => {
  155. new_patch.insert(s);
  156. op2 = ops2.next();
  157. }
  158. (OpMethod::Retain(i), OpMethod::Retain(j)) => match i.cmp(j) {
  159. Ordering::Less => {
  160. new_patch.retain(*i);
  161. op2 = Some(OpMethod::Retain(j - *i));
  162. op1 = ops1.next();
  163. }
  164. Ordering::Greater => {
  165. new_patch.retain(*j);
  166. op1 = Some(OpMethod::Retain(i - j));
  167. op2 = ops2.next();
  168. }
  169. Ordering::Equal => {
  170. new_patch.retain(*i);
  171. op1 = ops1.next();
  172. op2 = ops2.next();
  173. }
  174. },
  175. (OpMethod::Delete(i), OpMethod::Delete(j)) => match i.cmp(j) {
  176. Ordering::Less => {
  177. op2 = Some(OpMethod::Delete(j - *i));
  178. op1 = ops1.next();
  179. }
  180. Ordering::Greater => {
  181. op1 = Some(OpMethod::Delete(i - j));
  182. op2 = ops2.next();
  183. }
  184. Ordering::Equal => {
  185. op1 = ops1.next();
  186. op2 = ops2.next();
  187. }
  188. },
  189. (OpMethod::Delete(i), OpMethod::Retain(j)) => match i.cmp(j) {
  190. Ordering::Less => {
  191. op2 = Some(OpMethod::Retain(j - *i));
  192. op1 = ops1.next();
  193. }
  194. Ordering::Greater => {
  195. op1 = Some(OpMethod::Delete(i - j));
  196. op2 = ops2.next();
  197. }
  198. Ordering::Equal => {
  199. op1 = ops1.next();
  200. op2 = ops2.next();
  201. }
  202. },
  203. (OpMethod::Retain(i), OpMethod::Delete(j)) => match i.cmp(j) {
  204. Ordering::Less => {
  205. new_patch.delete(*i);
  206. op2 = Some(OpMethod::Delete(j - i));
  207. op1 = ops1.next();
  208. }
  209. Ordering::Greater => {
  210. new_patch.delete(*j);
  211. op1 = Some(OpMethod::Retain(i - j));
  212. op2 = ops2.next();
  213. }
  214. Ordering::Equal => {
  215. new_patch.delete(*i);
  216. op1 = ops1.next();
  217. op2 = ops2.next();
  218. }
  219. },
  220. }
  221. }
  222. new_patch
  223. }
  224. // TODO need more work to get better performance with iterators
  225. pub fn merge(&mut self, other: &Self) -> Self {
  226. let ops1 = self.ops.0.clone();
  227. let mut ops1 = ops1.iter().cloned();
  228. let mut ops2 = other.ops.0.iter().cloned();
  229. let mut new_patch = Self::new(&self.path, &self.id, &self.author, "");
  230. new_patch.base = self.base.clone();
  231. let mut op1 = ops1.next();
  232. let mut op2 = ops2.next();
  233. loop {
  234. match (&op1, &op2) {
  235. (None, None) => break,
  236. (None, Some(op)) => {
  237. new_patch.add_op(op);
  238. op2 = ops2.next();
  239. continue
  240. }
  241. (Some(op), None) => {
  242. new_patch.add_op(op);
  243. op1 = ops1.next();
  244. continue
  245. }
  246. _ => {}
  247. }
  248. match (op1.as_ref().unwrap(), op2.as_ref().unwrap()) {
  249. (OpMethod::Delete(i), _) => {
  250. new_patch.delete(*i);
  251. op1 = ops1.next();
  252. }
  253. (_, OpMethod::Insert(s)) => {
  254. new_patch.insert(s);
  255. op2 = ops2.next();
  256. }
  257. (OpMethod::Retain(i), OpMethod::Retain(j)) => match i.cmp(j) {
  258. Ordering::Less => {
  259. new_patch.retain(*i);
  260. op2 = Some(OpMethod::Retain(*j - i));
  261. op1 = ops1.next();
  262. }
  263. Ordering::Greater => {
  264. new_patch.retain(*j);
  265. op1 = Some(OpMethod::Retain(i - *j));
  266. op2 = ops2.next();
  267. }
  268. Ordering::Equal => {
  269. new_patch.retain(*i);
  270. op1 = ops1.next();
  271. op2 = ops2.next();
  272. }
  273. },
  274. (OpMethod::Insert(s), OpMethod::Delete(j)) => {
  275. let chars = str_to_chars(s);
  276. let chars_len = chars.len() as u64;
  277. match chars_len.cmp(j) {
  278. Ordering::Less => {
  279. op1 = ops1.next();
  280. op2 = Some(OpMethod::Delete(j - chars_len));
  281. }
  282. Ordering::Greater => {
  283. let st = chars.into_iter().skip(*j as usize).collect();
  284. op1 = Some(OpMethod::Insert(st));
  285. op2 = ops2.next();
  286. }
  287. Ordering::Equal => {
  288. op1 = ops1.next();
  289. op2 = ops2.next();
  290. }
  291. }
  292. }
  293. (OpMethod::Insert(s), OpMethod::Retain(j)) => {
  294. let chars = str_to_chars(s);
  295. let chars_len = chars.len() as u64;
  296. match chars_len.cmp(j) {
  297. Ordering::Less => {
  298. new_patch.insert(s);
  299. op1 = ops1.next();
  300. op2 = Some(OpMethod::Retain(*j - chars_len));
  301. }
  302. Ordering::Greater => {
  303. let st = chars.into_iter().take(*j as usize).collect::<String>();
  304. new_patch.insert(&st);
  305. op1 = Some(OpMethod::Insert(st));
  306. op2 = ops2.next();
  307. }
  308. Ordering::Equal => {
  309. new_patch.insert(s);
  310. op1 = ops1.next();
  311. op2 = ops2.next();
  312. }
  313. }
  314. }
  315. (OpMethod::Retain(i), OpMethod::Delete(j)) => match i.cmp(j) {
  316. Ordering::Less => {
  317. new_patch.delete(*i);
  318. op2 = Some(OpMethod::Delete(*j - *i));
  319. op1 = ops1.next();
  320. }
  321. Ordering::Greater => {
  322. new_patch.delete(*j);
  323. op1 = Some(OpMethod::Retain(*i - *j));
  324. op2 = ops2.next();
  325. }
  326. Ordering::Equal => {
  327. new_patch.delete(*j);
  328. op1 = ops1.next();
  329. op2 = ops2.next();
  330. }
  331. },
  332. };
  333. }
  334. new_patch
  335. }
  336. pub fn colorize(&self) -> String {
  337. if self.ops.0.is_empty() {
  338. return format!("{}", self.base.green())
  339. }
  340. let mut st = vec![];
  341. st.extend(str_to_chars(&self.base));
  342. let st = &mut st.iter();
  343. let mut colorized_str: Vec<String> = vec![];
  344. for op in self.ops.0.iter() {
  345. match op {
  346. OpMethod::Retain(n) => {
  347. for c in st.take(*n as usize) {
  348. colorized_str.push(c.to_string());
  349. }
  350. }
  351. OpMethod::Delete(n) => {
  352. let mut deleted_part = vec![];
  353. for _ in 0..*n {
  354. let s = st.next();
  355. if let Some(s) = s {
  356. deleted_part.push(s.to_string());
  357. }
  358. }
  359. colorized_str.push(format!("{}", deleted_part.join("").red()));
  360. }
  361. OpMethod::Insert(insert) => {
  362. let chars = str_to_chars(insert);
  363. colorized_str.push(format!("{}", chars.join("").green()));
  364. }
  365. }
  366. }
  367. colorized_str.join("")
  368. }
  369. }
  370. impl Decodable for OpMethod {
  371. fn decode<D: io::Read>(mut d: D) -> darkfi::Result<Self> {
  372. let com: u8 = Decodable::decode(&mut d)?;
  373. match com {
  374. 0 => {
  375. let i: u64 = Decodable::decode(&mut d)?;
  376. Ok(Self::Delete(i))
  377. }
  378. 1 => {
  379. let t: String = Decodable::decode(d)?;
  380. Ok(Self::Insert(t))
  381. }
  382. 2 => {
  383. let i: u64 = Decodable::decode(&mut d)?;
  384. Ok(Self::Retain(i))
  385. }
  386. _ => Err(darkfi::Error::ParseFailed("Parse OpMethod failed")),
  387. }
  388. }
  389. }
  390. impl Encodable for OpMethod {
  391. fn encode<S: io::Write>(&self, mut s: S) -> darkfi::Result<usize> {
  392. let len: usize = match self {
  393. Self::Delete(i) => (0_u8).encode(&mut s)? + i.encode(&mut s)?,
  394. Self::Insert(t) => (1_u8).encode(&mut s)? + t.encode(&mut s)?,
  395. Self::Retain(i) => (2_u8).encode(&mut s)? + i.encode(&mut s)?,
  396. };
  397. Ok(len)
  398. }
  399. }
  400. impl Encodable for OpMethods {
  401. fn encode<S: io::Write>(&self, mut s: S) -> darkfi::Result<usize> {
  402. let mut len = 0;
  403. len += VarInt(self.0.len() as u64).encode(&mut s)?;
  404. for c in self.0.iter() {
  405. len += c.encode(&mut s)?;
  406. }
  407. Ok(len)
  408. }
  409. }
  410. impl Decodable for OpMethods {
  411. fn decode<D: io::Read>(mut d: D) -> darkfi::Result<Self> {
  412. let len = VarInt::decode(&mut d)?.0;
  413. let mut ret = Vec::with_capacity(len as usize);
  414. for _ in 0..len {
  415. ret.push(Decodable::decode(&mut d)?);
  416. }
  417. Ok(Self(ret))
  418. }
  419. }
  420. #[cfg(test)]
  421. mod tests {
  422. use super::*;
  423. use darkfi::util::{
  424. gen_id,
  425. serial::{deserialize, serialize},
  426. };
  427. #[test]
  428. fn test_to_string() {
  429. let mut patch = Patch::new("", &gen_id(30), "", "");
  430. patch.base = "text example\n hello".to_string();
  431. patch.retain(14);
  432. patch.delete(5);
  433. patch.insert("hey");
  434. assert_eq!(patch.to_string(), "text example\n hey");
  435. }
  436. #[test]
  437. fn test_merge() {
  438. let mut patch_init = Patch::new("", &gen_id(30), "", "");
  439. let base = "text example\n hello";
  440. patch_init.base = base.to_string();
  441. let mut patch1 = patch_init.clone();
  442. patch1.retain(14);
  443. patch1.delete(5);
  444. patch1.insert("hey");
  445. let mut patch2 = patch_init.clone();
  446. patch2.retain(14);
  447. patch2.delete(5);
  448. patch2.insert("test");
  449. patch1.merge(&patch2);
  450. let patch3 = patch1.merge(&patch2);
  451. assert_eq!(patch3.to_string(), "text example\n test");
  452. let mut patch1 = patch_init.clone();
  453. patch1.retain(5);
  454. patch1.delete(7);
  455. patch1.insert("ex");
  456. patch1.retain(7);
  457. let mut patch2 = patch_init.clone();
  458. patch2.delete(4);
  459. patch2.insert("new");
  460. patch2.retain(13);
  461. let patch3 = patch1.merge(&patch2);
  462. assert_eq!(patch3.to_string(), "new ex\n hello");
  463. }
  464. #[test]
  465. fn test_transform() {
  466. let mut patch_init = Patch::new("", &gen_id(30), "", "");
  467. let base = "text example\n hello";
  468. patch_init.base = base.to_string();
  469. let mut patch1 = patch_init.clone();
  470. patch1.retain(14);
  471. patch1.delete(5);
  472. patch1.insert("hey");
  473. let mut patch2 = patch_init.clone();
  474. patch2.retain(14);
  475. patch2.delete(5);
  476. patch2.insert("test");
  477. let patch3 = patch1.transform(&patch2);
  478. let patch4 = patch1.merge(&patch3);
  479. assert_eq!(patch4.to_string(), "text example\n heytest");
  480. let mut patch1 = patch_init.clone();
  481. patch1.retain(5);
  482. patch1.delete(7);
  483. patch1.insert("ex");
  484. patch1.retain(7);
  485. let mut patch2 = patch_init.clone();
  486. patch2.delete(4);
  487. patch2.insert("new");
  488. patch2.retain(13);
  489. let patch3 = patch1.transform(&patch2);
  490. let patch4 = patch1.merge(&patch3);
  491. assert_eq!(patch4.to_string(), "new ex\n hello");
  492. }
  493. #[test]
  494. fn test_transform2() {
  495. let mut patch_init = Patch::new("", &gen_id(30), "", "");
  496. let base = "#hello\n hello";
  497. patch_init.base = base.to_string();
  498. let mut patch1 = patch_init.clone();
  499. patch1.retain(13);
  500. patch1.insert(" world");
  501. let mut patch2 = patch_init.clone();
  502. patch2.retain(1);
  503. patch2.delete(5);
  504. patch2.insert("this is the title");
  505. patch2.retain(7);
  506. patch2.insert("\n this is the content");
  507. let patch3 = patch1.transform(&patch2);
  508. let patch4 = patch1.merge(&patch3);
  509. assert_eq!(patch4.to_string(), "#this is the title\n hello world\n this is the content");
  510. }
  511. #[test]
  512. fn test_serialize() {
  513. // serialize & deserialize OpMethod
  514. let op_method = OpMethod::Delete(3);
  515. let op_method_ser = serialize(&op_method);
  516. let op_method_deser = deserialize(&op_method_ser).unwrap();
  517. assert_eq!(op_method, op_method_deser);
  518. // serialize & deserialize Patch
  519. let mut patch = Patch::new("", &gen_id(30), "", "");
  520. patch.insert("hello");
  521. patch.delete(2);
  522. let patch_ser = serialize(&patch);
  523. let patch_deser = deserialize(&patch_ser).unwrap();
  524. assert_eq!(patch, patch_deser);
  525. }
  526. }