Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

treewide: refactor read_file and mkdir #6

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

KarlK90
Copy link
Contributor

@KarlK90 KarlK90 commented Jan 30, 2025

mkdir and read_file augment the error case with the path in the error case. This is useful as we otherwise don't know which location failed. This commit refactors the functions to take any argument that coerces into a Path - which is implemented by many types.

mkdir now uses create_dir_all as it is not meant to fail if the directory already exists.

builds/depends on #5

@@ -46,10 +46,6 @@ pub fn mkdir(dir: &str) -> Result<()> {
Ok(())
}

fn read_file(filename: &str) -> std::result::Result<String, String> {
read_to_string(filename).map_err(|e| format!("Failed to read {filename}: {e}"))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main reason for this function is the map_err. It extends the error message so say which file could not be read. From what I've seen, read_to_string() does not include it.

Without it, since we propagate all errors to main() it becomes unclear which file failed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I didn't think of that. I moved the functions into a util module and applied some refactoring.

pub fn mkdir(dir: &str) -> Result<()> {
if let Err(e) = create_dir(dir) {
if e.kind() != io::ErrorKind::AlreadyExists {
return Err(format!("Failed to create {dir}: {e}",).into());
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here: we loose, which dir could not be created.

And that's not theoretical: the mkdirs in usbg_9pfs.rs can fail when drivers are missing in the Kernel.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I didn't think of that. I moved the functions into a util module and applied some refactoring.

@KarlK90 KarlK90 force-pushed the maintenance/use-std-fs-functions branch from c4227bc to a37192c Compare January 30, 2025 17:19
@KarlK90 KarlK90 changed the title treewide: use std fs functions treewide: refactor read_file and mkdir Jan 30, 2025
@KarlK90
Copy link
Contributor Author

KarlK90 commented Jan 30, 2025

For nicer error messages I propose to add https://crates.io/crates/anyhow to the project which is the canonical error handling library for Rust applications. It adds a bit to the final binary size but allows attaching context objects/information to the error cases and has better ergonomics for producing errors e.g.:

pub(crate) fn read_file(filename: impl AsRef<Path>) -> Result<String> {
    read_to_string(filename.as_ref())
        .with_context(|| format!("Failed to read {}", filename.as_ref().to_string_lossy()))
}

Gives in this simple error case (which can be extended easily):

Error: Failed to read test_test

Caused by:
    Is a directory (os error 21)

instead of:

Error: "Failed to read test_test: Is a directory (os error 21)"

@KarlK90 KarlK90 force-pushed the maintenance/use-std-fs-functions branch from a37192c to ed59bf5 Compare January 31, 2025 12:39
@michaelolbrich
Copy link
Owner

For nicer error messages I propose to add https://crates.io/crates/anyhow to the project which is the canonical error handling library for Rust applications. It adds a bit to the final binary size but allows attaching context objects/information to the error cases and has better ergonomics for producing errors e.g.:

pub(crate) fn read_file(filename: impl AsRef<Path>) -> Result<String> {
    read_to_string(filename.as_ref())
        .with_context(|| format!("Failed to read {}", filename.as_ref().to_string_lossy()))
}

Gives in this simple error case (which can be extended easily):

Error: Failed to read test_test

Caused by:
    Is a directory (os error 21)

instead of:

Error: "Failed to read test_test: Is a directory (os error 21)"

I want to keep the binary size down and adding extra stuff for nicer error messages does not sound like a good idea.

@KarlK90 KarlK90 force-pushed the maintenance/use-std-fs-functions branch from ed59bf5 to d24c4e1 Compare February 2, 2025 11:39
@@ -0,0 +1,36 @@
use std::{
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, missed that before: can you add the license identifier please?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, missed that. Fixed.

mkdir, read_file write_file augment the error case with the path in the
error case. This is useful as we otherwise don't know which location
failed. This commit refactors the functions to take any argument that
coerces into a Path - which is implemented by many types.

mkdir now uses create_dir_all as it is not meant to fail if the
directory already exists.

Signed-off-by: Stefan Kerkmann <[email protected]>
@KarlK90 KarlK90 force-pushed the maintenance/use-std-fs-functions branch from d24c4e1 to 6bb7ae5 Compare February 2, 2025 11:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants