patch.rs 19 KB

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