input-output-hk / input-output-hk/fs-sim

Dynamically check `FsPath` invariants

Open
#73 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Haskell
Stars
2
Forks
6
Avg merge
3d 22h
Merged PRs (30d)
1

Description

First suggested in https://github.com/input-output-hk/fs-sim/pull/72#issue-2337874221. `FsPath` has a number of invariants, and we currently rely on the user to satisfy them. It might be nice to check these invariants dynamically, while also providing an escape hatch for users in case they want to skip the check. For example:

```haskell
newtype FsPath = UnsafeFsPath { fsPathToList :: [Strict.Text] }
deriving (Eq, Ord, Generic)
deriving newtype NFData

invariant :: FsPath -> Bool
invariant (UnsafeFsPath xs) = all p xs
where p x = -- Paths are monotonic
x /= ".."
&& -- Paths can not have empty directory/file names
not (any Strict.null xs)
&& -- There are no path separators in individual names
not (Text.any (`Text.elem` allPathSeparators) x)

allPathSeparators :: Text
allPathSeparators = Text.pack (Posix.pathSeparators ++ Windows.pathSeparators)

unsafeFsPathFromList :: [Strict.Text] -> FsPath
unsafeFsPathFromList xs = assert (invariant fsp) $ fsp
where fsp = UnsafeFsPath (force xs)

fsPathFromList :: [Strict.Text] -> Maybe FsPath
fsPathFromList xs
| invariant fsp = Just fsp
| otherwise = Nothing
where fsp = UnsafeFsPath (force xs)
```

Note two things in the example above:
* Both `unsafeFsPathFromList` and `fsPathFromList` ensure that the resulting `FsPath` contains no thunks my using `force`. Maybe we want to `assert` instead that the `FsPath` contains no thunks in `unsafeFsPathFromList`, and have the user ensure that fact.
* To ensure similar behaviour across OS distributions, invariant checks do not depend on the underlying OS distribution, hence `allPathSeparators`.

We should also consider whether this design pattern is overkill: in practice, users are probably unlikely to use non-sensible path names

Contributor guide

Open the contributing guide

Research direction

Start by reading the FsPath definition and the design discussion in pull request 72. Compare the proposed invariant, unsafeFsPathFromList, and fsPathFromList APIs with the existing path behavior and consider the force/assert trade-off. Done means agreeing on whether dynamic checks are warranted and defining validated and escape-hatch construction behavior that is consistent across operating systems.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell
Domain
operating-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.