patch.rs 20 KB

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