##// END OF EJS Templates
lfs: fix a discrepancy with a function wanting a filelog, but calling it rlog...
lfs: fix a discrepancy with a function wanting a filelog, but calling it rlog This conceptually broke in 1541e1a8e87d when the filelog isa revlog relationship was changed to containment of the revlog. It was made more obvious in 62a532045e71 and related API simplification. It's resolved in favor of passing a revlog because the revlog verification code doesn't have a reference to a filelog. Differential Revision: https://phab.mercurial-scm.org/D7711

File last commit:

r44321:cf065c6a merge default
r44410:26cf356a default
Show More
files.rs
136 lines | 3.7 KiB | application/rls-services+xml | RustLexer
// files.rs
//
// Copyright 2019
// Raphaël Gomès <rgomes@octobus.net>,
// Yuya Nishihara <yuya@tcha.org>
//
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2 or any later version.
//! Functions for fiddling with files.
use crate::utils::hg_path::{HgPath, HgPathBuf};
use std::iter::FusedIterator;
use std::fs::Metadata;
use std::path::Path;
pub fn get_path_from_bytes(bytes: &[u8]) -> &Path {
let os_str;
#[cfg(unix)]
{
use std::os::unix::ffi::OsStrExt;
os_str = std::ffi::OsStr::from_bytes(bytes);
}
// TODO Handle other platforms
// TODO: convert from WTF8 to Windows MBCS (ANSI encoding).
// Perhaps, the return type would have to be Result<PathBuf>.
Path::new(os_str)
}
// TODO: need to convert from WTF8 to MBCS bytes on Windows.
// that's why Vec<u8> is returned.
#[cfg(unix)]
pub fn get_bytes_from_path(path: impl AsRef<Path>) -> Vec<u8> {
use std::os::unix::ffi::OsStrExt;
path.as_ref().as_os_str().as_bytes().to_vec()
}
/// An iterator over repository path yielding itself and its ancestors.
#[derive(Copy, Clone, Debug)]
pub struct Ancestors<'a> {
next: Option<&'a HgPath>,
}
impl<'a> Iterator for Ancestors<'a> {
type Item = &'a HgPath;
fn next(&mut self) -> Option<Self::Item> {
let next = self.next;
self.next = match self.next {
Some(s) if s.is_empty() => None,
Some(s) => {
let p = s.bytes().rposition(|c| *c == b'/').unwrap_or(0);
Some(HgPath::new(&s.as_bytes()[..p]))
}
None => None,
};
next
}
}
impl<'a> FusedIterator for Ancestors<'a> {}
/// Returns an iterator yielding ancestor directories of the given repository
/// path.
///
/// The path is separated by '/', and must not start with '/'.
///
/// The path itself isn't included unless it is b"" (meaning the root
/// directory.)
pub fn find_dirs<'a>(path: &'a HgPath) -> Ancestors<'a> {
let mut dirs = Ancestors { next: Some(path) };
if !path.is_empty() {
dirs.next(); // skip itself
}
dirs
}
/// TODO more than ASCII?
pub fn normalize_case(path: &HgPath) -> HgPathBuf {
#[cfg(windows)] // NTFS compares via upper()
return path.to_ascii_uppercase();
#[cfg(unix)]
path.to_ascii_lowercase()
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
pub struct HgMetadata {
pub st_dev: u64,
pub st_mode: u32,
pub st_nlink: u64,
pub st_size: u64,
pub st_mtime: i64,
pub st_ctime: i64,
}
// TODO support other plaforms
#[cfg(unix)]
impl HgMetadata {
pub fn from_metadata(metadata: Metadata) -> Self {
use std::os::unix::fs::MetadataExt;
Self {
st_dev: metadata.dev(),
st_mode: metadata.mode(),
st_nlink: metadata.nlink(),
st_size: metadata.size(),
st_mtime: metadata.mtime(),
st_ctime: metadata.ctime(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn find_dirs_some() {
let mut dirs = super::find_dirs(HgPath::new(b"foo/bar/baz"));
assert_eq!(dirs.next(), Some(HgPath::new(b"foo/bar")));
assert_eq!(dirs.next(), Some(HgPath::new(b"foo")));
assert_eq!(dirs.next(), Some(HgPath::new(b"")));
assert_eq!(dirs.next(), None);
assert_eq!(dirs.next(), None);
}
#[test]
fn find_dirs_empty() {
// looks weird, but mercurial.pathutil.finddirs(b"") yields b""
let mut dirs = super::find_dirs(HgPath::new(b""));
assert_eq!(dirs.next(), Some(HgPath::new(b"")));
assert_eq!(dirs.next(), None);
assert_eq!(dirs.next(), None);
}
}