Visitar URL original
Add file and directory path separate abstractions · Issue #58 · ForNeVeR/TruePath · GitHub
Skip to content

Add file and directory path separate abstractions #58

Open

Description

@rodion-m

For example, https://github.com/ndepend/NDepend.Path has IAbsoluteFilePath, IAbsoluteDirectoryPath, IRelativeDirectoryPath and IRelativeFilePath . It'd be great to see such abstractions in TruePath too.

Activity

  1. ForNeVeR commented on May 21, 2024

    @ForNeVeR
    Owner

    I believe this deserves more discussion.

    My current view on the library is that it should grant the compile-time safety for the provided entities.

    While a path could be easily classified as absolute or relative in compile time, and won't ever change its classification, it could easily be changed from a file to a directory (or even to not being existent) in runtime.

    I have a vague feeling that this kind of classification is better handled by runtime attributes (such as — methods, properties etc.) than compile-time types.

    But I understand the need.

    Perhaps we can implement wrappers around our current paths that will additionally check whether they are files or directories at some moment in runtime?

    What should be the operational model of these types? NDepend.Path documentation shows allowed operations for IAbsoluteFilePath but not IRelativeFilePath. What's the practical difference between file and directory path, from the library standpoint?

  2. ForNeVeR commented on Oct 17, 2025

    @ForNeVeR
    Owner

    After using TruePath a bit more in different scenarios — yes, definitely, this is a practical idea. Compile time safety or not I don't care that much (as a user), but what I do care is that I wanna to pass paths to files and directories as different types, to not accidentally mix them.

  3. ForNeVeR commented on Feb 14, 2026

    @ForNeVeR
    Owner

    Draft API and some general ideas.

    1. Introduce two new types, AbsoluteDirectoryPath and AbsoluteFilePath. AbsoluteDirectoryPath is for directories (or directory symlinks/hardlinks, i.e. anything that may be used as a container), while AbsoluteFilePath is for anything else — file symlinks, Unix domain sockets, etc.).

      If the users need something unusual, e.g. directly manipulating symlinks as files or opening directories as files, they should fall back to AbsolutePath or use AbsoluteFilePath.

    2. API of AbsoluteDirectoryPath should implement IPath<T> and generally be the same shape as the AbsolutePath. How to do that is a good question — I don't wanna copy-paste, so perhaps some trait over source gen?

    3. Absolute*Path should implicitly convert to AbsolutePath or LocalPath.

    4. Extension methods for AbsolutePath and AbsoluteDirectoryPath:

      • path.Directory() — represent the current path as directory;
      • path.Directory("foo", "bar") — same as (path / "foo" / "bar").Directory(), i.e. resolve a nested directory;
      • absolutePath.File() — represent the current path as file;
      • path.File("foo", "bar") — same as (path / "foo" / "bar").File();
      • how do we block absoluteDirectory().File() from re-interpreting a directory as a file?
        Quick ideas:
        • add a method without args, mark as deprecated,
        • emit a warning for a method with empty parameter list
          • expose the warnings in runtime somehow? Static logger interface?
    5. Sub-path resolve (operator /) should only be available for AbsoluteDirectoryPath, not file. Same for extension methods that return files insde path.

    6. File operations (e.g. path.OpenWrite(), etc.) should only be available for files.

    7. Some new generic interface for working with all three Absolute*Path at once when needed? Or maybe two interfaces to generalize cases over AbsolutePath+AbsoluteDirectoryPath and AbsolutePath+AbsoluteFilePath? Might delay until actually needed, though (implement on demand basis).

    8. Conversion operators .ReinterpretAsFile(), .ReinterpretAsDirectory() to convert as-is to each other.

    9. Mark AbsolutePath.CurrentWorkingDirectory() as an AbsoluteDirectoryPath? Breaking change but a nice one?

    Motivating example:

    var someFile = AbsolutePath.CurrentWorkingDirectory().File("foo", "bar.txt");
    var someDir = AbsolutePath.CurrentWorkingDirectory().Directory("foo", "bar.txt");
    using var stream = someFile.OpenRead();
    var textFiles = someDir.FindFiles("*.txt");
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is neededstatus:to-discussIssues that deserve more discussion

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions