diff --git a/src/error.rs b/src/error.rs index 0f019e2..75823a0 100644 --- a/src/error.rs +++ b/src/error.rs @@ -6,7 +6,7 @@ pub type Result = std::result::Result; /// The set of errors that can occur when axoasset is used #[derive(Debug, Error, Diagnostic)] pub enum AxoassetError { - /// This error is a transparent error forwarded from the reqwest library. + /// This error is a transparent error forwarded from the reqwe. /// Long-term the goal is to eliminate this error variant in favor of more /// specific error variants. #[error(transparent)] @@ -256,6 +256,7 @@ pub enum AxoassetError { /// The problematic path path: std::path::PathBuf, }, + #[error("Failed to find {desired_filename} in an ancestor of {start_dir}")] /// This error indicates we failed to find the desired file in an ancestor of the search dir. SearchFailed { diff --git a/src/lib.rs b/src/lib.rs index c2b84fd..b664c79 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,13 +47,12 @@ impl Asset { origin_path: origin_path.to_string(), }) } else { - Ok(Asset::LocalAsset(LocalAsset::new(origin_path, contents))) + Ok(Asset::LocalAsset(LocalAsset::new(origin_path, contents)?)) } } /// Loads an asset, either locally or remotely, returning an Asset enum /// variant containing the contents as bytes. - pub async fn load(origin_path: &str) -> Result { #[cfg(feature = "remote")] if is_remote(origin_path)? { diff --git a/src/local.rs b/src/local.rs index 2dbed2c..741a7f9 100644 --- a/src/local.rs +++ b/src/local.rs @@ -8,6 +8,8 @@ use crate::error::*; /// A local asset contains a path on the local filesystem and its contents #[derive(Debug)] pub struct LocalAsset { + /// The computed filename from origin_path + pub filename: String, /// A string representing a path on the local filesystem, where the asset /// originated. For a new asset, this will be the path you want the asset /// to be written to. This path is how the filename is determined for all @@ -20,11 +22,12 @@ pub struct LocalAsset { impl LocalAsset { /// A new asset is created with a path on the local filesystem and a /// vector of bytes representing its contents - pub fn new(origin_path: &str, contents: Vec) -> Self { - LocalAsset { + pub fn new(origin_path: &str, contents: Vec) -> Result { + Ok(LocalAsset { + filename: LocalAsset::filename(origin_path)?, origin_path: origin_path.to_string(), contents, - } + }) } /// Loads an asset from a path on the local filesystem, returning a @@ -33,6 +36,7 @@ impl LocalAsset { match Path::new(origin_path).try_exists() { Ok(_) => match fs::read(origin_path) { Ok(contents) => Ok(LocalAsset { + filename: LocalAsset::filename(origin_path)?, origin_path: origin_path.to_string(), contents, }), @@ -161,18 +165,24 @@ impl LocalAsset { }) } - fn filename(&self) -> Result { - if let Some(filename) = Path::new(&self.origin_path).file_name() { - Ok(filename.into()) + /// Computes filename from provided origin path + pub fn filename(origin_path: &str) -> Result { + if let Some(filename) = Path::new(origin_path).file_name() { + if let Some(filename) = filename.to_str() { + Ok(filename.to_string()) + } else { + Err(AxoassetError::LocalAssetMissingFilename { + origin_path: origin_path.to_string(), + }) + } } else { Err(AxoassetError::LocalAssetMissingFilename { - origin_path: self.origin_path.to_string(), + origin_path: origin_path.to_string(), }) } } fn dest_path(&self, dest_dir: &str) -> Result { - let filename = self.filename()?; - Ok(Path::new(dest_dir).join(filename)) + Ok(Path::new(dest_dir).join(&self.filename)) } } diff --git a/src/source.rs b/src/source.rs index c576a32..9db0010 100644 --- a/src/source.rs +++ b/src/source.rs @@ -4,13 +4,15 @@ use std::sync::Arc; use camino::Utf8Path; use miette::{MietteSpanContents, SourceCode, SourceSpan}; -use crate::{error::*, Asset, LocalAsset}; +use crate::{error::*, LocalAsset, RemoteAsset}; /// The inner contents of a [`SourceFile`][]. #[derive(Eq, PartialEq)] struct SourceFileInner { - /// "Name" of the file (this can be a path if you want) - name: String, + /// "Name" of the file + filename: String, + /// Origin path of the file + origin_path: String, /// Contents of the file contents: String, } @@ -29,17 +31,19 @@ pub struct SourceFile { impl SourceFile { /// Create an empty SourceFile with the given name - pub fn new_empty(name: &str) -> Self { - Self::new(name, String::new()) + pub fn new_empty(origin_path: &str) -> Result { + Self::new(origin_path, String::new()) } + /// Create a new source file with the given name and contents. - pub fn new(name: &str, contents: String) -> Self { - SourceFile { + pub fn new(origin_path: &str, contents: String) -> Result { + Ok(SourceFile { inner: Arc::new(SourceFileInner { - name: name.to_owned(), + filename: LocalAsset::filename(origin_path)?, + origin_path: origin_path.to_owned(), contents, }), - } + }) } #[cfg(feature = "remote")] @@ -48,7 +52,8 @@ impl SourceFile { let contents = crate::RemoteAsset::load_string(origin_path).await?; Ok(SourceFile { inner: Arc::new(SourceFileInner { - name: origin_path.to_owned(), + filename: RemoteAsset::load(origin_path).await?.filename, + origin_path: origin_path.to_owned(), contents, }), }) @@ -60,18 +65,8 @@ impl SourceFile { let contents = LocalAsset::load_string(origin_path.as_str())?; Ok(SourceFile { inner: Arc::new(SourceFileInner { - name: origin_path.to_string(), - contents, - }), - }) - } - - /// SourceFile equivalent of [`Asset::load`][] - pub async fn load(origin_path: &str) -> Result { - let contents = Asset::load_string(origin_path).await?; - Ok(SourceFile { - inner: Arc::new(SourceFileInner { - name: origin_path.to_owned(), + filename: LocalAsset::filename(origin_path.as_str())?, + origin_path: origin_path.to_string(), contents, }), }) @@ -107,10 +102,16 @@ impl SourceFile { Ok(toml) } - /// Get the name of a SourceFile - pub fn name(&self) -> &str { - &self.inner.name + /// Get the filename of a SourceFile + pub fn filename(&self) -> &str { + &self.inner.filename } + + /// Get the origin_path of a SourceFile + pub fn origin_path(&self) -> &str { + &self.inner.origin_path + } + /// Get the contents of a SourceFile pub fn contents(&self) -> &str { &self.inner.contents @@ -149,11 +150,11 @@ impl SourceCode for SourceFile { context_lines_before: usize, context_lines_after: usize, ) -> std::result::Result + 'a>, miette::MietteError> { - let contents = self - .contents() - .read_span(span, context_lines_before, context_lines_after)?; + let contents = + self.contents() + .read_span(span, context_lines_before, context_lines_after)?; Ok(Box::new(MietteSpanContents::new_named( - self.name().to_owned(), + self.origin_path().to_owned(), contents.data(), *contents.span(), contents.line(), @@ -166,7 +167,7 @@ impl SourceCode for SourceFile { impl Debug for SourceFile { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("SourceFile") - .field("name", &self.name()) + .field("origin_path", &self.origin_path()) .field("contents", &self.contents()) .finish() }