1#![allow(missing_docs)]
16
17use std::cmp::Ordering;
18use std::fmt::Debug;
19use std::fmt::Error;
20use std::fmt::Formatter;
21use std::hash::Hash;
22use std::hash::Hasher;
23use std::sync::Arc;
24
25use crate::backend::CommitId;
26use crate::op_store;
27use crate::op_store::OpStore;
28use crate::op_store::OpStoreResult;
29use crate::op_store::OperationId;
30use crate::op_store::OperationMetadata;
31use crate::op_store::ViewId;
32use crate::view::View;
33
34#[derive(Clone, serde::Serialize)]
37pub struct Operation {
38 #[serde(skip)]
39 op_store: Arc<dyn OpStore>,
40 id: OperationId,
41 #[serde(flatten)]
42 data: Arc<op_store::Operation>, }
44
45impl Debug for Operation {
46 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
47 f.debug_struct("Operation").field("id", &self.id).finish()
48 }
49}
50
51impl PartialEq for Operation {
52 fn eq(&self, other: &Self) -> bool {
53 self.id == other.id
54 }
55}
56
57impl Eq for Operation {}
58
59impl Ord for Operation {
60 fn cmp(&self, other: &Self) -> Ordering {
61 self.id.cmp(&other.id)
62 }
63}
64
65impl PartialOrd for Operation {
66 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
67 Some(self.cmp(other))
68 }
69}
70
71impl Hash for Operation {
72 fn hash<H: Hasher>(&self, state: &mut H) {
73 self.id.hash(state);
74 }
75}
76
77impl Operation {
78 pub fn new(
79 op_store: Arc<dyn OpStore>,
80 id: OperationId,
81 data: impl Into<Arc<op_store::Operation>>,
82 ) -> Self {
83 Operation {
84 op_store,
85 id,
86 data: data.into(),
87 }
88 }
89
90 pub fn op_store(&self) -> Arc<dyn OpStore> {
91 self.op_store.clone()
92 }
93
94 pub fn id(&self) -> &OperationId {
95 &self.id
96 }
97
98 pub fn view_id(&self) -> &ViewId {
99 &self.data.view_id
100 }
101
102 pub fn parent_ids(&self) -> &[OperationId] {
103 &self.data.parents
104 }
105
106 pub fn parents(&self) -> impl ExactSizeIterator<Item = OpStoreResult<Operation>> + use<'_> {
107 let op_store = &self.op_store;
108 self.data.parents.iter().map(|parent_id| {
109 let data = op_store.read_operation(parent_id)?;
110 Ok(Operation::new(op_store.clone(), parent_id.clone(), data))
111 })
112 }
113
114 pub fn view(&self) -> OpStoreResult<View> {
115 let data = self.op_store.read_view(&self.data.view_id)?;
116 Ok(View::new(data))
117 }
118
119 pub fn metadata(&self) -> &OperationMetadata {
120 &self.data.metadata
121 }
122
123 pub fn stores_commit_predecessors(&self) -> bool {
127 self.data.commit_predecessors.is_some()
128 }
129
130 pub fn predecessors_for_commit(&self, commit_id: &CommitId) -> Option<&[CommitId]> {
132 let map = self.data.commit_predecessors.as_ref()?;
133 Some(map.get(commit_id)?)
134 }
135
136 pub fn store_operation(&self) -> &op_store::Operation {
137 &self.data
138 }
139}