Make helix_core::Uri cheap to clone
We clone this type very often in LSP pickers, for example diagnostics and symbols. We can use a single Arc in many cases to avoid the unnecessary clones.
This commit is contained in:
parent
48e9357788
commit
da2b0a7484
2 changed files with 17 additions and 26 deletions
|
@ -1,15 +1,18 @@
|
||||||
use std::{
|
use std::{
|
||||||
fmt,
|
fmt,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A generic pointer to a file location.
|
/// A generic pointer to a file location.
|
||||||
///
|
///
|
||||||
/// Currently this type only supports paths to local files.
|
/// Currently this type only supports paths to local files.
|
||||||
|
///
|
||||||
|
/// Cloning this type is cheap: the internal representation uses an Arc.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum Uri {
|
pub enum Uri {
|
||||||
File(PathBuf),
|
File(Arc<Path>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Uri {
|
impl Uri {
|
||||||
|
@ -26,27 +29,11 @@ impl Uri {
|
||||||
Self::File(path) => Some(path),
|
Self::File(path) => Some(path),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_path_buf(self) -> Option<PathBuf> {
|
|
||||||
match self {
|
|
||||||
Self::File(path) => Some(path),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PathBuf> for Uri {
|
impl From<PathBuf> for Uri {
|
||||||
fn from(path: PathBuf) -> Self {
|
fn from(path: PathBuf) -> Self {
|
||||||
Self::File(path)
|
Self::File(path.into())
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Uri> for PathBuf {
|
|
||||||
type Error = ();
|
|
||||||
|
|
||||||
fn try_from(uri: Uri) -> Result<Self, Self::Error> {
|
|
||||||
match uri {
|
|
||||||
Uri::File(path) => Ok(path),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +80,7 @@ impl std::error::Error for UrlConversionError {}
|
||||||
fn convert_url_to_uri(url: &url::Url) -> Result<Uri, UrlConversionErrorKind> {
|
fn convert_url_to_uri(url: &url::Url) -> Result<Uri, UrlConversionErrorKind> {
|
||||||
if url.scheme() == "file" {
|
if url.scheme() == "file" {
|
||||||
url.to_file_path()
|
url.to_file_path()
|
||||||
.map(|path| Uri::File(helix_stdx::path::normalize(path)))
|
.map(|path| Uri::File(helix_stdx::path::normalize(path).into()))
|
||||||
.map_err(|_| UrlConversionErrorKind::UnableToConvert)
|
.map_err(|_| UrlConversionErrorKind::UnableToConvert)
|
||||||
} else {
|
} else {
|
||||||
Err(UrlConversionErrorKind::UnsupportedScheme)
|
Err(UrlConversionErrorKind::UnsupportedScheme)
|
||||||
|
|
|
@ -243,7 +243,7 @@ impl Editor {
|
||||||
match op {
|
match op {
|
||||||
ResourceOp::Create(op) => {
|
ResourceOp::Create(op) => {
|
||||||
let uri = Uri::try_from(&op.uri)?;
|
let uri = Uri::try_from(&op.uri)?;
|
||||||
let path = uri.as_path_buf().expect("URIs are valid paths");
|
let path = uri.as_path().expect("URIs are valid paths");
|
||||||
let ignore_if_exists = op.options.as_ref().map_or(false, |options| {
|
let ignore_if_exists = op.options.as_ref().map_or(false, |options| {
|
||||||
!options.overwrite.unwrap_or(false) && options.ignore_if_exists.unwrap_or(false)
|
!options.overwrite.unwrap_or(false) && options.ignore_if_exists.unwrap_or(false)
|
||||||
});
|
});
|
||||||
|
@ -255,13 +255,15 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::write(&path, [])?;
|
fs::write(path, [])?;
|
||||||
self.language_servers.file_event_handler.file_changed(path);
|
self.language_servers
|
||||||
|
.file_event_handler
|
||||||
|
.file_changed(path.to_path_buf());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResourceOp::Delete(op) => {
|
ResourceOp::Delete(op) => {
|
||||||
let uri = Uri::try_from(&op.uri)?;
|
let uri = Uri::try_from(&op.uri)?;
|
||||||
let path = uri.as_path_buf().expect("URIs are valid paths");
|
let path = uri.as_path().expect("URIs are valid paths");
|
||||||
if path.is_dir() {
|
if path.is_dir() {
|
||||||
let recursive = op
|
let recursive = op
|
||||||
.options
|
.options
|
||||||
|
@ -270,11 +272,13 @@ impl Editor {
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
|
|
||||||
if recursive {
|
if recursive {
|
||||||
fs::remove_dir_all(&path)?
|
fs::remove_dir_all(path)?
|
||||||
} else {
|
} else {
|
||||||
fs::remove_dir(&path)?
|
fs::remove_dir(path)?
|
||||||
}
|
}
|
||||||
self.language_servers.file_event_handler.file_changed(path);
|
self.language_servers
|
||||||
|
.file_event_handler
|
||||||
|
.file_changed(path.to_path_buf());
|
||||||
} else if path.is_file() {
|
} else if path.is_file() {
|
||||||
fs::remove_file(path)?;
|
fs::remove_file(path)?;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue