lb_rs/model/
server_ops.rs1use super::errors::{DiffError, LbErrKind, LbResult};
2use super::server_meta::{IntoServerMeta, ServerMeta};
3use super::signed_meta::SignedMeta;
4use crate::model::clock::get_time;
5use crate::model::file_like::FileLike;
6use crate::model::file_metadata::FileDiff;
7use crate::model::lazy::{LazyStaged1, LazyTree};
8use crate::model::server_tree::ServerTree;
9use crate::model::tree_like::TreeLike;
10
11type LazyServerStaged1<'a> = LazyStaged1<ServerTree<'a>, Vec<ServerMeta>>;
12
13impl<'a> LazyTree<ServerTree<'a>> {
14 pub fn stage_diff_v2(
15 self, changes: Vec<FileDiff<SignedMeta>>,
16 ) -> LbResult<LazyServerStaged1<'a>> {
17 for change in &changes {
19 if let Some(old) = &change.old {
20 if old.id() != change.new.id() {
21 return Err(LbErrKind::Diff(DiffError::DiffMalformed))?;
22 }
23 }
24 }
25
26 for change in &changes {
28 match &change.old {
29 Some(old) => {
30 if old.timestamped_value.value.document_hmac()
31 != change.new.timestamped_value.value.document_hmac()
32 {
33 return Err(LbErrKind::Diff(DiffError::HmacModificationInvalid))?;
34 }
35
36 if old.timestamped_value.value.doc_size()
37 != change.new.timestamped_value.value.doc_size()
38 {
39 return Err(LbErrKind::Diff(DiffError::SizeModificationInvalid))?;
40 }
41 }
42 None => {
43 if change.new.timestamped_value.value.doc_size().is_some() {
44 return Err(LbErrKind::Diff(DiffError::SizeModificationInvalid))?;
45 }
46 if change.new.timestamped_value.value.document_hmac().is_some() {
47 return Err(LbErrKind::Diff(DiffError::HmacModificationInvalid))?;
48 }
49 }
50 }
51 }
52
53 for change in &changes {
55 match &change.old {
56 Some(old) => {
57 let current = &self
58 .maybe_find(old.id())
59 .ok_or(LbErrKind::Diff(DiffError::OldFileNotFound))?
60 .file;
61
62 if current != old {
63 return Err(LbErrKind::Diff(DiffError::OldVersionIncorrect))?;
64 }
65 }
66 None => {
67 if self.tree.files.maybe_find(change.new.id()).is_some() {
69 return Err(LbErrKind::Diff(DiffError::OldVersionRequired))?;
70 }
71 }
72 }
73 }
74
75 Ok(self.stage_unvalidated(changes))
76 }
77
78 pub fn stage_unvalidated(self, changes: Vec<FileDiff<SignedMeta>>) -> LazyServerStaged1<'a> {
79 let now = get_time().0 as u64;
80 let changes = changes
81 .into_iter()
82 .map(|change| change.new.add_time(now))
83 .collect();
84
85 self.stage(changes)
86 }
87}