patch.rs 19 KB

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