jj_lib/
operation.rs

1// Copyright 2020 The Jujutsu Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#![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/// A wrapper around [`op_store::Operation`] that defines additional methods and
35/// stores a pointer to the `OpStore` the operation belongs to.
36#[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>, // allow cheap clone
43}
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    /// Returns true if predecessors are recorded in this operation.
124    ///
125    /// This returns false only if the operation was written by jj < 0.30.
126    pub fn stores_commit_predecessors(&self) -> bool {
127        self.data.commit_predecessors.is_some()
128    }
129
130    /// Returns predecessors of the specified commit if recorded.
131    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}