Skip to content

Commit e26c72f

Browse files
committed
[ref] refactor
1 parent f4bb7a0 commit e26c72f

File tree

19 files changed

+167
-226
lines changed

19 files changed

+167
-226
lines changed

git-object/tests/immutable/tag.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ mod method {
99
fn target() -> crate::Result {
1010
let fixture = fixture_bytes("tag", "signed.txt");
1111
let tag = Tag::from_bytes(&fixture)?;
12-
assert_eq!(tag.target(), hex_to_id("ffa700b4aca13b80cb6b98a078e7c96804f8e0ec"));
12+
assert_eq!(
13+
tag.target.borrow(),
14+
hex_to_id("ffa700b4aca13b80cb6b98a078e7c96804f8e0ec")
15+
);
1316
assert_eq!(tag.target, "ffa700b4aca13b80cb6b98a078e7c96804f8e0ec".as_bytes());
1417
Ok(())
1518
}

git-ref/src/mutable.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ impl TryFrom<BString> for FullName {
3333
}
3434
}
3535

36+
// TODO: remove this one to be consistent with borrowed version
3637
impl AsRef<BStr> for FullName {
3738
fn as_ref(&self) -> &BStr {
3839
self.0.as_bstr()
@@ -59,6 +60,10 @@ impl FullName {
5960
pub fn into_inner(self) -> BString {
6061
self.0
6162
}
63+
/// Return ourselves as byte string which is a valid refname
64+
pub fn as_bstr(&self) -> &BStr {
65+
self.0.as_bstr()
66+
}
6267
}
6368

6469
/// Denotes a ref target, equivalent to [`Kind`][super::Kind], but with mutable data.

git-ref/src/store/file/loose/find.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,12 @@ impl file::Store {
119119
}
120120
Some(c) => c,
121121
};
122-
Ok(Some(
123-
file::Reference::try_from_path(self, &relative_path, &contents)
122+
Ok(Some({
123+
let full_name = path_to_name(&relative_path);
124+
file::Reference::try_from_path(self, FullName(full_name), &contents)
124125
.map(file::loose_then_packed::Reference::Loose)
125-
.map_err(|err| Error::ReferenceCreation { err, relative_path })?,
126-
))
126+
.map_err(|err| Error::ReferenceCreation { err, relative_path })?
127+
}))
127128
}
128129
}
129130

@@ -256,4 +257,5 @@ mod error {
256257
}
257258
}
258259
}
260+
use crate::mutable::FullName;
259261
pub use error::Error;

git-ref/src/store/file/loose/iter.rs

Lines changed: 30 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::store::file;
2-
use bstr::{BString, ByteSlice};
1+
use crate::{mutable::FullName, store::file};
2+
use bstr::ByteSlice;
33
use git_features::fs::walkdir::DirEntryIter;
44
use os_str_bytes::OsStrBytes;
55
use std::{
@@ -11,31 +11,20 @@ use std::{
1111
pub(in crate::store::file) struct SortedLoosePaths {
1212
base: PathBuf,
1313
file_walk: DirEntryIter,
14-
mode: LoosePathsMode,
15-
}
16-
17-
enum LoosePathsMode {
18-
Paths,
19-
PathsAndNames,
2014
}
2115

2216
impl SortedLoosePaths {
23-
pub fn at_root(path: impl AsRef<Path>, base: impl Into<PathBuf>) -> Self {
24-
Self::new(path.as_ref(), base.into(), LoosePathsMode::Paths)
25-
}
26-
2717
pub fn at_root_with_names(path: impl AsRef<Path>, base: impl Into<PathBuf>) -> Self {
28-
Self::new(path.as_ref(), base.into(), LoosePathsMode::PathsAndNames)
29-
}
30-
31-
fn new(path: &Path, base: PathBuf, mode: LoosePathsMode) -> Self {
3218
let file_walk = git_features::fs::walkdir_sorted_new(path).into_iter();
33-
SortedLoosePaths { base, file_walk, mode }
19+
SortedLoosePaths {
20+
base: base.into(),
21+
file_walk,
22+
}
3423
}
3524
}
3625

3726
impl Iterator for SortedLoosePaths {
38-
type Item = std::io::Result<(PathBuf, Option<BString>)>;
27+
type Item = std::io::Result<(PathBuf, FullName)>;
3928

4029
fn next(&mut self) -> Option<Self::Item> {
4130
while let Some(entry) = self.file_walk.next() {
@@ -52,15 +41,11 @@ impl Iterator for SortedLoosePaths {
5241
#[cfg(windows)]
5342
let full_name: Vec<u8> = full_name.into_owned().replace(b"\\", b"/");
5443

55-
use LoosePathsMode::*;
5644
if git_validate::reference::name_partial(full_name.as_bstr()).is_ok() {
57-
let name = match self.mode {
58-
Paths => None,
59-
#[cfg(not(windows))]
60-
PathsAndNames => Some(full_name.into_owned().into()),
61-
#[cfg(windows)]
62-
PathsAndNames => Some(full_name.into()),
63-
};
45+
#[cfg(not(windows))]
46+
let name = FullName(full_name.into_owned().into());
47+
#[cfg(windows)]
48+
let name = FullName(full_name.into());
6449
return Some(Ok((full_path, name)));
6550
} else {
6651
continue;
@@ -86,7 +71,7 @@ impl<'a> Loose<'a> {
8671
pub fn at_root(store: &'a file::Store, root: impl AsRef<Path>, base: impl Into<PathBuf>) -> Self {
8772
Loose {
8873
parent: store,
89-
ref_paths: SortedLoosePaths::at_root(root, base),
74+
ref_paths: SortedLoosePaths::at_root_with_names(root, base),
9075
buf: Vec::new(),
9176
}
9277
}
@@ -97,26 +82,25 @@ impl<'a> Iterator for Loose<'a> {
9782

9883
fn next(&mut self) -> Option<Self::Item> {
9984
self.ref_paths.next().map(|res| {
100-
res.map_err(loose::Error::Traversal)
101-
.and_then(|(validated_path, _name)| {
102-
std::fs::File::open(&validated_path)
103-
.and_then(|mut f| {
104-
self.buf.clear();
105-
f.read_to_end(&mut self.buf)
106-
})
107-
.map_err(loose::Error::ReadFileContents)
108-
.and_then(|_| {
109-
let relative_path = validated_path
110-
.strip_prefix(&self.ref_paths.base)
111-
.expect("root contains path");
112-
file::Reference::try_from_path(self.parent, relative_path, &self.buf).map_err(|err| {
113-
loose::Error::ReferenceCreation {
114-
err,
115-
relative_path: relative_path.into(),
116-
}
117-
})
85+
res.map_err(loose::Error::Traversal).and_then(|(validated_path, name)| {
86+
std::fs::File::open(&validated_path)
87+
.and_then(|mut f| {
88+
self.buf.clear();
89+
f.read_to_end(&mut self.buf)
90+
})
91+
.map_err(loose::Error::ReadFileContents)
92+
.and_then(|_| {
93+
let relative_path = validated_path
94+
.strip_prefix(&self.ref_paths.base)
95+
.expect("root contains path");
96+
file::Reference::try_from_path(self.parent, name, &self.buf).map_err(|err| {
97+
loose::Error::ReferenceCreation {
98+
err,
99+
relative_path: relative_path.into(),
100+
}
118101
})
119-
})
102+
})
103+
})
120104
})
121105
}
122106
}

git-ref/src/store/file/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ impl Default for WriteReflog {
2121
pub struct Reference<'a> {
2222
parent: &'a Store,
2323
/// The path to uniquely identify this ref within its store.
24-
// TODO: make this a FullName(BString) and remove the `relative_path()` method entirely.
25-
relative_path: PathBuf,
26-
target: mutable::Target,
24+
pub name: mutable::FullName,
25+
/// The target of the reference, either a symbolic reference by full name or an object by its id.
26+
pub target: mutable::Target,
2727
}
2828

2929
/// A store for reference which uses plain files.

git-ref/src/store/file/overlay/iter.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use crate::{
33
file::path_to_name,
44
store::{file, packed},
55
};
6-
use bstr::BString;
76
use std::{
87
cmp::Ordering,
98
io::Read,
@@ -27,19 +26,21 @@ impl<'p, 's> LooseThenPacked<'p, 's> {
2726
})
2827
}
2928

30-
fn convert_loose(&mut self, res: std::io::Result<(PathBuf, Option<BString>)>) -> Result<Reference<'p, 's>, Error> {
31-
let (refpath, _name) = res.map_err(Error::Traversal)?;
29+
fn convert_loose(&mut self, res: std::io::Result<(PathBuf, FullName)>) -> Result<Reference<'p, 's>, Error> {
30+
let (refpath, name) = res.map_err(Error::Traversal)?;
3231
std::fs::File::open(&refpath)
3332
.and_then(|mut f| {
3433
self.buf.clear();
3534
f.read_to_end(&mut self.buf)
3635
})
3736
.map_err(Error::ReadFileContents)?;
38-
let relative_path = refpath.strip_prefix(&self.parent.base).expect("base contains path");
39-
file::Reference::try_from_path(self.parent, relative_path, &self.buf)
37+
file::Reference::try_from_path(self.parent, name, &self.buf)
4038
.map_err(|err| Error::ReferenceCreation {
4139
err,
42-
relative_path: relative_path.into(),
40+
relative_path: refpath
41+
.strip_prefix(&self.parent.base)
42+
.expect("base contains path")
43+
.into(),
4344
})
4445
.map(Reference::Loose)
4546
}
@@ -60,8 +61,8 @@ impl<'p, 's> Iterator for LooseThenPacked<'p, 's> {
6061
Some(self.convert_loose(res))
6162
}
6263
(Some(Ok(loose)), Some(Ok(packed))) => {
63-
let loose_name = loose.1.as_ref().expect("name retrieval configured");
64-
match loose_name.as_slice().cmp(packed.full_name) {
64+
let loose_name = loose.1.as_ref();
65+
match loose_name.cmp(packed.full_name) {
6566
Ordering::Less => {
6667
let res = self.loose.next().expect("name retrieval configured");
6768
Some(self.convert_loose(res))
@@ -154,4 +155,5 @@ mod error {
154155
}
155156
}
156157

158+
use crate::mutable::FullName;
157159
pub use error::Error;

git-ref/src/store/file/overlay/reference.rs

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
use super::Reference;
22
use crate::{
3-
mutable,
3+
mutable, name,
44
store::{
55
file::{log, loose},
66
packed,
77
},
8+
FullName,
89
};
910
use git_hash::oid;
10-
use std::{
11-
convert::{TryFrom, TryInto},
12-
path::Path,
13-
};
11+
use std::convert::{TryFrom, TryInto};
1412

1513
impl<'p, 's> TryFrom<Reference<'p, 's>> for crate::file::Reference<'s> {
1614
type Error = ();
@@ -32,14 +30,6 @@ impl<'p, 's> Reference<'p, 's> {
3230
}
3331
}
3432

35-
/// Return the full name of this reference as path, only applicable if this is a loose reference.
36-
pub fn relative_path(&self) -> Option<&Path> {
37-
match self {
38-
Reference::Loose(r) => Some(r.relative_path()),
39-
Reference::Packed(_) => None,
40-
}
41-
}
42-
4333
/// For details, see [crate::file::Reference::peel_to_id_in_place].
4434
pub fn peel_to_id_in_place(
4535
&mut self,
@@ -96,7 +86,7 @@ impl<'p, 's> Reference<'p, 's> {
9686
pub fn into_target(self) -> mutable::Target {
9787
match self {
9888
Reference::Packed(p) => mutable::Target::Peeled(p.object()),
99-
Reference::Loose(r) => r.into_target(),
89+
Reference::Loose(r) => r.target,
10090
}
10191
}
10292

@@ -109,18 +99,18 @@ impl<'p, 's> Reference<'p, 's> {
10999
}
110100

111101
/// Return the full validated name of the reference. Please note that if the reference is packed, validation can fail here.
112-
pub fn name(&self) -> Result<mutable::FullName, git_validate::refname::Error> {
102+
pub fn name(&self) -> Result<FullName<'_>, name::Error> {
113103
match self {
114104
Reference::Packed(p) => p.full_name.try_into(),
115-
Reference::Loose(l) => Ok(l.name()),
105+
Reference::Loose(l) => Ok(l.name.borrow()),
116106
}
117107
}
118108

119109
/// Return the target to which the reference points to.
120110
pub fn target(&self) -> mutable::Target {
121111
match self {
122112
Reference::Packed(p) => mutable::Target::Peeled(p.target()),
123-
Reference::Loose(l) => l.target().to_owned(),
113+
Reference::Loose(l) => l.target.clone(),
124114
}
125115
}
126116
}

git-ref/src/store/file/reference/decode.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ use nom::{
1212
IResult,
1313
};
1414
use quick_error::quick_error;
15-
use std::{
16-
convert::{TryFrom, TryInto},
17-
path::PathBuf,
18-
};
15+
use std::convert::{TryFrom, TryInto};
1916

2017
enum MaybeUnsafeState {
2118
Id(ObjectId),
@@ -56,14 +53,10 @@ impl TryFrom<MaybeUnsafeState> for mutable::Target {
5653
impl<'a> Reference<'a> {
5754
/// Create a new reference of the given `parent` store with `relative_path` service as unique identifier
5855
/// at which the `path_contents` was read to obtain the refs value.
59-
pub fn try_from_path(
60-
parent: &'a Store,
61-
relative_path: impl Into<PathBuf>,
62-
path_contents: &[u8],
63-
) -> Result<Self, Error> {
56+
pub fn try_from_path(parent: &'a Store, name: mutable::FullName, path_contents: &[u8]) -> Result<Self, Error> {
6457
Ok(Reference {
6558
parent,
66-
relative_path: relative_path.into(),
59+
name,
6760
target: parse(path_contents)
6861
.map_err(|_| Error::Parse(path_contents.into()))?
6962
.1

git-ref/src/store/file/reference/logiter.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
use crate::{
2-
store::file::{log, loose, Reference},
3-
FullName,
4-
};
5-
use bstr::ByteSlice;
1+
use crate::store::file::{log, loose, Reference};
62
use std::io::Read;
73

84
impl<'a> Reference<'a> {
@@ -13,9 +9,7 @@ impl<'a> Reference<'a> {
139
/// If the caller needs to know if it's readable, try to read the log instead with a reverse or forward iterator.
1410
pub fn log_exists(&self) -> Result<bool, loose::reflog::Error> {
1511
// NOTE: Have to repeat the implementation of store::reflog_iter here as borrow_check believes impl Iterator binds self
16-
use os_str_bytes::OsStrBytes;
17-
let name = self.relative_path.as_path().to_raw_bytes();
18-
Ok(self.parent.reflog_path(FullName(name.as_bstr())).is_file())
12+
Ok(self.parent.reflog_path(self.name.borrow()).is_file())
1913
}
2014
/// Return a reflog reverse iterator for this ref, reading chunks from the back into the fixed buffer `buf`.
2115
///
@@ -26,9 +20,7 @@ impl<'a> Reference<'a> {
2620
buf: &'b mut [u8],
2721
) -> Result<Option<log::iter::Reverse<'b, std::fs::File>>, loose::reflog::Error> {
2822
// NOTE: Have to repeat the implementation of store::reflog_iter here as borrow_check believes impl Iterator binds self
29-
use os_str_bytes::OsStrBytes;
30-
let name = self.relative_path.as_path().to_raw_bytes();
31-
let file = match std::fs::File::open(self.parent.reflog_path(FullName(name.as_bstr()))) {
23+
let file = match std::fs::File::open(self.parent.reflog_path(self.name.borrow())) {
3224
Ok(file) => file,
3325
Err(err) if err.kind() == std::io::ErrorKind::NotFound => return Ok(None),
3426
Err(err) => return Err(err.into()),
@@ -46,9 +38,7 @@ impl<'a> Reference<'a> {
4638
) -> Result<Option<impl Iterator<Item = Result<log::Line<'b>, log::iter::decode::Error>>>, loose::reflog::Error>
4739
{
4840
// NOTE: Have to repeat the implementation of store::reflog_iter here as borrow_check believes impl Iterator binds self
49-
use os_str_bytes::OsStrBytes;
50-
let name = self.relative_path.as_path().to_raw_bytes();
51-
match std::fs::File::open(self.parent.reflog_path(FullName(name.as_bstr()))) {
41+
match std::fs::File::open(self.parent.reflog_path(self.name.borrow())) {
5242
Ok(mut file) => {
5343
buf.clear();
5444
file.read_to_end(buf)?;

0 commit comments

Comments
 (0)