Skip to content

Commit

Permalink
Merge pull request #30 from axodotdev/update-api
Browse files Browse the repository at this point in the history
make api consistent for release
  • Loading branch information
ashleygwilliams authored Apr 6, 2023
2 parents e33448f + e815797 commit 53bc6fe
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 55 deletions.
3 changes: 2 additions & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub type Result<T> = std::result::Result<T, AxoassetError>;
/// 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)]
Expand Down Expand Up @@ -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 {
Expand Down
3 changes: 1 addition & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Asset> {
#[cfg(feature = "remote")]
if is_remote(origin_path)? {
Expand Down
28 changes: 19 additions & 9 deletions src/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand 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<u8>) -> Self {
LocalAsset {
pub fn new(origin_path: &str, contents: Vec<u8>) -> Result<Self> {
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
Expand All @@ -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,
}),
Expand Down Expand Up @@ -161,18 +165,24 @@ impl LocalAsset {
})
}

fn filename(&self) -> Result<PathBuf> {
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<String> {
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<PathBuf> {
let filename = self.filename()?;
Ok(Path::new(dest_dir).join(filename))
Ok(Path::new(dest_dir).join(&self.filename))
}
}
87 changes: 44 additions & 43 deletions src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ 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
source: String,
contents: String,
}

/// A file's contents along with its display name
Expand All @@ -29,50 +31,43 @@ 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> {
Self::new(origin_path, String::new())
}

/// Create a new source file with the given name and contents.
pub fn new(name: &str, source: String) -> Self {
SourceFile {
pub fn new(origin_path: &str, contents: String) -> Result<Self> {
Ok(SourceFile {
inner: Arc::new(SourceFileInner {
name: name.to_owned(),
source,
filename: LocalAsset::filename(origin_path)?,
origin_path: origin_path.to_owned(),
contents,
}),
}
})
}

#[cfg(feature = "remote")]
/// SourceFile equivalent of [`crate::RemoteAsset::load`][]
pub async fn load_remote(origin_path: &str) -> Result<SourceFile> {
let source = crate::RemoteAsset::load_string(origin_path).await?;
let contents = crate::RemoteAsset::load_string(origin_path).await?;
Ok(SourceFile {
inner: Arc::new(SourceFileInner {
name: origin_path.to_owned(),
source,
filename: RemoteAsset::load(origin_path).await?.filename,
origin_path: origin_path.to_owned(),
contents,
}),
})
}

/// SourceFile equivalent of [`LocalAsset::load`][]
pub fn load_local<'a>(origin_path: impl Into<&'a Utf8Path>) -> Result<SourceFile> {
let origin_path = origin_path.into();
let source = LocalAsset::load_string(origin_path.as_str())?;
let contents = LocalAsset::load_string(origin_path.as_str())?;
Ok(SourceFile {
inner: Arc::new(SourceFileInner {
name: origin_path.to_string(),
source,
}),
})
}

/// SourceFile equivalent of [`Asset::load`][]
pub async fn load(origin_path: &str) -> Result<SourceFile> {
let source = Asset::load_string(origin_path).await?;
Ok(SourceFile {
inner: Arc::new(SourceFileInner {
name: origin_path.to_owned(),
source,
filename: LocalAsset::filename(origin_path.as_str())?,
origin_path: origin_path.to_string(),
contents,
}),
})
}
Expand All @@ -83,7 +78,7 @@ impl SourceFile {
let json = serde_json::from_str(self.source()).map_err(|details| {
let span = self.span_for_line_col(details.line(), details.column());
AxoassetError::Json {
source: self.clone(),
contents: self.clone(),
span,
details,
}
Expand All @@ -94,26 +89,32 @@ impl SourceFile {
/// Try to deserialize the contents of the SourceFile as toml
#[cfg(feature = "toml-serde")]
pub fn deserialize_toml<'a, T: serde::Deserialize<'a>>(&'a self) -> Result<T> {
let toml = toml::from_str(self.source()).map_err(|details| {
let toml = toml::from_str(self.contents()).map_err(|details| {
let span = details
.line_col()
.and_then(|(line, col)| self.span_for_line_col(line, col));
AxoassetError::Toml {
source: self.clone(),
contents: self.clone(),
span,
details,
}
})?;
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 source(&self) -> &str {
&self.inner.source
pub fn contents(&self) -> &str {
&self.inner.contents
}

/// Gets a proper [`SourceSpan`] from a line-and-column representation
Expand All @@ -125,7 +126,7 @@ impl SourceFile {
/// This is a pretty heavy-weight process, we have to basically linearly scan the source
/// for this position!
pub fn span_for_line_col(&self, line: usize, col: usize) -> Option<SourceSpan> {
let src = self.source();
let src = self.contents();
let src_line = src.lines().nth(line.checked_sub(1)?)?;
if col > src_line.len() {
return None;
Expand All @@ -149,11 +150,11 @@ impl SourceCode for SourceFile {
context_lines_before: usize,
context_lines_after: usize,
) -> std::result::Result<Box<dyn miette::SpanContents<'a> + 'a>, miette::MietteError> {
let contents = self
.source()
.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(),
Expand All @@ -166,8 +167,8 @@ 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("source", &self.source())
.field("origin_path", &self.origin_path())
.field("contents", &self.contents())
.finish()
}
}

0 comments on commit 53bc6fe

Please sign in to comment.