mirror of
https://github.com/sxyazi/yazi.git
synced 2024-12-26 02:04:42 +03:00
perf: using usize
instead of *const OsStr
reduces memory usage (#1839)
This commit is contained in:
parent
96bcd820b8
commit
ef1a31a274
6
.github/workflows/check.yml
vendored
6
.github/workflows/check.yml
vendored
@ -19,6 +19,9 @@ jobs:
|
|||||||
|
|
||||||
- name: Setup Rust cache
|
- name: Setup Rust cache
|
||||||
uses: Swatinem/rust-cache@v2
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
prefix-key: rust
|
||||||
|
shared-key: ubuntu-latest@debug
|
||||||
|
|
||||||
- name: Clippy
|
- name: Clippy
|
||||||
run: cargo clippy --all
|
run: cargo clippy --all
|
||||||
@ -36,6 +39,9 @@ jobs:
|
|||||||
|
|
||||||
- name: Setup Rust cache
|
- name: Setup Rust cache
|
||||||
uses: Swatinem/rust-cache@v2
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
prefix-key: rust
|
||||||
|
shared-key: ubuntu-latest@debug
|
||||||
|
|
||||||
- name: Rustfmt
|
- name: Rustfmt
|
||||||
run: cargo +nightly fmt --all -- --check
|
run: cargo +nightly fmt --all -- --check
|
||||||
|
37
.github/workflows/draft.yml
vendored
37
.github/workflows/draft.yml
vendored
@ -32,6 +32,15 @@ jobs:
|
|||||||
echo "JEMALLOC_SYS_WITH_LG_PAGE=16" >> $GITHUB_ENV
|
echo "JEMALLOC_SYS_WITH_LG_PAGE=16" >> $GITHUB_ENV
|
||||||
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=/usr/bin/aarch64-linux-gnu-gcc" >> $GITHUB_ENV
|
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=/usr/bin/aarch64-linux-gnu-gcc" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Setup Rust toolchain
|
||||||
|
run: rustup toolchain install stable --profile minimal --target ${{ matrix.target }}
|
||||||
|
|
||||||
|
- name: Setup Rust cache
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
prefix-key: rust
|
||||||
|
shared-key: ${{ matrix.target }}@release
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: ./scripts/build.sh ${{ matrix.target }}
|
run: ./scripts/build.sh ${{ matrix.target }}
|
||||||
|
|
||||||
@ -54,10 +63,13 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Rust toolchain
|
- name: Setup Rust toolchain
|
||||||
run: rustup toolchain install stable --profile minimal
|
run: rustup toolchain install stable --profile minimal --target ${{ matrix.target }}
|
||||||
|
|
||||||
- name: Add target
|
- name: Setup Rust cache
|
||||||
run: rustup target add ${{ matrix.target }}
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
prefix-key: rust
|
||||||
|
shared-key: ${{ matrix.target }}@release
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
env:
|
env:
|
||||||
@ -98,6 +110,15 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Add musl target
|
||||||
|
run: rustup target add ${{ matrix.target }}
|
||||||
|
|
||||||
|
- name: Setup Rust cache
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
prefix-key: rust
|
||||||
|
shared-key: ${{ matrix.target }}@release
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: ./scripts/build.sh ${{ matrix.target }}
|
run: ./scripts/build.sh ${{ matrix.target }}
|
||||||
|
|
||||||
@ -117,10 +138,16 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Build snap
|
- name: Setup Rust cache
|
||||||
uses: snapcore/action-build@v1
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
prefix-key: rust
|
||||||
|
shared-key: ${{ matrix.target }}@release
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
|
uses: snapcore/action-build@v1
|
||||||
|
|
||||||
|
- name: Rename snap
|
||||||
run: mv yazi_*.snap yazi-${{ matrix.target }}.snap
|
run: mv yazi_*.snap yazi-${{ matrix.target }}.snap
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
|
3
.github/workflows/test.yml
vendored
3
.github/workflows/test.yml
vendored
@ -23,6 +23,9 @@ jobs:
|
|||||||
|
|
||||||
- name: Setup Rust cache
|
- name: Setup Rust cache
|
||||||
uses: Swatinem/rust-cache@v2
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
prefix-key: rust
|
||||||
|
shared-key: ${{ matrix.os }}@debug
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cargo build --verbose
|
run: cargo build --verbose
|
||||||
|
46
README.md
46
README.md
@ -45,25 +45,39 @@ https://github.com/sxyazi/yazi/assets/17523360/92ff23fa-0cd5-4f04-b387-894c12265
|
|||||||
## Image Preview
|
## Image Preview
|
||||||
|
|
||||||
| Platform | Protocol | Support |
|
| Platform | Protocol | Support |
|
||||||
| --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
|
| --------------------------------------------------------------------------- | -------------------------------------- | --------------------------------------------- |
|
||||||
| [kitty](https://github.com/kovidgoyal/kitty) | [Kitty unicode placeholders](https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders) | ✅ Built-in |
|
| [kitty](https://github.com/kovidgoyal/kitty) | [Kitty unicode placeholders][kgp] | ✅ Built-in |
|
||||||
| [Konsole](https://invent.kde.org/utilities/konsole) | [Kitty old protocol](https://github.com/sxyazi/yazi/blob/main/yazi-adapter/src/kgp_old.rs) | ✅ Built-in |
|
| [iTerm2](https://iterm2.com) | [Inline images protocol][iip] | ✅ Built-in |
|
||||||
| [iTerm2](https://iterm2.com) | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
|
| [WezTerm](https://github.com/wez/wezterm) | [Inline images protocol][iip] | ✅ Built-in |
|
||||||
| [WezTerm](https://github.com/wez/wezterm) | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
|
| [Konsole](https://invent.kde.org/utilities/konsole) | [Kitty old protocol][kgp-old] | ✅ Built-in |
|
||||||
| [Mintty](https://github.com/mintty/mintty) (Git Bash) | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
|
| [foot](https://codeberg.org/dnkl/foot) | [Sixel graphics format][sixel] | ✅ Built-in |
|
||||||
| [foot](https://codeberg.org/dnkl/foot) | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in |
|
| [Ghostty](https://mitchellh.com/ghostty) | [Kitty unicode placeholders][kgp] | ✅ Built-in |
|
||||||
| [Ghostty](https://mitchellh.com/ghostty) | [Kitty unicode placeholders](https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders) | ✅ Built-in |
|
| [Windows Terminal](https://github.com/microsoft/terminal) (>= v1.22.2702.0) | [Sixel graphics format][sixel] | ✅ Built-in |
|
||||||
| [Windows Terminal](https://github.com/microsoft/terminal) (>= v1.22.2702.0) | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in |
|
| [st with Sixel patch](https://github.com/bakkeby/st-flexipatch) | [Sixel graphics format][sixel] | ✅ Built-in |
|
||||||
| [Black Box](https://gitlab.gnome.org/raggesilver/blackbox) | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in |
|
| [Tabby](https://github.com/Eugeny/tabby) | [Inline images protocol][iip] | ✅ Built-in |
|
||||||
| [VSCode](https://github.com/microsoft/vscode) | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
|
| [VSCode](https://github.com/microsoft/vscode) | [Inline images protocol][iip] | ✅ Built-in |
|
||||||
| [Tabby](https://github.com/Eugeny/tabby) | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
|
| [Rio](https://github.com/raphamorim/rio) | [Inline images protocol][iip] | ❌ Rio doesn't correctly clear images (#1786) |
|
||||||
| [Hyper](https://github.com/vercel/hyper) | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
|
| [Mintty](https://github.com/mintty/mintty) (Git Bash) | [Inline images protocol][iip] | ✅ Built-in |
|
||||||
| [Rio](https://github.com/raphamorim/rio) | [Inline images protocol](https://iterm2.com/documentation-images.html) | ❌ Rio doesn't correctly clear images (#1786) |
|
| [Black Box](https://gitlab.gnome.org/raggesilver/blackbox) | [Sixel graphics format][sixel] | ✅ Built-in |
|
||||||
| X11 / Wayland | Window system protocol | ☑️ [Überzug++](https://github.com/jstkdng/ueberzugpp) required |
|
| [Hyper](https://github.com/vercel/hyper) | [Inline images protocol][iip] | ✅ Built-in |
|
||||||
| Fallback | [ASCII art (Unicode block)](https://en.wikipedia.org/wiki/ASCII_art) | ☑️ [Chafa](https://hpjansson.org/chafa/) required |
|
| X11 / Wayland | Window system protocol | ☑️ [Überzug++][ueberzug] required |
|
||||||
|
| Fallback | [ASCII art (Unicode block)][ascii-art] | ☑️ [Chafa][chafa] required |
|
||||||
|
|
||||||
See https://yazi-rs.github.io/docs/image-preview for details.
|
See https://yazi-rs.github.io/docs/image-preview for details.
|
||||||
|
|
||||||
|
<!-- Protocols -->
|
||||||
|
|
||||||
|
[kgp]: https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders
|
||||||
|
[kgp-old]: https://github.com/sxyazi/yazi/blob/main/yazi-adapter/src/kgp_old.rs
|
||||||
|
[iip]: https://iterm2.com/documentation-images.html
|
||||||
|
[sixel]: https://www.vt100.net/docs/vt3xx-gp/chapter14.html
|
||||||
|
[ascii-art]: https://en.wikipedia.org/wiki/ASCII_art
|
||||||
|
|
||||||
|
<!-- Dependencies -->
|
||||||
|
|
||||||
|
[ueberzug]: https://github.com/jstkdng/ueberzugpp
|
||||||
|
[chafa]: https://hpjansson.org/chafa/
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Yazi is MIT-licensed. For more information check the [LICENSE](LICENSE) file.
|
Yazi is MIT-licensed. For more information check the [LICENSE](LICENSE) file.
|
||||||
|
@ -5,13 +5,6 @@ export ARTIFACT_NAME="yazi-$1"
|
|||||||
export YAZI_GEN_COMPLETIONS=1
|
export YAZI_GEN_COMPLETIONS=1
|
||||||
export MACOSX_DEPLOYMENT_TARGET="10.11"
|
export MACOSX_DEPLOYMENT_TARGET="10.11"
|
||||||
|
|
||||||
# Setup Rust toolchain
|
|
||||||
if [[ "$1" == *-musl ]]; then
|
|
||||||
rustup target add "$1"
|
|
||||||
else
|
|
||||||
rustup toolchain install stable --profile minimal --target "$1"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build for the target
|
# Build for the target
|
||||||
cargo build --release --locked --target "$1"
|
cargo build --release --locked --target "$1"
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ impl Cha {
|
|||||||
reg.add_method("perm", |_, _me, ()| {
|
reg.add_method("perm", |_, _me, ()| {
|
||||||
Ok(
|
Ok(
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
Some(yazi_shared::fs::permissions(_me.perm, _me.is_dummy())),
|
Some(yazi_shared::fs::permissions(_me.mode, _me.is_dummy())),
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
None::<String>,
|
None::<String>,
|
||||||
)
|
)
|
||||||
@ -95,7 +95,7 @@ impl Cha {
|
|||||||
warn_deprecated(lua.named_registry_value::<RtRef>("rt")?.current());
|
warn_deprecated(lua.named_registry_value::<RtRef>("rt")?.current());
|
||||||
Ok(
|
Ok(
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
Some(yazi_shared::fs::permissions(_me.perm, _me.is_dummy())),
|
Some(yazi_shared::fs::permissions(_me.mode, _me.is_dummy())),
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
None::<String>,
|
None::<String>,
|
||||||
)
|
)
|
||||||
@ -131,7 +131,7 @@ impl Cha {
|
|||||||
ctime: parse_time(t.raw_get("ctime").ok())?,
|
ctime: parse_time(t.raw_get("ctime").ok())?,
|
||||||
mtime: parse_time(t.raw_get("mtime").ok())?,
|
mtime: parse_time(t.raw_get("mtime").ok())?,
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
perm: t.raw_get("permissions").unwrap_or_default(),
|
mode: t.raw_get("mode").unwrap_or_default(),
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
uid: t.raw_get("uid").unwrap_or_default(),
|
uid: t.raw_get("uid").unwrap_or_default(),
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
|
@ -26,7 +26,7 @@ pub struct Cha {
|
|||||||
pub ctime: Option<SystemTime>,
|
pub ctime: Option<SystemTime>,
|
||||||
pub mtime: Option<SystemTime>,
|
pub mtime: Option<SystemTime>,
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub perm: libc::mode_t,
|
pub mode: libc::mode_t,
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub uid: libc::uid_t,
|
pub uid: libc::uid_t,
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@ -57,7 +57,7 @@ impl From<Metadata> for Cha {
|
|||||||
mtime: m.modified().ok(),
|
mtime: m.modified().ok(),
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
perm: {
|
mode: {
|
||||||
use std::os::unix::prelude::PermissionsExt;
|
use std::os::unix::prelude::PermissionsExt;
|
||||||
m.permissions().mode() as _
|
m.permissions().mode() as _
|
||||||
},
|
},
|
||||||
@ -85,7 +85,7 @@ impl From<FileType> for Cha {
|
|||||||
let mut kind = ChaKind::DUMMY;
|
let mut kind = ChaKind::DUMMY;
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
let perm = {
|
let mode = {
|
||||||
use std::os::unix::fs::FileTypeExt;
|
use std::os::unix::fs::FileTypeExt;
|
||||||
if t.is_dir() {
|
if t.is_dir() {
|
||||||
kind |= ChaKind::DIR;
|
kind |= ChaKind::DIR;
|
||||||
@ -118,7 +118,7 @@ impl From<FileType> for Cha {
|
|||||||
Self {
|
Self {
|
||||||
kind,
|
kind,
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
perm,
|
mode,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,7 +173,7 @@ impl Cha {
|
|||||||
&& unix_either!(self.ctime == c.ctime, true)
|
&& unix_either!(self.ctime == c.ctime, true)
|
||||||
&& self.btime == c.btime
|
&& self.btime == c.btime
|
||||||
&& self.kind == c.kind
|
&& self.kind == c.kind
|
||||||
&& unix_either!(self.perm == c.perm, true)
|
&& unix_either!(self.mode == c.mode, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,27 +195,27 @@ impl Cha {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn is_block(&self) -> bool {
|
pub const fn is_block(&self) -> bool {
|
||||||
unix_either!(self.perm & libc::S_IFMT == libc::S_IFBLK, false)
|
unix_either!(self.mode & libc::S_IFMT == libc::S_IFBLK, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn is_char(&self) -> bool {
|
pub const fn is_char(&self) -> bool {
|
||||||
unix_either!(self.perm & libc::S_IFMT == libc::S_IFCHR, false)
|
unix_either!(self.mode & libc::S_IFMT == libc::S_IFCHR, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn is_fifo(&self) -> bool {
|
pub const fn is_fifo(&self) -> bool {
|
||||||
unix_either!(self.perm & libc::S_IFMT == libc::S_IFIFO, false)
|
unix_either!(self.mode & libc::S_IFMT == libc::S_IFIFO, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn is_sock(&self) -> bool {
|
pub const fn is_sock(&self) -> bool {
|
||||||
unix_either!(self.perm & libc::S_IFMT == libc::S_IFSOCK, false)
|
unix_either!(self.mode & libc::S_IFMT == libc::S_IFSOCK, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn is_exec(&self) -> bool { unix_either!(self.perm & libc::S_IXUSR != 0, false) }
|
pub const fn is_exec(&self) -> bool { unix_either!(self.mode & libc::S_IXUSR != 0, false) }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn is_sticky(&self) -> bool { unix_either!(self.perm & libc::S_ISVTX != 0, false) }
|
pub const fn is_sticky(&self) -> bool { unix_either!(self.mode & libc::S_ISVTX != 0, false) }
|
||||||
}
|
}
|
||||||
|
@ -258,14 +258,14 @@ async fn _copy_with_progress(from: PathBuf, to: PathBuf, cha: Cha) -> io::Result
|
|||||||
tokio::task::spawn_blocking(move || {
|
tokio::task::spawn_blocking(move || {
|
||||||
let mut reader = std::fs::File::open(from)?;
|
let mut reader = std::fs::File::open(from)?;
|
||||||
let mut writer = std::fs::OpenOptions::new()
|
let mut writer = std::fs::OpenOptions::new()
|
||||||
.mode(cha.perm as u32)
|
.mode(cha.mode as u32)
|
||||||
.write(true)
|
.write(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
.truncate(true)
|
.truncate(true)
|
||||||
.open(to)?;
|
.open(to)?;
|
||||||
|
|
||||||
let written = std::io::copy(&mut reader, &mut writer)?;
|
let written = std::io::copy(&mut reader, &mut writer)?;
|
||||||
unsafe { libc::fchmod(writer.as_raw_fd(), cha.perm) };
|
unsafe { libc::fchmod(writer.as_raw_fd(), cha.mode) };
|
||||||
writer.set_times(ft).ok();
|
writer.set_times(ft).ok();
|
||||||
|
|
||||||
Ok(written)
|
Ok(written)
|
||||||
|
@ -2,31 +2,17 @@ use std::{cmp, ffi::OsStr, fmt::{self, Debug, Formatter}, hash::{Hash, Hasher},
|
|||||||
|
|
||||||
use super::{Urn, UrnBuf};
|
use super::{Urn, UrnBuf};
|
||||||
|
|
||||||
|
#[derive(Clone, Default)]
|
||||||
pub struct Loc {
|
pub struct Loc {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
urn: *const OsStr,
|
urn: usize,
|
||||||
name: *const OsStr,
|
name: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for Loc {}
|
unsafe impl Send for Loc {}
|
||||||
|
|
||||||
unsafe impl Sync for Loc {}
|
unsafe impl Sync for Loc {}
|
||||||
|
|
||||||
impl Default for Loc {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self { path: PathBuf::default(), urn: OsStr::new(""), name: OsStr::new("") }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clone for Loc {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
let path = self.path.clone();
|
|
||||||
let name = path.file_name().unwrap_or(OsStr::new("")) as *const OsStr;
|
|
||||||
let urn = if self.urn() == self.name() { name } else { self.twin_urn(&path) };
|
|
||||||
Self { path, urn, name }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for Loc {
|
impl Deref for Loc {
|
||||||
type Target = PathBuf;
|
type Target = PathBuf;
|
||||||
|
|
||||||
@ -63,56 +49,58 @@ impl Debug for Loc {
|
|||||||
|
|
||||||
impl Loc {
|
impl Loc {
|
||||||
pub fn new(path: PathBuf) -> Self {
|
pub fn new(path: PathBuf) -> Self {
|
||||||
let urn = path.file_name().unwrap_or(OsStr::new("")) as *const OsStr;
|
let name = path.file_name().map_or(0, |s| s.len());
|
||||||
Self { path, urn, name: urn }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from(base: &Path, path: PathBuf) -> Self {
|
|
||||||
let urn = path.strip_prefix(base).unwrap_or(&path).as_os_str() as *const OsStr;
|
|
||||||
let name = path.file_name().unwrap_or(OsStr::new("")) as *const OsStr;
|
|
||||||
Self { path, urn, name }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn base(&self) -> &Path {
|
|
||||||
let mut it = self.path.components();
|
|
||||||
for _ in 0..self.urn().components().count() {
|
|
||||||
it.next_back().unwrap();
|
|
||||||
}
|
|
||||||
it.as_path()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rebase(&self, parent: &Path) -> Self {
|
|
||||||
debug_assert!(self.urn() == self.name());
|
|
||||||
|
|
||||||
let path = parent.join(self.name());
|
|
||||||
let name = path.file_name().unwrap_or(OsStr::new("")) as *const OsStr;
|
|
||||||
Self { path, urn: name, name }
|
Self { path, urn: name, name }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
pub fn from(base: &Path, path: PathBuf) -> Self {
|
||||||
fn twin_urn<'a>(&self, new: &'a Path) -> &'a OsStr {
|
let urn = path.strip_prefix(base).unwrap_or(&path).as_os_str().len();
|
||||||
let total = new.components().count();
|
let name = path.file_name().map_or(0, |s| s.len());
|
||||||
let take = self.urn().components().count();
|
Self { path, urn, name }
|
||||||
|
|
||||||
let mut it = new.components();
|
|
||||||
for _ in 0..total - take {
|
|
||||||
it.next().unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
it.as_path().as_os_str()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Loc {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn urn(&self) -> &Urn { Urn::new(unsafe { &*self.urn }) }
|
pub fn urn(&self) -> &Urn {
|
||||||
|
Urn::new(unsafe {
|
||||||
|
OsStr::from_encoded_bytes_unchecked(
|
||||||
|
self.bytes().get_unchecked(self.bytes().len() - self.urn..),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn urn_owned(&self) -> UrnBuf { self.urn().to_owned() }
|
pub fn urn_owned(&self) -> UrnBuf { self.urn().to_owned() }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn name(&self) -> &OsStr { unsafe { &*self.name } }
|
pub fn name(&self) -> &OsStr {
|
||||||
|
unsafe {
|
||||||
|
OsStr::from_encoded_bytes_unchecked(
|
||||||
|
self.bytes().get_unchecked(self.bytes().len() - self.name..),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn base(&self) -> &Path {
|
||||||
|
Path::new(unsafe {
|
||||||
|
OsStr::from_encoded_bytes_unchecked(
|
||||||
|
self.bytes().get_unchecked(..self.bytes().len() - self.urn),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn rebase(&self, parent: &Path) -> Self {
|
||||||
|
debug_assert!(self.urn == self.name);
|
||||||
|
let path = parent.join(self.name());
|
||||||
|
|
||||||
|
debug_assert!(path.file_name().is_some_and(|s| s.len() == self.name));
|
||||||
|
Self { path, urn: self.name, name: self.name }
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_path(self) -> PathBuf { self.path }
|
pub fn into_path(self) -> PathBuf { self.path }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn bytes(&self) -> &[u8] { self.path.as_os_str().as_encoded_bytes() }
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user