patch.rs 19 KB

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