diff --git a/examples/get.rs b/examples/get.rs index 1ef946d..4a6ed57 100644 --- a/examples/get.rs +++ b/examples/get.rs @@ -10,6 +10,8 @@ /// `example-readme.md` in the current directory. use std::path::Path; +use kxio::fs::FileHandle; + #[tokio::main] async fn main() -> kxio::Result<()> { // Create a `Net` object for making real network requests. @@ -27,7 +29,7 @@ async fn main() -> kxio::Result<()> { let file_path = fs.base().join("example-readme.md"); // Create a generic handle for the file. This doesn't open the file, and always succeeds. - let path: kxio::fs::PathReal = fs.path(&file_path); + let path = fs.path(&file_path); // Other options are; // `fs.file(&file_path)` - for a file @@ -42,8 +44,9 @@ async fn main() -> kxio::Result<()> { // Passes a reference to the `fs` and `net` objects for use by your program. // Your programs should not know whether they are handling a mock or the real thing. // Any file or network access should be made using these handlers to be properly testable. - download_and_save_to_file(url, &file_path, &fs, &net).await?; - delete_file(&file_path, &fs)?; + let file = download_and_save_to_file(url, &file_path, &fs, &net).await?; + read_file(&file)?; + delete_file(file)?; Ok(()) } @@ -52,27 +55,20 @@ async fn main() -> kxio::Result<()> { async fn download_and_save_to_file( url: &str, file_path: &Path, - // The file system abstraction + // The filesystem abstraction fs: &kxio::fs::FileSystem, // The network abstraction net: &kxio::net::Net, -) -> kxio::Result<()> { +) -> kxio::Result { println!("fetching: {url}"); - // Rather than calling `.build().send()?` on the request, pass it to the `net` - // This allows the `net` to either make the network request as normal, or, if we are - // under test, to handle the request as the test dictates. - // NOTE: if the `.build().send()` is called on the `request` then that WILL result in - // a real network request being made, even under test conditions. Only ever use the - // `net.send(...)` function to keep your code testable. - // `kxio::net::Response` is an alias for `reqwest::Response`. - let response: kxio::net::Response = net.get(url).header("key", "value").send().await?; - // Other options: - // Uses the network abstraction to create a perfectly normal `reqwest::ResponseBuilder`. - // `kxio::net::RequestBuilder` is an alias. - // let response = net.send(net.client().get(url)).await?; + // Makes a GET request that can be mocked in a test + let response: reqwest::Response = net.get(url).header("key", "value").send().await?; + + // As you can see, we use [reqwest] under the hood. // - // let response = net.post(url).body("{}").send().await?; + // If you need to create a more complex request than the [kxio] fluent API allows, you + // can create a request using [reqwest] and pass it to [net.send(request)]. let body = response.text().await?; println!("fetched {} bytes", body.bytes().len()); @@ -83,15 +79,13 @@ async fn download_and_save_to_file( // Writes the body to the file. file.write(body)?; - Ok(()) + Ok(file) } -/// An function that uses a `FileSystem` object to interact with the outside world. -fn delete_file(file_path: &Path, fs: &kxio::fs::FileSystem) -> kxio::Result<()> { - println!("reading file: {}", file_path.display()); +/// A function that reads the file contents +fn read_file(file: &FileHandle) -> kxio::Result<()> { + println!("reading file: {file}"); - // Uses the file system abstraction to create a handle for a file. - let file: kxio::fs::PathReal = fs.file(file_path); // Creates a `Reader` which loaded the file into memory. let reader: kxio::fs::Reader = file.reader()?; let contents: &str = reader.as_str(); @@ -100,6 +94,15 @@ fn delete_file(file_path: &Path, fs: &kxio::fs::FileSystem) -> kxio::Result<()> Ok(()) } +/// A function that deletes the file +fn delete_file(file: FileHandle) -> kxio::Result<()> { + println!("deleting file: {file}"); + + file.remove()?; + + Ok(()) +} + #[cfg(test)] mod tests { use http::StatusCode; diff --git a/src/fs/path.rs b/src/fs/path.rs index 84c8b52..f9e38e4 100644 --- a/src/fs/path.rs +++ b/src/fs/path.rs @@ -1,6 +1,8 @@ // use std::{ - fmt::Display, marker::PhantomData, path::{Path, PathBuf} + fmt::Display, + marker::PhantomData, + path::{Path, PathBuf}, }; use crate::fs::{Error, Result}; diff --git a/src/net/system.rs b/src/net/system.rs index f1d1dd0..9c57e3f 100644 --- a/src/net/system.rs +++ b/src/net/system.rs @@ -97,6 +97,9 @@ impl Net { /// then the request will be matched and any stored response returned, or an /// error if no matched request was found. /// + /// This method provides an escape-hatch from `kxio`'s fluent API, and allows you + /// to create a request using [reqwest] directly. + /// /// # Errors /// /// This method fails if there was an error while sending request,