document.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. use bytes::Bytes;
  2. use flowy_error::{FlowyError, FlowyResult};
  3. use flowy_http_model::revision::Revision;
  4. use flowy_revision::{RevisionMergeable, RevisionObjectDeserializer, RevisionObjectSerializer};
  5. use lib_ot::core::{Extension, NodeDataBuilder, NodeOperation, NodeTree, NodeTreeContext, Selection, Transaction};
  6. use lib_ot::text_delta::DeltaTextOperationBuilder;
  7. #[derive(Debug)]
  8. pub struct Document {
  9. tree: NodeTree,
  10. }
  11. impl Document {
  12. pub fn new(tree: NodeTree) -> Self {
  13. Self { tree }
  14. }
  15. pub fn from_transaction(transaction: Transaction) -> FlowyResult<Self> {
  16. let tree = NodeTree::from_operations(transaction.operations, make_tree_context())?;
  17. Ok(Self { tree })
  18. }
  19. pub fn get_content(&self, pretty: bool) -> FlowyResult<String> {
  20. if pretty {
  21. serde_json::to_string_pretty(self).map_err(|err| FlowyError::serde().context(err))
  22. } else {
  23. serde_json::to_string(self).map_err(|err| FlowyError::serde().context(err))
  24. }
  25. }
  26. pub fn document_md5(&self) -> String {
  27. let bytes = self.tree.to_bytes();
  28. format!("{:x}", md5::compute(&bytes))
  29. }
  30. pub fn get_tree(&self) -> &NodeTree {
  31. &self.tree
  32. }
  33. }
  34. pub(crate) fn make_tree_context() -> NodeTreeContext {
  35. NodeTreeContext {}
  36. }
  37. pub fn initial_document_content() -> String {
  38. let delta = DeltaTextOperationBuilder::new().insert("").build();
  39. let node_data = NodeDataBuilder::new("text").insert_delta(delta).build();
  40. let editor_node = NodeDataBuilder::new("editor").add_node_data(node_data).build();
  41. let node_operation = NodeOperation::Insert {
  42. path: vec![0].into(),
  43. nodes: vec![editor_node],
  44. };
  45. let extension = Extension::TextSelection {
  46. before_selection: Selection::default(),
  47. after_selection: Selection::default(),
  48. };
  49. let transaction = Transaction {
  50. operations: vec![node_operation].into(),
  51. extension,
  52. };
  53. transaction.to_json().unwrap()
  54. }
  55. impl std::ops::Deref for Document {
  56. type Target = NodeTree;
  57. fn deref(&self) -> &Self::Target {
  58. &self.tree
  59. }
  60. }
  61. impl std::ops::DerefMut for Document {
  62. fn deref_mut(&mut self) -> &mut Self::Target {
  63. &mut self.tree
  64. }
  65. }
  66. pub struct DocumentRevisionSerde();
  67. impl RevisionObjectDeserializer for DocumentRevisionSerde {
  68. type Output = Document;
  69. fn deserialize_revisions(_object_id: &str, revisions: Vec<Revision>) -> FlowyResult<Self::Output> {
  70. let mut tree = NodeTree::new(make_tree_context());
  71. let transaction = make_transaction_from_revisions(&revisions)?;
  72. let _ = tree.apply_transaction(transaction)?;
  73. let document = Document::new(tree);
  74. Result::<Document, FlowyError>::Ok(document)
  75. }
  76. }
  77. impl RevisionObjectSerializer for DocumentRevisionSerde {
  78. fn combine_revisions(revisions: Vec<Revision>) -> FlowyResult<Bytes> {
  79. let transaction = make_transaction_from_revisions(&revisions)?;
  80. Ok(Bytes::from(transaction.to_bytes()?))
  81. }
  82. }
  83. pub(crate) struct DocumentRevisionCompress();
  84. impl RevisionMergeable for DocumentRevisionCompress {
  85. fn combine_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
  86. DocumentRevisionSerde::combine_revisions(revisions)
  87. }
  88. }
  89. #[tracing::instrument(level = "trace", skip_all, err)]
  90. pub fn make_transaction_from_revisions(revisions: &[Revision]) -> FlowyResult<Transaction> {
  91. let mut transaction = Transaction::new();
  92. for revision in revisions {
  93. let _ = transaction.compose(Transaction::from_bytes(&revision.bytes)?)?;
  94. }
  95. Ok(transaction)
  96. }