mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-11-24 05:29:51 +03:00
remove linefile
This commit is contained in:
parent
c13c706268
commit
9803a7d0c8
61
Cargo.lock
generated
61
Cargo.lock
generated
@ -1334,18 +1334,6 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "enum-as-inner"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a"
|
|
||||||
dependencies = [
|
|
||||||
"heck 0.4.1",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.48",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "enumflags2"
|
name = "enumflags2"
|
||||||
version = "0.7.8"
|
version = "0.7.8"
|
||||||
@ -1991,8 +1979,6 @@ dependencies = [
|
|||||||
name = "gitbutler-changeset"
|
name = "gitbutler-changeset"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"git2",
|
|
||||||
"mmap-rs",
|
|
||||||
"paste",
|
"paste",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
@ -2863,15 +2849,6 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
|
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mach2"
|
|
||||||
version = "0.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "malloc_buf"
|
name = "malloc_buf"
|
||||||
version = "0.0.6"
|
version = "0.0.6"
|
||||||
@ -2986,23 +2963,6 @@ dependencies = [
|
|||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mmap-rs"
|
|
||||||
version = "0.6.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "86968d85441db75203c34deefd0c88032f275aaa85cee19a1dcfff6ae9df56da"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 1.3.2",
|
|
||||||
"combine",
|
|
||||||
"libc",
|
|
||||||
"mach2",
|
|
||||||
"nix 0.26.4",
|
|
||||||
"sysctl",
|
|
||||||
"thiserror",
|
|
||||||
"widestring",
|
|
||||||
"windows 0.48.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "native-tls"
|
name = "native-tls"
|
||||||
version = "0.2.11"
|
version = "0.2.11"
|
||||||
@ -3065,7 +3025,6 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"memoffset 0.7.1",
|
"memoffset 0.7.1",
|
||||||
"pin-utils",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -5263,20 +5222,6 @@ dependencies = [
|
|||||||
"windows-sys 0.45.0",
|
"windows-sys 0.45.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sysctl"
|
|
||||||
version = "0.5.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ec7dddc5f0fee506baf8b9fdb989e242f17e4b11c61dfbb0635b705217199eea"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 2.4.0",
|
|
||||||
"byteorder",
|
|
||||||
"enum-as-inner",
|
|
||||||
"libc",
|
|
||||||
"thiserror",
|
|
||||||
"walkdir",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sysinfo"
|
name = "sysinfo"
|
||||||
version = "0.30.7"
|
version = "0.30.7"
|
||||||
@ -6485,12 +6430,6 @@ version = "0.1.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
|
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "widestring"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
|
@ -3,15 +3,8 @@ name = "gitbutler-changeset"
|
|||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["git2", "mmap"]
|
|
||||||
git2 = ["dep:git2"]
|
|
||||||
mmap = ["dep:mmap-rs"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
git2 = { workspace = true, optional = true }
|
|
||||||
mmap-rs = { version = "0.6.1", optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
paste = "1.0.14"
|
paste = "1.0.14"
|
||||||
|
@ -46,14 +46,7 @@
|
|||||||
#![allow(clippy::doc_markdown, clippy::missing_errors_doc)]
|
#![allow(clippy::doc_markdown, clippy::missing_errors_doc)]
|
||||||
#![feature(impl_trait_in_assoc_type, iter_map_windows, slice_as_chunks)]
|
#![feature(impl_trait_in_assoc_type, iter_map_windows, slice_as_chunks)]
|
||||||
|
|
||||||
mod linefile;
|
|
||||||
mod signature;
|
mod signature;
|
||||||
mod span;
|
mod span;
|
||||||
|
|
||||||
#[cfg(feature = "mmap")]
|
pub use self::{signature::Signature, span::LineSpan};
|
||||||
pub use self::linefile::mmap::MmapLineFile;
|
|
||||||
pub use self::{
|
|
||||||
linefile::{memory::MemoryLineFile, CrlfBehavior, LineEndings, LineFile},
|
|
||||||
signature::Signature,
|
|
||||||
span::LineSpan,
|
|
||||||
};
|
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
use crate::LineSpan;
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
pub mod memory;
|
|
||||||
#[cfg(feature = "mmap")]
|
|
||||||
pub mod mmap;
|
|
||||||
|
|
||||||
/// A file, delimited by lines. The line ending is unspecified;
|
|
||||||
/// it is assumed the underlying implementation handles (and omits)
|
|
||||||
/// line endings for us.
|
|
||||||
///
|
|
||||||
/// All text is assumed to be UTF-8.
|
|
||||||
pub trait LineFile<'a> {
|
|
||||||
/// The type of iterator returned by [`LineFile::lines`] and [`LineFile::extract`].
|
|
||||||
type LineIterator: Iterator<Item = &'a str>;
|
|
||||||
|
|
||||||
/// Gets the line count of the file.
|
|
||||||
fn line_count(&self) -> usize;
|
|
||||||
|
|
||||||
/// Returns a slice of lines given the span.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if the span is out of bounds.
|
|
||||||
fn extract(&'a self, span: LineSpan) -> Self::LineIterator;
|
|
||||||
|
|
||||||
/// Returns an iterator over the all lines of the file.
|
|
||||||
fn lines(&'a self) -> Self::LineIterator {
|
|
||||||
self.extract(LineSpan::new(0, self.line_count() - 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Render the file to the given [`fmt::Write`]r.
|
|
||||||
/// Will append each line, including the last, with the line ending
|
|
||||||
/// specified by `line_endings`.
|
|
||||||
fn render<W: fmt::Write>(
|
|
||||||
&'a self,
|
|
||||||
writer: &mut W,
|
|
||||||
line_endings: LineEndings,
|
|
||||||
) -> Result<(), fmt::Error> {
|
|
||||||
for line in self.lines() {
|
|
||||||
writer.write_str(line)?;
|
|
||||||
match line_endings {
|
|
||||||
LineEndings::Unix => writer.write_char('\n')?,
|
|
||||||
LineEndings::Windows => writer.write_str("\r\n")?,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The behavior of CRLF (carriage return + line feed) characters
|
|
||||||
/// when splitting a file into lines.
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
||||||
pub enum CrlfBehavior {
|
|
||||||
/// Trims carriage returns (`\r`) from the end of lines.
|
|
||||||
Trim,
|
|
||||||
/// Keeps carriage returns (`\r`) at the end of lines.
|
|
||||||
Keep,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Which line ending to emit when rendering files to a [`fmt::Write`]r.
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
||||||
pub enum LineEndings {
|
|
||||||
/// Use Unix-style line endings (`\n`).
|
|
||||||
Unix,
|
|
||||||
/// Use Windows-style line endings (`\r\n`).
|
|
||||||
Windows,
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
#![allow(clippy::module_name_repetitions)]
|
|
||||||
|
|
||||||
use crate::{CrlfBehavior, LineFile, LineSpan};
|
|
||||||
|
|
||||||
/// A [`LineFile`] stored in memory.
|
|
||||||
pub struct MemoryLineFile {
|
|
||||||
lines: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MemoryLineFile {
|
|
||||||
/// Creates a new [`MemoryLineFile`] from the given lines.
|
|
||||||
#[must_use]
|
|
||||||
pub fn new(lines: Vec<String>) -> Self {
|
|
||||||
Self { lines }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new [`MemoryLineFile`] from the given text,
|
|
||||||
/// with the given CRLF behavior.
|
|
||||||
#[must_use]
|
|
||||||
pub fn from_str(text: &str, crlf_behavior: CrlfBehavior) -> Self {
|
|
||||||
MemoryLineFile {
|
|
||||||
lines: text
|
|
||||||
.split('\n')
|
|
||||||
.map(|line| match crlf_behavior {
|
|
||||||
CrlfBehavior::Trim => line.trim_end_matches('\r').to_owned(),
|
|
||||||
CrlfBehavior::Keep => line.to_owned(),
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> LineFile<'a> for MemoryLineFile {
|
|
||||||
type LineIterator = impl Iterator<Item = &'a str>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn line_count(&self) -> usize {
|
|
||||||
self.lines.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
fn extract(&'a self, span: LineSpan) -> Self::LineIterator {
|
|
||||||
self.lines[span.start()..=span.end()]
|
|
||||||
.iter()
|
|
||||||
.map(AsRef::as_ref)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,87 +0,0 @@
|
|||||||
#![allow(clippy::module_name_repetitions)]
|
|
||||||
|
|
||||||
use crate::{CrlfBehavior, LineFile};
|
|
||||||
use mmap_rs::{Error, Mmap};
|
|
||||||
|
|
||||||
/// A [`LineFile`] created from a read-only memory-mapped file.
|
|
||||||
pub struct MmapLineFile {
|
|
||||||
mmap: Mmap,
|
|
||||||
line_slices: Vec<(usize, usize)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MmapLineFile {
|
|
||||||
/// Creates a new [`MmapLineFile`] from the given memory-mapped file.
|
|
||||||
///
|
|
||||||
/// Will attempt to make the Mmap read-only. Upon failure to do so,
|
|
||||||
/// returns both the original [`Mmap`] and the error.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if the document's contents are not valid UTF-8.
|
|
||||||
pub fn from_mmap(mmap: Mmap, crlf_behavior: CrlfBehavior) -> Result<Self, (Mmap, Error)> {
|
|
||||||
let mmap = mmap.make_read_only()?;
|
|
||||||
let mut line_slices = Vec::new();
|
|
||||||
// We check it here to avoid having to check it in the loop.
|
|
||||||
std::str::from_utf8(mmap.as_ref()).expect("mmap contents are not valid UTF-8");
|
|
||||||
MmapLineFile::init_lines(mmap.as_slice(), &mut line_slices, crlf_behavior);
|
|
||||||
Ok(Self { mmap, line_slices })
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new [`MmapLineFile`] from the given file path.
|
|
||||||
/// **Unsafely** assumes the file is UTF-8 and will not attempt to convert it.
|
|
||||||
///
|
|
||||||
/// Will attempt to make the Mmap read-only. Upon failure to do so,
|
|
||||||
/// returns both the original [`Mmap`] and the error.
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// This function is unsafe because it assumes the file is UTF-8. If it is not,
|
|
||||||
/// the behavior is undefined.
|
|
||||||
pub unsafe fn from_mmap_unsafe(
|
|
||||||
mmap: Mmap,
|
|
||||||
crlf_behavior: CrlfBehavior,
|
|
||||||
) -> Result<Self, (Mmap, Error)> {
|
|
||||||
let mmap = mmap.make_read_only()?;
|
|
||||||
let mut line_slices = Vec::new();
|
|
||||||
MmapLineFile::init_lines(mmap.as_slice(), &mut line_slices, crlf_behavior);
|
|
||||||
Ok(Self { mmap, line_slices })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init_lines(text: &[u8], lines: &mut Vec<(usize, usize)>, crlf_behavior: CrlfBehavior) {
|
|
||||||
text.iter()
|
|
||||||
.enumerate()
|
|
||||||
.fold((0, false), |(start, cr), (i, c)| {
|
|
||||||
if *c == b'\n' {
|
|
||||||
lines.push((
|
|
||||||
start,
|
|
||||||
i - usize::from(cr && crlf_behavior == CrlfBehavior::Trim),
|
|
||||||
));
|
|
||||||
(i + 1, false)
|
|
||||||
} else {
|
|
||||||
(start, *c == b'\r')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> LineFile<'a> for MmapLineFile {
|
|
||||||
type LineIterator = impl Iterator<Item = &'a str>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn line_count(&self) -> usize {
|
|
||||||
self.line_slices.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract(&'a self, span: crate::LineSpan) -> Self::LineIterator {
|
|
||||||
let mmap_ref = self.mmap.as_ref();
|
|
||||||
|
|
||||||
self.line_slices[span.start()..=span.end()]
|
|
||||||
.iter()
|
|
||||||
.map(|(start, end)| &mmap_ref[*start..=*end])
|
|
||||||
// The unsafe variant has been checked in the constructors.
|
|
||||||
// Either they called `from_mmap` and it was checked there,
|
|
||||||
// or they called `from_mmap_unsafe` and the caller assumes
|
|
||||||
// responsibility for the UTF-8 invariant.
|
|
||||||
.map(|bytes| unsafe { std::str::from_utf8_unchecked(bytes) })
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user