rust-crates / ergo_fs

ergonomic filesystem operations in rust
https://docs.rs/ergo_fs
Other
7 stars 0 forks source link

Reduce the API's cognitive load #12

Open epage opened 6 years ago

epage commented 6 years ago

Right now the API is meant to be both easy to use and (I assume) enforcing invariants in types (like ensuring a file is a file and not a dir before reading it). The challenge is that there are a lot of types for the user to deal with and its hard to see where one can get started.

epage commented 6 years ago

I can see this being improved in a mixture of two ways

vitiral commented 6 years ago

@epage thanks for opening up all these great issues!

There are really only two groups of types: Path types and File types. Let's explore them and see if there are areas we could reduce.

Note: I am the author of path_abs so any decision we make can be made directly to that crate.

Path Types

First of all, there is the stdlib Path and PathBuf. I do not want to overlap with their names and I want to use them as the API to emulate/expand upon.

After that there are the following:

There is serious overlap between PathAbs and PathType so I would be okay getting rid of PathAbs (hilariously this is the name of the crate... might have to rename path_abs to something else?)

File Types

The following file types are exposed to the user:

Honestly file types are one of my big annoynances. The OpenOptions is error prone since the returned object is impl Write even if you requested a read-only file. I'm open to suggestions here as well though!

Possible Improvement path: file/dir modules

I think it is worth mentioning that the Path types have way too many methods IMO. I would like to maybe have a file and dir module for accomplishing what PathFile::read_str currently accomplishes. I would also like to remove things like PathFile::read() -> FileRead as it is straight up redundant.

Conclusion

Part of the reason there are "so many types" is because the operations you can do on the file system are so varied. When you list a directory, what are you getting back? Well... it could be files or directories (symlinks are auto-resolved). PathType doesn't hide that from you anymore and in rust style forces you to handle both possibilities.

The type system prevents programmer error when using methods and I think that is well worth the expanded API.

vitiral commented 6 years ago

So I mostly agree with your second point, which is to improve the docs to "tell the story better."

This brings up another point: where do these docs live? I see the ergo_fs docs as "library/reference" docs and I think just stating the types is correct there. IMO the Ergo Cookbook is the right place to tell this kind of "story" and slowly unveil the types.

epage commented 6 years ago

see the ergo_fs docs as "library/reference" docs and I think just stating the types is correct there.

I think its reasonable for the crate-wide doc string to tell a brief story but I do agree that there will need to be docs outside of that. This again fits into my idea of there being an ergo org. You could then have an ergo.github.io repo for mdbook + other docs to consolidate the ergo themed docs.

epage commented 6 years ago

From your brief description, I can't really tell the difference in purpose

They all seem to fulfill the same purpose.

What is your goal with having distinct PathFile and PathDir?

Maybe its just me, but with PathTmp, I'd personally separate out ownership vs path.

epage commented 6 years ago

(future) FileTmp a temporary file handle, wraps tempfile::TempFile.

While this might be annoying from the implementation, but should this just be a different factory on the other File types?

How well can I pass FileEdit to functions in place of FileRead or FileWrite?

vitiral commented 6 years ago

All of the path types (except PathArc) are canonicalized so that you can always compare them, ask has_prefix, etc and it will give the "expected" answer.

PathArc exists as a zero-cost escape hatch when you want to stop caring about this.

The goal of PathFile vs PathDir is to:

Maybe its just me, but with PathTmp...

Agh, these are issues! I opened #14

While this might be annoying from the implementation, but should this just be a different factory on the other File types?

I don't think so -- it has to have ownership to handle dropping correctly.

How well can I pass FileEdit to functions in place of FileRead or FileWrite?

Well, FileEdit implements both Read and Write so you could use it in that way. I suppose we should probably provide AsRef<FileRead> etc as well for it!

epage commented 6 years ago

While this might be annoying from the implementation, but should this just be a different factory on the other File types?

I don't think so -- it has to have ownership to handle dropping correctly.

Unlike Path, File* already have an ownership model compatible with Temp*. So one way to merge FileTmp could be by having an Option<TempFile> inside of File*.

epage commented 6 years ago

All of the path types (except PathArc) are canonicalized so that you can always compare them, ask has_prefix, etc and it will give the "expected" answer.

PathArc exists as a zero-cost escape hatch when you want to stop caring about this.

An alternative to always-canonicalized is https://github.com/rust-crates/ergo_fs/issues/10