ok/jj
1
0
Fork 0
forked from mirrors/jj

simple_op_store: rewrite RefTarget serialization to work with Option<_>

is_none()/is_some() are wrapped as is_absent()/is_present() respectively.
If we see new RefTarget as a Conflict, an "absent" target isn't an emptyish
value like None, but an add of single [None]. It seemed a bit weird to call
such target is_none().
This commit is contained in:
Yuya Nishihara 2023-07-12 04:36:25 +09:00
parent 5d87f372d8
commit 75429293f2
2 changed files with 46 additions and 29 deletions

View file

@ -190,7 +190,11 @@ impl RefTarget {
// TODO: These methods will be migrate to new Conflict-based RefTarget type. // TODO: These methods will be migrate to new Conflict-based RefTarget type.
pub trait RefTargetExt { pub trait RefTargetExt {
fn as_normal(&self) -> Option<&CommitId>; fn as_normal(&self) -> Option<&CommitId>;
fn is_absent(&self) -> bool;
fn is_present(&self) -> bool;
fn is_conflict(&self) -> bool; fn is_conflict(&self) -> bool;
fn removes(&self) -> &[CommitId];
fn adds(&self) -> &[CommitId];
} }
impl RefTargetExt for Option<&RefTarget> { impl RefTargetExt for Option<&RefTarget> {
@ -198,9 +202,25 @@ impl RefTargetExt for Option<&RefTarget> {
self.and_then(|target| target.as_normal()) self.and_then(|target| target.as_normal())
} }
fn is_absent(&self) -> bool {
self.is_none()
}
fn is_present(&self) -> bool {
self.is_some()
}
fn is_conflict(&self) -> bool { fn is_conflict(&self) -> bool {
self.map(|target| target.is_conflict()).unwrap_or(false) self.map(|target| target.is_conflict()).unwrap_or(false)
} }
fn removes(&self) -> &[CommitId] {
self.map(|target| target.removes()).unwrap_or_default()
}
fn adds(&self) -> &[CommitId] {
self.map(|target| target.adds()).unwrap_or_default()
}
} }
content_hash! { content_hash! {

View file

@ -29,7 +29,7 @@ use crate::content_hash::blake2b_hash;
use crate::file_util::persist_content_addressed_temp_file; use crate::file_util::persist_content_addressed_temp_file;
use crate::op_store::{ use crate::op_store::{
BranchTarget, OpStore, OpStoreError, OpStoreResult, Operation, OperationId, OperationMetadata, BranchTarget, OpStore, OpStoreError, OpStoreResult, Operation, OperationId, OperationMetadata,
RefTarget, View, ViewId, WorkspaceId, RefTarget, RefTargetExt as _, View, ViewId, WorkspaceId,
}; };
impl From<std::io::Error> for OpStoreError { impl From<std::io::Error> for OpStoreError {
@ -220,15 +220,13 @@ fn view_to_proto(view: &View) -> crate::protos::op_store::View {
..Default::default() ..Default::default()
}; };
branch_proto.name = name.clone(); branch_proto.name = name.clone();
if let Some(local_target) = &target.local_target { branch_proto.local_target = ref_target_to_proto(target.local_target.as_ref());
branch_proto.local_target = Some(ref_target_to_proto(local_target));
}
for (remote_name, target) in &target.remote_targets { for (remote_name, target) in &target.remote_targets {
branch_proto branch_proto
.remote_branches .remote_branches
.push(crate::protos::op_store::RemoteBranch { .push(crate::protos::op_store::RemoteBranch {
remote_name: remote_name.clone(), remote_name: remote_name.clone(),
target: Some(ref_target_to_proto(target)), target: ref_target_to_proto(Some(target)),
}); });
} }
proto.branches.push(branch_proto); proto.branches.push(branch_proto);
@ -237,21 +235,19 @@ fn view_to_proto(view: &View) -> crate::protos::op_store::View {
for (name, target) in &view.tags { for (name, target) in &view.tags {
proto.tags.push(crate::protos::op_store::Tag { proto.tags.push(crate::protos::op_store::Tag {
name: name.clone(), name: name.clone(),
target: Some(ref_target_to_proto(target)), target: ref_target_to_proto(Some(target)),
}); });
} }
for (git_ref_name, target) in &view.git_refs { for (git_ref_name, target) in &view.git_refs {
proto.git_refs.push(crate::protos::op_store::GitRef { proto.git_refs.push(crate::protos::op_store::GitRef {
name: git_ref_name.clone(), name: git_ref_name.clone(),
target: Some(ref_target_to_proto(target)), target: ref_target_to_proto(Some(target)),
..Default::default() ..Default::default()
}); });
} }
if let Some(git_head) = &view.git_head { proto.git_head = ref_target_to_proto(view.git_head.as_ref());
proto.git_head = Some(ref_target_to_proto(git_head));
}
proto proto
} }
@ -326,28 +322,29 @@ fn view_from_proto(proto: crate::protos::op_store::View) -> View {
view view
} }
fn ref_target_to_proto(value: &RefTarget) -> crate::protos::op_store::RefTarget { fn ref_target_to_proto(value: Option<&RefTarget>) -> Option<crate::protos::op_store::RefTarget> {
let mut proto = crate::protos::op_store::RefTarget::default(); if let Some(id) = value.as_normal() {
match value { let proto = crate::protos::op_store::RefTarget {
RefTarget::Normal(id) => { value: Some(crate::protos::op_store::ref_target::Value::CommitId(
proto.value = Some(crate::protos::op_store::ref_target::Value::CommitId(
id.to_bytes(), id.to_bytes(),
)); )),
} };
RefTarget::Conflict { removes, adds } => { Some(proto)
let mut ref_conflict_proto = crate::protos::op_store::RefConflict::default(); } else if value.is_conflict() {
for id in removes { let ref_conflict_proto = crate::protos::op_store::RefConflict {
ref_conflict_proto.removes.push(id.to_bytes()); removes: value.removes().iter().map(|id| id.to_bytes()).collect(),
} adds: value.adds().iter().map(|id| id.to_bytes()).collect(),
for id in adds { };
ref_conflict_proto.adds.push(id.to_bytes()); let proto = crate::protos::op_store::RefTarget {
} value: Some(crate::protos::op_store::ref_target::Value::Conflict(
proto.value = Some(crate::protos::op_store::ref_target::Value::Conflict(
ref_conflict_proto, ref_conflict_proto,
)); )),
} };
Some(proto)
} else {
assert!(value.is_absent());
None
} }
proto
} }
fn ref_target_from_proto(proto: crate::protos::op_store::RefTarget) -> RefTarget { fn ref_target_from_proto(proto: crate::protos::op_store::RefTarget) -> RefTarget {