##// END OF EJS Templates
rust-cpython: remove useless PyResult<> from leak_immutable()...
rust-cpython: remove useless PyResult<> from leak_immutable() The caller should know if the shared data is mutably borrowed or not.

File last commit:

r43565:99394e6c default
r43611:8418b771 default
Show More
files.rs
128 lines | 3.4 KiB | application/rls-services+xml | RustLexer
Raphaël Gomès
rust-docstrings: add missing module docstrings...
r42996 // 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.
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 use crate::utils::hg_path::{HgPath, HgPathBuf};
Yuya Nishihara
rust-dirstate: add helper to iterate ancestor paths...
r42789 use std::iter::FusedIterator;
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227
Raphaël Gomès
rust-dirstate-status: add first Rust implementation of `dirstate.status`...
r43565 use std::fs::Metadata;
Raphaël Gomès
rust-filepatterns: use bytes instead of String...
r42630 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);
}
Raphaël Gomès
rust-cross-platform: remove `unimplemented!` to get compile-time errors...
r43544 // TODO Handle other platforms
// TODO: convert from WTF8 to Windows MBCS (ANSI encoding).
// Perhaps, the return type would have to be Result<PathBuf>.
Raphaël Gomès
rust-filepatterns: use bytes instead of String...
r42630
Path::new(os_str)
}
Yuya Nishihara
rust-dirstate: add helper to iterate ancestor paths...
r42789
/// An iterator over repository path yielding itself and its ancestors.
#[derive(Copy, Clone, Debug)]
pub struct Ancestors<'a> {
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 next: Option<&'a HgPath>,
Yuya Nishihara
rust-dirstate: add helper to iterate ancestor paths...
r42789 }
impl<'a> Iterator for Ancestors<'a> {
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 type Item = &'a HgPath;
Yuya Nishihara
rust-dirstate: add helper to iterate ancestor paths...
r42789
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) => {
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 let p = s.bytes().rposition(|c| *c == b'/').unwrap_or(0);
Some(HgPath::new(&s.as_bytes()[..p]))
Yuya Nishihara
rust-dirstate: add helper to iterate ancestor paths...
r42789 }
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.)
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 pub fn find_dirs<'a>(path: &'a HgPath) -> Ancestors<'a> {
Yuya Nishihara
rust-dirstate: add helper to iterate ancestor paths...
r42789 let mut dirs = Ancestors { next: Some(path) };
if !path.is_empty() {
dirs.next(); // skip itself
}
dirs
}
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 /// TODO more than ASCII?
pub fn normalize_case(path: &HgPath) -> HgPathBuf {
Raphaël Gomès
rust-utils: add normalize_case util to mirror Python one...
r43108 #[cfg(windows)] // NTFS compares via upper()
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 return path.to_ascii_uppercase();
Raphaël Gomès
rust-utils: add normalize_case util to mirror Python one...
r43108 #[cfg(unix)]
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 path.to_ascii_lowercase()
Raphaël Gomès
rust-utils: add normalize_case util to mirror Python one...
r43108 }
Raphaël Gomès
rust-dirstate-status: add first Rust implementation of `dirstate.status`...
r43565 #[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(),
}
}
}
Yuya Nishihara
rust-dirstate: add helper to iterate ancestor paths...
r42789 #[cfg(test)]
mod tests {
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 use super::*;
Yuya Nishihara
rust-dirstate: add helper to iterate ancestor paths...
r42789 #[test]
fn find_dirs_some() {
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 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"")));
Yuya Nishihara
rust-dirstate: add helper to iterate ancestor paths...
r42789 assert_eq!(dirs.next(), None);
assert_eq!(dirs.next(), None);
}
#[test]
fn find_dirs_empty() {
// looks weird, but mercurial.util.finddirs(b"") yields b""
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 let mut dirs = super::find_dirs(HgPath::new(b""));
assert_eq!(dirs.next(), Some(HgPath::new(b"")));
Yuya Nishihara
rust-dirstate: add helper to iterate ancestor paths...
r42789 assert_eq!(dirs.next(), None);
assert_eq!(dirs.next(), None);
}
}