… into trim_end_matches that takes a callack.
Also add trim_start_matches.
( )
Alphare |
hg-reviewers |
… into trim_end_matches that takes a callack.
Also add trim_start_matches.
Automatic diff as part of commit; lint not applicable. |
Automatic diff as part of commit; unit tests not applicable. |
Path | Packages | |||
---|---|---|---|---|
M | rust/hg-core/src/repo.rs (3 lines) | |||
M | rust/hg-core/src/utils.rs (32 lines) |
Status | Author | Revision | |
---|---|---|---|
Closed | SimonSapin | ||
Closed | SimonSapin | ||
Closed | SimonSapin |
let share_safe = reqs.contains(requirements::SHARESAFE_REQUIREMENT); | let share_safe = reqs.contains(requirements::SHARESAFE_REQUIREMENT); | ||||
let store_path; | let store_path; | ||||
if !shared { | if !shared { | ||||
store_path = dot_hg.join("store"); | store_path = dot_hg.join("store"); | ||||
} else { | } else { | ||||
let bytes = hg_vfs.read("sharedpath")?; | let bytes = hg_vfs.read("sharedpath")?; | ||||
let mut shared_path = | let mut shared_path = | ||||
get_path_from_bytes(bytes.trim_end_newlines()).to_owned(); | get_path_from_bytes(bytes.trim_end_matches(|b| b == b'\n')) | ||||
.to_owned(); | |||||
if relative { | if relative { | ||||
shared_path = dot_hg.join(shared_path) | shared_path = dot_hg.join(shared_path) | ||||
} | } | ||||
if !is_dir(&shared_path)? { | if !is_dir(&shared_path)? { | ||||
return Err(HgError::corrupted(format!( | return Err(HgError::corrupted(format!( | ||||
".hg/sharedpath points to nonexistent directory {}", | ".hg/sharedpath points to nonexistent directory {}", | ||||
shared_path.display() | shared_path.display() | ||||
)) | )) |
for i in 0..=buf.len() - from.len() { | for i in 0..=buf.len() - from.len() { | ||||
if buf[i..].starts_with(from) { | if buf[i..].starts_with(from) { | ||||
buf[i..(i + from.len())].clone_from_slice(to); | buf[i..(i + from.len())].clone_from_slice(to); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
pub trait SliceExt { | pub trait SliceExt { | ||||
fn trim_end_newlines(&self) -> &Self; | |||||
fn trim_end(&self) -> &Self; | fn trim_end(&self) -> &Self; | ||||
fn trim_start(&self) -> &Self; | fn trim_start(&self) -> &Self; | ||||
fn trim_end_matches(&self, f: impl FnMut(u8) -> bool) -> &Self; | |||||
fn trim_start_matches(&self, f: impl FnMut(u8) -> bool) -> &Self; | |||||
fn trim(&self) -> &Self; | fn trim(&self) -> &Self; | ||||
fn drop_prefix(&self, needle: &Self) -> Option<&Self>; | fn drop_prefix(&self, needle: &Self) -> Option<&Self>; | ||||
fn split_2(&self, separator: u8) -> Option<(&[u8], &[u8])>; | fn split_2(&self, separator: u8) -> Option<(&[u8], &[u8])>; | ||||
} | } | ||||
#[allow(clippy::trivially_copy_pass_by_ref)] | |||||
fn is_not_whitespace(c: &u8) -> bool { | |||||
!(*c as char).is_whitespace() | |||||
} | |||||
impl SliceExt for [u8] { | impl SliceExt for [u8] { | ||||
fn trim_end_newlines(&self) -> &[u8] { | fn trim_end(&self) -> &[u8] { | ||||
if let Some(last) = self.iter().rposition(|&byte| byte != b'\n') { | self.trim_end_matches(|byte| byte.is_ascii_whitespace()) | ||||
&self[..=last] | |||||
} else { | |||||
&[] | |||||
} | } | ||||
fn trim_start(&self) -> &[u8] { | |||||
self.trim_start_matches(|byte| byte.is_ascii_whitespace()) | |||||
} | } | ||||
fn trim_end(&self) -> &[u8] { | |||||
if let Some(last) = self.iter().rposition(is_not_whitespace) { | fn trim_end_matches(&self, mut f: impl FnMut(u8) -> bool) -> &Self { | ||||
if let Some(last) = self.iter().rposition(|&byte| !f(byte)) { | |||||
&self[..=last] | &self[..=last] | ||||
} else { | } else { | ||||
&[] | &[] | ||||
} | } | ||||
} | } | ||||
fn trim_start(&self) -> &[u8] { | |||||
if let Some(first) = self.iter().position(is_not_whitespace) { | fn trim_start_matches(&self, mut f: impl FnMut(u8) -> bool) -> &Self { | ||||
if let Some(first) = self.iter().position(|&byte| !f(byte)) { | |||||
&self[first..] | &self[first..] | ||||
} else { | } else { | ||||
&[] | &[] | ||||
} | } | ||||
} | } | ||||
/// ``` | /// ``` | ||||
/// use hg::utils::SliceExt; | /// use hg::utils::SliceExt; |