Compare commits
No commits in common. "main" and "v3.2.0" have entirely different histories.
6 changed files with 14 additions and 24 deletions
|
@ -7,12 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
## [4.0.0](https://git.kemitix.net/kemitix/kxio/compare/v3.2.0...v4.0.0) - 2024-12-15
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- *(fs)* [**breaking**] Reader now supports non-utf8 files
|
|
||||||
|
|
||||||
## [3.2.0](https://git.kemitix.net/kemitix/kxio/compare/v3.1.0...v3.2.0) - 2024-12-12
|
## [3.2.0](https://git.kemitix.net/kemitix/kxio/compare/v3.1.0...v3.2.0) - 2024-12-12
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "kxio"
|
name = "kxio"
|
||||||
version = "4.0.0"
|
version = "3.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["Paul Campbell <pcampbell@kemitix.net>"]
|
authors = ["Paul Campbell <pcampbell@kemitix.net>"]
|
||||||
description = "Provides injectable Filesystem and Network resources to make code more testable"
|
description = "Provides injectable Filesystem and Network resources to make code more testable"
|
||||||
|
|
|
@ -89,7 +89,7 @@ fn read_file(file: &FileHandle) -> kxio::Result<()> {
|
||||||
|
|
||||||
// Creates a `Reader` which loaded the file into memory.
|
// Creates a `Reader` which loaded the file into memory.
|
||||||
let reader: kxio::fs::Reader = file.reader()?;
|
let reader: kxio::fs::Reader = file.reader()?;
|
||||||
let contents: &str = reader.as_str()?;
|
let contents: &str = reader.as_str();
|
||||||
println!("{contents}");
|
println!("{contents}");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -106,7 +106,6 @@ fn delete_file(file: FileHandle) -> kxio::Result<()> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use assert2::let_assert;
|
|
||||||
use http::StatusCode;
|
use http::StatusCode;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -147,7 +146,7 @@ mod tests {
|
||||||
// Read the file
|
// Read the file
|
||||||
let file = fs.file(&file_path);
|
let file = fs.file(&file_path);
|
||||||
let reader = file.reader().expect("reader");
|
let reader = file.reader().expect("reader");
|
||||||
let_assert!(Ok(contents) = reader.as_str());
|
let contents = reader.as_str();
|
||||||
|
|
||||||
assert_eq!(contents, "contents");
|
assert_eq!(contents, "contents");
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,13 @@ use super::Error;
|
||||||
/// A reader for a file.
|
/// A reader for a file.
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
||||||
pub struct Reader {
|
pub struct Reader {
|
||||||
contents: Vec<u8>,
|
contents: String,
|
||||||
}
|
}
|
||||||
impl Reader {
|
impl Reader {
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
pub(super) fn new(path: &Path) -> Result<Self> {
|
pub(super) fn new(path: &Path) -> Result<Self> {
|
||||||
tracing::debug!("std::fs::read_to_string");
|
tracing::debug!("std::fs::read_to_string");
|
||||||
let contents = std::fs::read(path).map_err(Error::Io)?;
|
let contents = std::fs::read_to_string(path).map_err(Error::Io)?;
|
||||||
tracing::debug!(len = contents.len(), "contents");
|
tracing::debug!(len = contents.len(), "contents");
|
||||||
Ok(Self { contents })
|
Ok(Self { contents })
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,8 @@ impl Reader {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn as_str(&self) -> Result<&str> {
|
pub fn as_str(&self) -> &str {
|
||||||
std::str::from_utf8(&self.contents).map_err(Error::Utf8Error)
|
&self.contents
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over the lines in the file.
|
/// Returns an iterator over the lines in the file.
|
||||||
|
@ -49,8 +49,8 @@ impl Reader {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn lines(&self) -> Result<Lines<'_>> {
|
pub fn lines(&self) -> Lines<'_> {
|
||||||
self.as_str().map(|s| s.lines())
|
self.contents.lines()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the contents of the file as bytes.
|
/// Returns the contents of the file as bytes.
|
||||||
|
@ -67,11 +67,11 @@ impl Reader {
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn bytes(&self) -> &[u8] {
|
pub fn bytes(&self) -> &[u8] {
|
||||||
&self.contents
|
self.contents.as_bytes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Display for Reader {
|
impl Display for Reader {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "{}", self.as_str().map_err(|_| std::fmt::Error)?)
|
write!(f, "{}", self.contents)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,6 @@ pub enum Error {
|
||||||
|
|
||||||
IoString(String),
|
IoString(String),
|
||||||
|
|
||||||
Utf8Error(std::str::Utf8Error),
|
|
||||||
|
|
||||||
#[display("Path access attempted outside of base ({base:?}): {path:?}")]
|
#[display("Path access attempted outside of base ({base:?}): {path:?}")]
|
||||||
PathTraversal {
|
PathTraversal {
|
||||||
base: PathBuf,
|
base: PathBuf,
|
||||||
|
@ -36,7 +34,6 @@ impl Clone for Error {
|
||||||
match self {
|
match self {
|
||||||
Error::Io(err) => Error::IoString(err.to_string()),
|
Error::Io(err) => Error::IoString(err.to_string()),
|
||||||
Error::IoString(err) => Error::IoString(err.clone()),
|
Error::IoString(err) => Error::IoString(err.clone()),
|
||||||
Error::Utf8Error(err) => Error::Utf8Error(*err),
|
|
||||||
Error::PathTraversal { base, path } => Error::PathTraversal {
|
Error::PathTraversal { base, path } => Error::PathTraversal {
|
||||||
base: base.clone(),
|
base: base.clone(),
|
||||||
path: path.clone(),
|
path: path.clone(),
|
||||||
|
|
|
@ -723,7 +723,7 @@ mod file {
|
||||||
file.write(&contents).expect("write");
|
file.write(&contents).expect("write");
|
||||||
|
|
||||||
let reader = file.reader().expect("reader");
|
let reader = file.reader().expect("reader");
|
||||||
let string = reader.as_str().expect("as_str");
|
let string = reader.as_str();
|
||||||
|
|
||||||
assert_eq!(string, contents);
|
assert_eq!(string, contents);
|
||||||
}
|
}
|
||||||
|
@ -743,7 +743,7 @@ mod file {
|
||||||
file.write(&contents).expect("write");
|
file.write(&contents).expect("write");
|
||||||
|
|
||||||
let reader = file.reader().expect("reader");
|
let reader = file.reader().expect("reader");
|
||||||
let lines = reader.lines().expect("lines").collect::<Vec<_>>();
|
let lines = reader.lines().collect::<Vec<_>>();
|
||||||
|
|
||||||
assert_eq!(lines, vec!["line 1", "line 2", &line3]);
|
assert_eq!(lines, vec!["line 1", "line 2", &line3]);
|
||||||
}
|
}
|
||||||
|
@ -759,7 +759,7 @@ mod file {
|
||||||
file.write("line 1\nline 2").expect("write");
|
file.write("line 1\nline 2").expect("write");
|
||||||
|
|
||||||
let reader = file.reader().expect("reader");
|
let reader = file.reader().expect("reader");
|
||||||
let lines = reader.lines().expect("lines").collect::<Vec<_>>();
|
let lines = reader.lines().collect::<Vec<_>>();
|
||||||
|
|
||||||
assert_eq!(lines, vec!["line 1", "line 2"]);
|
assert_eq!(lines, vec!["line 1", "line 2"]);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue