module System.Path.Internal
(
  -- * The main filepath (& dirpath) abstract type
  Path, -- kept abstract

  -- * Type Synonyms
  AbsFile,
  RelFile,
  AbsDir,
  RelDir,
  AbsRelFile,
  AbsRelDir,
  AbsFileDir,
  RelFileDir,
  AbsRelFileDir,

  AbsPath,     Abs,
  RelPath,     Rel,
  FilePath,    File,
  DirPath,     Dir,
  AbsRelPath,  AbsRel,
  FileDirPath, FileDir,

  -- * Decisions on path types
  withAbsRel, withFileDir,

  -- * Path to String conversion
  toString,
  getPathString,

  -- * Constants
  rootDir,
  currentDir,
  emptyFile,

  -- * Parsing Functions
  maybePath, maybe,
  parsePath, parse,

  -- * Checked Construction Functions
  path,
  relFile,
  relDir,
  absFile,
  absDir,
  relPath,    rel,
  absPath,    abs,
  filePath,   file,
  dirPath,    dir,
  absRel,     fileDir,

  idAbsRel, idAbs, idRel,
  idFileDir, idFile, idDir,

  -- * Unchecked Construction Functions
  asPath,
  asRelFile,
  asRelDir,
  asAbsFile,
  asAbsDir,
  asRelPath,
  asAbsPath,
  asFilePath,
  asDirPath,

  -- * Checked Construction Functions
  mkPathAbsOrRel,
  mkPathFileOrDir,
  mkAbsPath,
  mkAbsPathFromCwd,

  -- * Basic Manipulation Functions
  (</>),
  (<.>),
  (<++>),
  addExtension,
  combine,
  dropExtension,
  dropExtensions,
  dropFileName,
  replaceExtension,
  replaceBaseName,
  replaceDirectory,
  replaceFileName,
  splitExtension,
  splitExtensions,
  splitFileName,
  splitDirName,
  takeBaseName,
  takeDirectory,
  takeSuperDirectory,
  takeExtension,
  takeExtensions,
  takeFileName,
  takeDirName,
  mapFileName,
  mapFileNameF,

  -- * Auxillary Manipulation Functions
  equalFilePath,
  joinPath,
  normalise,
  splitPath,
  makeRelative,
  makeRelativeMaybe,
  makeAbsolute,
  makeAbsoluteFromCwd,
  dynamicMakeAbsolute,
  dynamicMakeAbsoluteFromCwd,
  genericMakeAbsolute,
  genericMakeAbsoluteFromCwd,
  pathMap,
  dirFromFile,
  fileFromDir,
  toFileDir,
  fromFileDir,
  fileFromFileDir,
  dirFromFileDir,
  toAbsRel,
  fromAbsRel,

  -- * Path Predicates
  isAbsolute,
  isRelative,
  isAbsoluteString,
  isRelativeString,
  hasAnExtension,
  hasExtension,

  -- * Separators
  System(..),
  extSeparator,
  searchPathSeparator,
  isExtSeparator,
  isSearchPathSeparator,

  -- * Generic Manipulation Functions
  genericAddExtension,
  genericDropExtension,
  genericDropExtensions,
  genericSplitExtension,
  genericSplitExtensions,
  genericTakeExtension,
  genericTakeExtensions,

  -- * Tests
  testAll,
  isValid,
)

where

import qualified System.Path.Internal.PartClass as Class
import qualified System.Path.Internal.Part as Part
import qualified System.Path.Internal.Component as PC
import qualified System.Path.Internal.Separator as Sep
import System.Path.Internal.PartClass as Class
        (WrapFileDir(WrapFileDir), WrapAbsRel(WrapAbsRel), FuncArg(..), fdMap)
import System.Path.Internal.Part (absPC)
import System.Path.Internal.System (System(..))
import System.Path.Internal.Component
        (Component(Component), GenComponent)

import qualified System.Directory as SD

import qualified Control.Monad.Trans.Class as MT
import qualified Control.Monad.Trans.State as MS
import Control.Monad (MonadPlus, guard, liftM2, mplus, mzero)
import Control.Applicative (Const(Const), liftA2, (<$>), (<$))
import Control.DeepSeq (NFData(rnf))

import qualified Data.Monoid.HT as MonHT
import qualified Data.List.HT as ListHT
import Data.Tagged (Tagged(Tagged), untag)
import Data.Functor.Compose (Compose(Compose), getCompose)
import Data.List (isSuffixOf, stripPrefix, intersperse)
import Data.String (IsString(fromString))
import Data.Maybe.HT (toMaybe)
import Data.Maybe (fromMaybe, maybeToList)
import Data.Tuple.HT (mapFst, mapSnd)
import Data.Monoid (Monoid(mempty, mappend, mconcat), Endo(Endo), appEndo)
import Data.Semigroup (Semigroup(sconcat, (<>)), )
import Data.Char (isSpace)
import Data.Ord.HT (comparing)
import Data.Eq.HT (equating)

import Text.Show.HT (concatS)
import Text.Printf (printf)

import qualified Test.DocTest.Driver as DocTest
import qualified Test.QuickCheck as QC
import Test.QuickCheck
          (Gen, Property, property, Arbitrary(arbitrary), frequency)

import qualified Prelude as P
import Prelude hiding (FilePath, maybe, abs)


{- $setup
>>> :set -fno-warn-warnings-deprecations
>>> import qualified System.Path.PartClass as Class
>>> import qualified System.Path.Generic as Path
>>> import qualified System.Path.Posix as Posix
>>> import qualified System.Path.Windows as Windows
>>> import System.Path.Generic ((</>), (<.>), relFile, relDir, absFile, absDir)
>>> import Data.List (isSuffixOf, isPrefixOf)
>>> import Data.Char (toLower)
>>> import qualified Test.QuickCheck as QC
>>> forAllAbsRel :: (Class.FileDir fd, QC.Testable prop) => (Default.AbsRel fd -> prop) -> QC.Property
>>> forAllAbsRel = QC.forAll QC.arbitrary
-}


------------------------------------------------------------------------
-- Types

-- | This is the main filepath abstract datatype
data Path os ar fd = Path ar [Component os] fd

instance
    (System os, Class.AbsRel ar, Class.FileDir fd) =>
        Eq (Path os ar fd) where
    == :: Path os ar fd -> Path os ar fd -> Bool
(==)  =  (Path os ar fd
 -> (WrapAbsRel os ar, [Component os], WrapFileDir os fd))
-> Path os ar fd -> Path os ar fd -> Bool
forall b a. Eq b => (a -> b) -> a -> a -> Bool
equating Path os ar fd
-> (WrapAbsRel os ar, [Component os], WrapFileDir os fd)
forall os ar fd.
Path os ar fd
-> (WrapAbsRel os ar, [Component os], WrapFileDir os fd)
inspectPath

instance
    (System os, Class.AbsRel ar, Class.FileDir fd) =>
        Ord (Path os ar fd) where
    compare :: Path os ar fd -> Path os ar fd -> Ordering
compare  =  (Path os ar fd
 -> (WrapAbsRel os ar, [Component os], WrapFileDir os fd))
-> Path os ar fd -> Path os ar fd -> Ordering
forall b a. Ord b => (a -> b) -> a -> a -> Ordering
comparing Path os ar fd
-> (WrapAbsRel os ar, [Component os], WrapFileDir os fd)
forall os ar fd.
Path os ar fd
-> (WrapAbsRel os ar, [Component os], WrapFileDir os fd)
inspectPath

inspectPath ::
    Path os ar fd -> (WrapAbsRel os ar, [Component os], WrapFileDir os fd)
inspectPath :: forall os ar fd.
Path os ar fd
-> (WrapAbsRel os ar, [Component os], WrapFileDir os fd)
inspectPath (Path ar
ar [Component os]
pcs fd
fd) = (ar -> WrapAbsRel os ar
forall os ar. ar -> WrapAbsRel os ar
WrapAbsRel ar
ar, [Component os]
pcs, fd -> WrapFileDir os fd
forall os fd. fd -> WrapFileDir os fd
WrapFileDir fd
fd)


selTag :: Path os ar fd -> Tagged os a -> a
selTag :: forall os ar fd a. Path os ar fd -> Tagged os a -> a
selTag Path os ar fd
_ = Tagged os a -> a
forall {k} (s :: k) b. Tagged s b -> b
untag


type AbsFile os = Path os Part.Abs Part.File
type RelFile os = Path os Part.Rel Part.File
type AbsDir  os = Path os Part.Abs Part.Dir
type RelDir  os = Path os Part.Rel Part.Dir
type AbsRelFile os = Path os Part.AbsRel Part.File
type AbsRelDir  os = Path os Part.AbsRel Part.Dir
type AbsFileDir os = Path os Part.Abs Part.FileDir
type RelFileDir os = Path os Part.Rel Part.FileDir
type AbsRelFileDir os = Path os Part.AbsRel Part.FileDir

type Abs  os fd = Path os Part.Abs fd
type Rel  os fd = Path os Part.Rel fd
type File os ar = Path os ar Part.File
type Dir  os ar = Path os ar Part.Dir
type AbsRel  os fd = Path os Part.AbsRel fd
type FileDir os ar = Path os ar Part.FileDir

{-# DEPRECATED RelPath     "Use Path.Rel instead." #-}
{-# DEPRECATED AbsPath     "Use Path.Abs instead." #-}
{-# DEPRECATED AbsRelPath  "Use Path.AbsRel instead." #-}
{-# DEPRECATED FilePath    "Use Path.File instead." #-}
{-# DEPRECATED DirPath     "Use Path.Dir instead." #-}
{-# DEPRECATED FileDirPath "Use Path.FileDir instead." #-}

type AbsPath  os fd = Path os Part.Abs fd
type RelPath  os fd = Path os Part.Rel fd
type FilePath os ar = Path os ar Part.File
type DirPath  os ar = Path os ar Part.Dir
type AbsRelPath  os fd = Path os Part.AbsRel fd
type FileDirPath os ar = Path os ar Part.FileDir

instance (Class.AbsRel ar, Class.FileDir fd) => NFData (Path os ar fd) where
    rnf :: Path os ar fd -> ()
rnf (Path ar
ar [Component os]
pcs fd
fd) =
        ((), [Component os], ()) -> ()
forall a. NFData a => a -> ()
rnf (([Char] -> ()) -> () -> ar -> ()
forall ar a. AbsRel ar => ([Char] -> a) -> a -> ar -> a
Class.withAbsRel [Char] -> ()
forall a. NFData a => a -> ()
rnf () ar
ar, [Component os]
pcs, (GenComponent -> ()) -> () -> () -> fd -> ()
forall fd a. FileDir fd => (GenComponent -> a) -> a -> a -> fd -> a
Class.withFileDir GenComponent -> ()
forall a. NFData a => a -> ()
rnf () () fd
fd)

-- I don't think this basic type of fold is appropriate for a nested datatype
-- pathFold :: a -> (a -> String -> a) -> Path ar fd -> a
-- pathFold pr f PathRoot = pr
-- pathFold pr f (FileDir d pc) = f (pathFold pr f d) (unPathComponent pc)

-- | Map over the components of the path.
--
-- prop> Path.pathMap (map toLower) (absDir "/tmp/Reports/SpreadSheets") == Posix.absDir "/tmp/reports/spreadsheets"
pathMap ::
    (Class.FileDir fd) => (String -> String) -> Path os ar fd -> Path os ar fd
pathMap :: forall fd os ar.
FileDir fd =>
([Char] -> [Char]) -> Path os ar fd -> Path os ar fd
pathMap [Char] -> [Char]
f (Path ar
ar [Component os]
pcs fd
fd) = ar -> [Component os] -> fd -> Path os ar fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar ((Component os -> Component os) -> [Component os] -> [Component os]
forall a b. (a -> b) -> [a] -> [b]
map (([Char] -> [Char]) -> Component os -> Component os
forall os. ([Char] -> [Char]) -> Component os -> Component os
PC.map [Char] -> [Char]
f) [Component os]
pcs) (([Char] -> [Char]) -> fd -> fd
forall fd. FileDir fd => ([Char] -> [Char]) -> fd -> fd
fdMap [Char] -> [Char]
f fd
fd)


mapFilePart ::
    (GenComponent -> GenComponent) -> FilePath os ar -> FilePath os ar
mapFilePart :: forall os ar.
(GenComponent -> GenComponent) -> FilePath os ar -> FilePath os ar
mapFilePart GenComponent -> GenComponent
f (Path ar
ar [Component os]
pcs (Part.File GenComponent
fd)) = ar -> [Component os] -> File -> Path os ar File
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar [Component os]
pcs (File -> Path os ar File) -> File -> Path os ar File
forall a b. (a -> b) -> a -> b
$ GenComponent -> File
Part.File (GenComponent -> File) -> GenComponent -> File
forall a b. (a -> b) -> a -> b
$ GenComponent -> GenComponent
f GenComponent
fd

mapFilePartF ::
    (Functor f) =>
    (GenComponent -> f GenComponent) -> FilePath os ar -> f (FilePath os ar)
mapFilePartF :: forall (f :: * -> *) os ar.
Functor f =>
(GenComponent -> f GenComponent)
-> FilePath os ar -> f (FilePath os ar)
mapFilePartF GenComponent -> f GenComponent
f (Path ar
ar [Component os]
pcs (Part.File GenComponent
fd)) =
    ar -> [Component os] -> File -> Path os ar File
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar [Component os]
pcs (File -> Path os ar File)
-> (GenComponent -> File) -> GenComponent -> Path os ar File
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenComponent -> File
Part.File (GenComponent -> Path os ar File)
-> f GenComponent -> f (Path os ar File)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenComponent -> f GenComponent
f GenComponent
fd

splitFilePart ::
    (GenComponent -> (GenComponent, a)) -> FilePath os ar -> (FilePath os ar, a)
splitFilePart :: forall a os ar.
(GenComponent -> (GenComponent, a))
-> FilePath os ar -> (FilePath os ar, a)
splitFilePart GenComponent -> (GenComponent, a)
f (Path ar
ar [Component os]
pcs (Part.File GenComponent
fd)) = (GenComponent -> Path os ar File)
-> (GenComponent, a) -> (Path os ar File, a)
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (ar -> [Component os] -> File -> Path os ar File
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar [Component os]
pcs (File -> Path os ar File)
-> (GenComponent -> File) -> GenComponent -> Path os ar File
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenComponent -> File
Part.File) ((GenComponent, a) -> (Path os ar File, a))
-> (GenComponent, a) -> (Path os ar File, a)
forall a b. (a -> b) -> a -> b
$ GenComponent -> (GenComponent, a)
f GenComponent
fd

mapPathDirs ::
    ([Component os] -> [Component os]) -> Path os ar fd -> Path os ar fd
mapPathDirs :: forall os ar fd.
([Component os] -> [Component os])
-> Path os ar fd -> Path os ar fd
mapPathDirs [Component os] -> [Component os]
f ~(Path ar
ar [Component os]
pcs fd
fd) = ar -> [Component os] -> fd -> Path os ar fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar ([Component os] -> [Component os]
f [Component os]
pcs) fd
fd


withAbsRel ::
    (Class.AbsRel ar) =>
    (AbsPath os fd -> a) -> (RelPath os fd -> a) -> Path os ar fd -> a
withAbsRel :: forall ar os fd a.
AbsRel ar =>
(AbsPath os fd -> a) -> (RelPath os fd -> a) -> Path os ar fd -> a
withAbsRel AbsPath os fd -> a
fAbs RelPath os fd -> a
fRel (Path ar
ar [Component os]
pcs fd
fd) =
    ([Char] -> a) -> a -> ar -> a
forall ar a. AbsRel ar => ([Char] -> a) -> a -> ar -> a
Class.withAbsRel
        (\[Char]
drive -> AbsPath os fd -> a
fAbs (AbsPath os fd -> a) -> AbsPath os fd -> a
forall a b. (a -> b) -> a -> b
$ Abs -> [Component os] -> fd -> AbsPath os fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path (GenComponent -> Abs
Part.Abs ([Char] -> GenComponent
forall os. [Char] -> Component os
Component [Char]
drive)) [Component os]
pcs fd
fd)
        (RelPath os fd -> a
fRel (RelPath os fd -> a) -> RelPath os fd -> a
forall a b. (a -> b) -> a -> b
$ Rel -> [Component os] -> fd -> RelPath os fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path Rel
Part.Rel [Component os]
pcs fd
fd)
        ar
ar

switchFileDir ::
    (Class.FileDir fd) =>
    f (FilePath os ar) -> f (DirPath os ar) -> f (FileDirPath os ar) ->
    f (Path os ar fd)
switchFileDir :: forall fd (f :: * -> *) os ar.
FileDir fd =>
f (FilePath os ar)
-> f (DirPath os ar) -> f (FileDirPath os ar) -> f (Path os ar fd)
switchFileDir f (FilePath os ar)
f f (DirPath os ar)
d f (FileDirPath os ar)
fd =
    Compose f (Path os ar) fd -> f (Path os ar fd)
forall {k1} {k2} (f :: k1 -> *) (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose (Compose f (Path os ar) fd -> f (Path os ar fd))
-> Compose f (Path os ar) fd -> f (Path os ar fd)
forall a b. (a -> b) -> a -> b
$ Compose f (Path os ar) File
-> Compose f (Path os ar) Dir
-> Compose f (Path os ar) FileDir
-> Compose f (Path os ar) fd
forall fd (f :: * -> *).
FileDir fd =>
f File -> f Dir -> f FileDir -> f fd
forall (f :: * -> *). f File -> f Dir -> f FileDir -> f fd
Class.switchFileDir (f (FilePath os ar) -> Compose f (Path os ar) File
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose f (FilePath os ar)
f) (f (DirPath os ar) -> Compose f (Path os ar) Dir
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose f (DirPath os ar)
d) (f (FileDirPath os ar) -> Compose f (Path os ar) FileDir
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose f (FileDirPath os ar)
fd)

switchFileOrDir ::
    (Class.FileOrDir fd) =>
    f (FilePath os ar) -> f (DirPath os ar) -> f (Path os ar fd)
switchFileOrDir :: forall fd (f :: * -> *) os ar.
FileOrDir fd =>
f (FilePath os ar) -> f (DirPath os ar) -> f (Path os ar fd)
switchFileOrDir f (FilePath os ar)
f f (DirPath os ar)
d =
    Compose f (Path os ar) fd -> f (Path os ar fd)
forall {k1} {k2} (f :: k1 -> *) (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose (Compose f (Path os ar) fd -> f (Path os ar fd))
-> Compose f (Path os ar) fd -> f (Path os ar fd)
forall a b. (a -> b) -> a -> b
$ Compose f (Path os ar) File
-> Compose f (Path os ar) Dir -> Compose f (Path os ar) fd
forall fd (f :: * -> *). FileOrDir fd => f File -> f Dir -> f fd
forall (f :: * -> *). f File -> f Dir -> f fd
Class.switchFileOrDir (f (FilePath os ar) -> Compose f (Path os ar) File
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose f (FilePath os ar)
f) (f (DirPath os ar) -> Compose f (Path os ar) Dir
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose f (DirPath os ar)
d)

withFileDir ::
    (Class.FileOrDir fd) =>
    (FilePath os ar -> a) -> (DirPath os ar -> a) -> Path os ar fd -> a
withFileDir :: forall fd os ar a.
FileOrDir fd =>
(FilePath os ar -> a) -> (DirPath os ar -> a) -> Path os ar fd -> a
withFileDir FilePath os ar -> a
f DirPath os ar -> a
g = FuncArg a (Path os ar fd) -> Path os ar fd -> a
forall b a. FuncArg b a -> a -> b
runFuncArg (FuncArg a (Path os ar fd) -> Path os ar fd -> a)
-> FuncArg a (Path os ar fd) -> Path os ar fd -> a
forall a b. (a -> b) -> a -> b
$ FuncArg a (FilePath os ar)
-> FuncArg a (DirPath os ar) -> FuncArg a (Path os ar fd)
forall fd (f :: * -> *) os ar.
FileOrDir fd =>
f (FilePath os ar) -> f (DirPath os ar) -> f (Path os ar fd)
switchFileOrDir ((FilePath os ar -> a) -> FuncArg a (FilePath os ar)
forall b a. (a -> b) -> FuncArg b a
FuncArg FilePath os ar -> a
f) ((DirPath os ar -> a) -> FuncArg a (DirPath os ar)
forall b a. (a -> b) -> FuncArg b a
FuncArg DirPath os ar -> a
g)


-- | Currently not exported
eitherFromAbsRel ::
    Class.AbsRel ar => Path os ar fd -> Either (AbsPath os fd) (RelPath os fd)
eitherFromAbsRel :: forall ar os fd.
AbsRel ar =>
Path os ar fd -> Either (AbsPath os fd) (RelPath os fd)
eitherFromAbsRel = (AbsPath os fd -> Either (AbsPath os fd) (RelPath os fd))
-> (RelPath os fd -> Either (AbsPath os fd) (RelPath os fd))
-> Path os ar fd
-> Either (AbsPath os fd) (RelPath os fd)
forall ar os fd a.
AbsRel ar =>
(AbsPath os fd -> a) -> (RelPath os fd -> a) -> Path os ar fd -> a
withAbsRel AbsPath os fd -> Either (AbsPath os fd) (RelPath os fd)
forall a b. a -> Either a b
Left RelPath os fd -> Either (AbsPath os fd) (RelPath os fd)
forall a b. b -> Either a b
Right

-- | Currently not exported
_eitherFromFileDir ::
    Class.FileOrDir fd => Path os ar fd -> Either (FilePath os ar) (DirPath os ar)
_eitherFromFileDir :: forall fd os ar.
FileOrDir fd =>
Path os ar fd -> Either (FilePath os ar) (DirPath os ar)
_eitherFromFileDir = (FilePath os ar -> Either (FilePath os ar) (DirPath os ar))
-> (DirPath os ar -> Either (FilePath os ar) (DirPath os ar))
-> Path os ar fd
-> Either (FilePath os ar) (DirPath os ar)
forall fd os ar a.
FileOrDir fd =>
(FilePath os ar -> a) -> (DirPath os ar -> a) -> Path os ar fd -> a
withFileDir FilePath os ar -> Either (FilePath os ar) (DirPath os ar)
forall a b. a -> Either a b
Left DirPath os ar -> Either (FilePath os ar) (DirPath os ar)
forall a b. b -> Either a b
Right

------------------------------------------------------------------------
-- Read & Show instances

{- |
We show and parse file path components
using the rather generic 'relPath' smart constructor
instead of 'relFile', 'relDir' and @relPath str :: FileDirPath ar@.
Otherwise handling of all cases of 'Part.File', 'Part.Dir' and 'Part.FileDir' types
becomes pretty complicated.

>>> Posix.rootDir </> relDir "bla" </> relFile "blub"
rootDir </> relPath "bla" </> relPath "blub"
>>> Just (Posix.rootDir </> relDir "bla" </> relFile "blub")
Just (rootDir </> relPath "bla" </> relPath "blub")
>>> Posix.currentDir </> relDir "bla" </> relFile "blub"
currentDir </> relPath "bla" </> relPath "blub"
>>> Just (Posix.currentDir </> relDir "bla" </> relFile "blub")
Just (currentDir </> relPath "bla" </> relPath "blub")
>>> Windows.absDir "c:" </> relDir "bla" </> relFile "blub"
absDir "c:" </> relPath "bla" </> relPath "blub"
>>> Just (Windows.absDir "c:\\" </> relDir "bla" </> relFile "blub")
Just (absDir "c:\\" </> relPath "bla" </> relPath "blub")
-}
instance
    (System os, Class.AbsRel ar, Class.FileDir fd) =>
        Show (Path os ar fd) where
    showsPrec :: Int -> Path os ar fd -> [Char] -> [Char]
showsPrec = Tagged os (Int -> Path os ar fd -> [Char] -> [Char])
-> Int -> Path os ar fd -> [Char] -> [Char]
forall {k} (s :: k) b. Tagged s b -> b
untag Tagged os (Int -> Path os ar fd -> [Char] -> [Char])
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Tagged os (Int -> Path os ar fd -> [Char] -> [Char])
showsPrecTagged

showsPrecTagged ::
    (System os, Class.AbsRel ar, Class.FileDir fd) =>
    Tagged os (Int -> Path os ar fd -> ShowS)
showsPrecTagged :: forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Tagged os (Int -> Path os ar fd -> [Char] -> [Char])
showsPrecTagged =
    (([Char] -> Int -> Path os ar fd -> [Char] -> [Char])
 -> Tagged os [Char]
 -> Tagged os (Int -> Path os ar fd -> [Char] -> [Char]))
-> Tagged os [Char]
-> ([Char] -> Int -> Path os ar fd -> [Char] -> [Char])
-> Tagged os (Int -> Path os ar fd -> [Char] -> [Char])
forall a b c. (a -> b -> c) -> b -> a -> c
flip ([Char] -> Int -> Path os ar fd -> [Char] -> [Char])
-> Tagged os [Char]
-> Tagged os (Int -> Path os ar fd -> [Char] -> [Char])
forall a b. (a -> b) -> Tagged os a -> Tagged os b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Tagged os [Char]
forall os. System os => Tagged os [Char]
rootStringTagged (([Char] -> Int -> Path os ar fd -> [Char] -> [Char])
 -> Tagged os (Int -> Path os ar fd -> [Char] -> [Char]))
-> ([Char] -> Int -> Path os ar fd -> [Char] -> [Char])
-> Tagged os (Int -> Path os ar fd -> [Char] -> [Char])
forall a b. (a -> b) -> a -> b
$ \[Char]
root Int
d Path os ar fd
x ->
        case Path os ar fd -> (ar, [Component os])
forall fd os ar.
FileDir fd =>
Path os ar fd -> (ar, [Component os])
pathComponents Path os ar fd
x of
            (ar
ar, [Component os]
pcs) ->
                Bool -> ([Char] -> [Char]) -> [Char] -> [Char]
showParen (Int
dInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
5) (([Char] -> [Char]) -> [Char] -> [Char])
-> ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ [[Char] -> [Char]] -> [Char] -> [Char]
concatS ([[Char] -> [Char]] -> [Char] -> [Char])
-> [[Char] -> [Char]] -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$
                ([Char] -> [Char]) -> [[Char] -> [Char]] -> [[Char] -> [Char]]
forall a. a -> [a] -> [a]
intersperse
                    (Char -> [Char] -> [Char]
showChar Char
' ' ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [Char] -> [Char]
showString [Char]
combineOperator ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> [Char] -> [Char]
showChar Char
' ') ([[Char] -> [Char]] -> [[Char] -> [Char]])
-> [[Char] -> [Char]] -> [[Char] -> [Char]]
forall a b. (a -> b) -> a -> b
$
                ([Char] -> [Char] -> [Char])
-> ([Char] -> [Char]) -> ar -> [Char] -> [Char]
forall ar a. AbsRel ar => ([Char] -> a) -> a -> ar -> a
Class.withAbsRel
                    (\[Char]
drive ->
                        if [Char]
drive [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
root
                          then [Char] -> [Char] -> [Char]
showString [Char]
rootName
                          else [Char] -> [Char] -> [Char] -> [Char]
forall a. Show a => [Char] -> a -> [Char] -> [Char]
showsCons [Char]
absDirName [Char]
drive)
                    ([Char] -> [Char] -> [Char]
showString [Char]
currentName)
                    ar
ar ([Char] -> [Char]) -> [[Char] -> [Char]] -> [[Char] -> [Char]]
forall a. a -> [a] -> [a]
:
                (Component os -> [Char] -> [Char])
-> [Component os] -> [[Char] -> [Char]]
forall a b. (a -> b) -> [a] -> [b]
map (\(Component [Char]
pc) -> [Char] -> [Char] -> [Char] -> [Char]
forall a. Show a => [Char] -> a -> [Char] -> [Char]
showsCons [Char]
relPathName [Char]
pc) [Component os]
pcs

showsCons :: Show a => String -> a -> ShowS
showsCons :: forall a. Show a => [Char] -> a -> [Char] -> [Char]
showsCons [Char]
name a
arg  =  [Char] -> [Char] -> [Char]
showString [Char]
name ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> [Char] -> [Char]
showChar Char
' ' ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a -> [Char] -> [Char]
forall a. Show a => Int -> a -> [Char] -> [Char]
showsPrec Int
11 a
arg

{- |
Currently it also parses Part.AbsRel and Part.FileDir paths,
although these cannot be composed with the accepted combinators.
-}
-- prop> read "rootDir" == Posix.rootDir
-- prop> read "rootDir" == Windows.rootDir
-- prop> read "currentDir" == Posix.currentDir
-- prop> read "currentDir" == Windows.currentDir
-- prop> let path = Posix.rootDir </> relDir "bla" </> relFile "blub" in read (show path) == path
-- prop> let path = Just (Posix.rootDir </> relDir "bla" </> relFile "blub") in read (show path) == path
-- prop> let path = Posix.currentDir </> relDir "bla" </> relFile "blub" in read (show path) == path
-- prop> let path = Just (Posix.currentDir </> relDir "bla" </> relFile "blub") in read (show path) == path
-- prop> let path = Windows.rootDir </> relDir "bla" </> relFile "blub" in read (show path) == path
-- prop> let path = Just (Windows.rootDir </> relDir "bla" </> relFile "blub") in read (show path) == path
-- prop> let path = Windows.absDir "c:" </> relDir "bla" </> relFile "blub" in read (show path) == path
instance
    (System os, Class.AbsRel ar, Class.FileDir fd) =>
        Read (Path os ar fd) where
    readsPrec :: Int -> ReadS (Path os ar fd)
readsPrec Int
d = Bool -> ReadS (Path os ar fd) -> ReadS (Path os ar fd)
forall a. Bool -> ReadS a -> ReadS a
readParen (Int
dInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
5) (ReadS (Path os ar fd) -> ReadS (Path os ar fd))
-> ReadS (Path os ar fd) -> ReadS (Path os ar fd)
forall a b. (a -> b) -> a -> b
$ Tagged os (ReadS (Path os ar fd)) -> ReadS (Path os ar fd)
forall {k} (s :: k) b. Tagged s b -> b
untag Tagged os (ReadS (Path os ar fd))
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Tagged os (ReadS (Path os ar fd))
readsPrecTagged

readsPrecTagged ::
    (System os, Class.AbsRel ar, Class.FileDir fd) =>
    Tagged os (ReadS (Path os ar fd))
readsPrecTagged :: forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Tagged os (ReadS (Path os ar fd))
readsPrecTagged =
    ((StateT [Char] [] ar -> ReadS (Path os ar fd))
 -> Tagged os (StateT [Char] [] ar)
 -> Tagged os (ReadS (Path os ar fd)))
-> Tagged os (StateT [Char] [] ar)
-> (StateT [Char] [] ar -> ReadS (Path os ar fd))
-> Tagged os (ReadS (Path os ar fd))
forall a b c. (a -> b -> c) -> b -> a -> c
flip (StateT [Char] [] ar -> ReadS (Path os ar fd))
-> Tagged os (StateT [Char] [] ar)
-> Tagged os (ReadS (Path os ar fd))
forall a b. (a -> b) -> Tagged os a -> Tagged os b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Tagged os (StateT [Char] [] ar)
forall os ar.
(System os, AbsRel ar) =>
Tagged os (StateT [Char] [] ar)
readsSplitDrive ((StateT [Char] [] ar -> ReadS (Path os ar fd))
 -> Tagged os (ReadS (Path os ar fd)))
-> (StateT [Char] [] ar -> ReadS (Path os ar fd))
-> Tagged os (ReadS (Path os ar fd))
forall a b. (a -> b) -> a -> b
$ \StateT [Char] [] ar
readsSplDrv ->
        let go :: StateT [Char] [] [Component os]
go =
                StateT [Char] Maybe ()
-> StateT [Char] [] [Component os]
-> StateT [Char] [] [Component os]
-> StateT [Char] [] [Component os]
forall s (m :: * -> *) a.
StateT s Maybe () -> StateT s m a -> StateT s m a -> StateT s m a
handleMismatch
                    (StateT [Char] Maybe ()
forall (m :: * -> *). Monad m => StateT [Char] m ()
skipSpaces StateT [Char] Maybe ()
-> StateT [Char] Maybe () -> StateT [Char] Maybe ()
forall a b.
StateT [Char] Maybe a
-> StateT [Char] Maybe b -> StateT [Char] Maybe b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Char] -> StateT [Char] Maybe ()
forall (m :: * -> *). MonadPlus m => [Char] -> StateT [Char] m ()
matchString [Char]
combineOperator)
                    ([Component os] -> StateT [Char] [] [Component os]
forall a. a -> StateT [Char] [] a
forall (m :: * -> *) a. Monad m => a -> m a
return [])
                    ((Component os -> [Component os] -> [Component os])
-> StateT [Char] [] (Component os)
-> StateT [Char] [] [Component os]
-> StateT [Char] [] [Component os]
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (:) (([Char] -> Component os)
-> StateT [Char] [] [Char] -> StateT [Char] [] (Component os)
forall a b. (a -> b) -> StateT [Char] [] a -> StateT [Char] [] b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Char] -> Component os
forall os. [Char] -> Component os
Component (StateT [Char] [] [Char] -> StateT [Char] [] (Component os))
-> StateT [Char] [] [Char] -> StateT [Char] [] (Component os)
forall a b. (a -> b) -> a -> b
$ [Char] -> StateT [Char] [] [Char]
forall a. Read a => [Char] -> StateT [Char] [] a
readsCons [Char]
relPathName) StateT [Char] [] [Component os]
go)
        in  StateT [Char] [] (Path os ar fd) -> ReadS (Path os ar fd)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
MS.runStateT (StateT [Char] [] (Path os ar fd) -> ReadS (Path os ar fd))
-> StateT [Char] [] (Path os ar fd) -> ReadS (Path os ar fd)
forall a b. (a -> b) -> a -> b
$ do
                StateT [Char] [] ()
forall (m :: * -> *). Monad m => StateT [Char] m ()
skipSpaces
                [Path os ar fd] -> StateT [Char] [] (Path os ar fd)
forall (m :: * -> *) a. Monad m => m a -> StateT [Char] m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
MT.lift ([Path os ar fd] -> StateT [Char] [] (Path os ar fd))
-> (Maybe (Path os ar fd) -> [Path os ar fd])
-> Maybe (Path os ar fd)
-> StateT [Char] [] (Path os ar fd)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe (Path os ar fd) -> [Path os ar fd]
forall a. Maybe a -> [a]
maybeToList (Maybe (Path os ar fd) -> StateT [Char] [] (Path os ar fd))
-> StateT [Char] [] (Maybe (Path os ar fd))
-> StateT [Char] [] (Path os ar fd)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
                    (ar -> [Component os] -> Maybe (Path os ar fd))
-> StateT [Char] [] ar
-> StateT [Char] [] [Component os]
-> StateT [Char] [] (Maybe (Path os ar fd))
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 ar -> [Component os] -> Maybe (Path os ar fd)
forall fd ar os.
FileDir fd =>
ar -> [Component os] -> Maybe (Path os ar fd)
maybePathFromComponents StateT [Char] [] ar
readsSplDrv StateT [Char] [] [Component os]
forall {os}. StateT [Char] [] [Component os]
go

skipSpaces :: (Monad m) => MS.StateT String m ()
skipSpaces :: forall (m :: * -> *). Monad m => StateT [Char] m ()
skipSpaces = ([Char] -> [Char]) -> StateT [Char] m ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
MS.modify (([Char] -> [Char]) -> StateT [Char] m ())
-> ([Char] -> [Char]) -> StateT [Char] m ()
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> [Char] -> [Char]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace

readsCons :: (Read a) => String -> MS.StateT String [] a
readsCons :: forall a. Read a => [Char] -> StateT [Char] [] a
readsCons [Char]
name = do
    StateT [Char] [] ()
forall (m :: * -> *). Monad m => StateT [Char] m ()
skipSpaces
    [Char] -> StateT [Char] [] ()
forall (m :: * -> *). MonadPlus m => [Char] -> StateT [Char] m ()
matchString [Char]
name
    ([Char] -> [(a, [Char])]) -> StateT [Char] [] a
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
MS.StateT (([Char] -> [(a, [Char])]) -> StateT [Char] [] a)
-> ([Char] -> [(a, [Char])]) -> StateT [Char] [] a
forall a b. (a -> b) -> a -> b
$ Int -> [Char] -> [(a, [Char])]
forall a. Read a => Int -> ReadS a
readsPrec Int
11

handleMismatch ::
    MS.StateT s Maybe () ->
    MS.StateT s m a -> MS.StateT s m a -> MS.StateT s m a
handleMismatch :: forall s (m :: * -> *) a.
StateT s Maybe () -> StateT s m a -> StateT s m a -> StateT s m a
handleMismatch StateT s Maybe ()
act StateT s m a
err StateT s m a
success =
    (s -> m (a, s)) -> StateT s m a
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
MS.StateT ((s -> m (a, s)) -> StateT s m a)
-> (s -> m (a, s)) -> StateT s m a
forall a b. (a -> b) -> a -> b
$ \s
s0 ->
        case StateT s Maybe () -> s -> Maybe s
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
MS.execStateT StateT s Maybe ()
act s
s0 of
           Maybe s
Nothing -> StateT s m a -> s -> m (a, s)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
MS.runStateT StateT s m a
err s
s0
           Just s
s1 -> StateT s m a -> s -> m (a, s)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
MS.runStateT StateT s m a
success s
s1

matchString :: (MonadPlus m) => String -> MS.StateT String m ()
matchString :: forall (m :: * -> *). MonadPlus m => [Char] -> StateT [Char] m ()
matchString [Char]
prefix =
    ([Char] -> m ((), [Char])) -> StateT [Char] m ()
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
MS.StateT (([Char] -> m ((), [Char])) -> StateT [Char] m ())
-> ([Char] -> m ((), [Char])) -> StateT [Char] m ()
forall a b. (a -> b) -> a -> b
$ m ((), [Char])
-> ([Char] -> m ((), [Char])) -> Maybe [Char] -> m ((), [Char])
forall b a. b -> (a -> b) -> Maybe a -> b
P.maybe m ((), [Char])
forall a. m a
forall (m :: * -> *) a. MonadPlus m => m a
mzero (((), [Char]) -> m ((), [Char])
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (((), [Char]) -> m ((), [Char]))
-> ([Char] -> ((), [Char])) -> [Char] -> m ((), [Char])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (,) ()) (Maybe [Char] -> m ((), [Char]))
-> ([Char] -> Maybe [Char]) -> [Char] -> m ((), [Char])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [Char] -> Maybe [Char]
forall a. Eq a => [a] -> [a] -> Maybe [a]
stripPrefix [Char]
prefix

readsSplitDrive ::
    (System os, Class.AbsRel ar) => Tagged os (MS.StateT String [] ar)
readsSplitDrive :: forall os ar.
(System os, AbsRel ar) =>
Tagged os (StateT [Char] [] ar)
readsSplitDrive =
    ((StateT [Char] [] Abs -> StateT [Char] [] ar)
 -> Tagged os (StateT [Char] [] Abs)
 -> Tagged os (StateT [Char] [] ar))
-> Tagged os (StateT [Char] [] Abs)
-> (StateT [Char] [] Abs -> StateT [Char] [] ar)
-> Tagged os (StateT [Char] [] ar)
forall a b c. (a -> b -> c) -> b -> a -> c
flip (StateT [Char] [] Abs -> StateT [Char] [] ar)
-> Tagged os (StateT [Char] [] Abs)
-> Tagged os (StateT [Char] [] ar)
forall a b. (a -> b) -> Tagged os a -> Tagged os b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Tagged os (StateT [Char] [] Abs)
forall os. System os => Tagged os (StateT [Char] [] Abs)
readsSplitDriveAbs ((StateT [Char] [] Abs -> StateT [Char] [] ar)
 -> Tagged os (StateT [Char] [] ar))
-> (StateT [Char] [] Abs -> StateT [Char] [] ar)
-> Tagged os (StateT [Char] [] ar)
forall a b. (a -> b) -> a -> b
$ \StateT [Char] [] Abs
readsSplDrvAbs ->
        StateT [Char] [] Abs
-> StateT [Char] [] Rel
-> StateT [Char] [] AbsRel
-> StateT [Char] [] ar
forall ar (f :: * -> *).
AbsRel ar =>
f Abs -> f Rel -> f AbsRel -> f ar
forall (f :: * -> *). f Abs -> f Rel -> f AbsRel -> f ar
Class.switchAbsRel
            StateT [Char] [] Abs
readsSplDrvAbs
            StateT [Char] [] Rel
forall (m :: * -> *). MonadPlus m => StateT [Char] m Rel
readsSplitDriveRel
            (StateT [Char] [] AbsRel
-> StateT [Char] [] AbsRel -> StateT [Char] [] AbsRel
forall a.
StateT [Char] [] a -> StateT [Char] [] a -> StateT [Char] [] a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
mplus
                ((Abs -> AbsRel) -> StateT [Char] [] Abs -> StateT [Char] [] AbsRel
forall a b. (a -> b) -> StateT [Char] [] a -> StateT [Char] [] b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Part.Abs GenComponent
drive) -> GenComponent -> AbsRel
Part.AbsO GenComponent
drive) StateT [Char] [] Abs
readsSplDrvAbs)
                ((Rel -> AbsRel) -> StateT [Char] [] Rel -> StateT [Char] [] AbsRel
forall a b. (a -> b) -> StateT [Char] [] a -> StateT [Char] [] b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Rel
Part.Rel -> AbsRel
Part.RelO) StateT [Char] [] Rel
forall (m :: * -> *). MonadPlus m => StateT [Char] m Rel
readsSplitDriveRel))

readsSplitDriveAbs :: (System os) => Tagged os (MS.StateT String [] Part.Abs)
readsSplitDriveAbs :: forall os. System os => Tagged os (StateT [Char] [] Abs)
readsSplitDriveAbs =
    (([Char] -> StateT [Char] [] Abs)
 -> Tagged os [Char] -> Tagged os (StateT [Char] [] Abs))
-> Tagged os [Char]
-> ([Char] -> StateT [Char] [] Abs)
-> Tagged os (StateT [Char] [] Abs)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ([Char] -> StateT [Char] [] Abs)
-> Tagged os [Char] -> Tagged os (StateT [Char] [] Abs)
forall a b. (a -> b) -> Tagged os a -> Tagged os b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Tagged os [Char]
forall os. System os => Tagged os [Char]
rootStringTagged (([Char] -> StateT [Char] [] Abs)
 -> Tagged os (StateT [Char] [] Abs))
-> ([Char] -> StateT [Char] [] Abs)
-> Tagged os (StateT [Char] [] Abs)
forall a b. (a -> b) -> a -> b
$ \[Char]
root ->
        ([Char] -> Abs) -> StateT [Char] [] [Char] -> StateT [Char] [] Abs
forall a b. (a -> b) -> StateT [Char] [] a -> StateT [Char] [] b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Char] -> Abs
absPC (StateT [Char] [] [Char] -> StateT [Char] [] Abs)
-> StateT [Char] [] [Char] -> StateT [Char] [] Abs
forall a b. (a -> b) -> a -> b
$
            ([Char]
root [Char] -> StateT [Char] [] () -> StateT [Char] [] [Char]
forall a b. a -> StateT [Char] [] b -> StateT [Char] [] a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ [Char] -> StateT [Char] [] ()
forall (m :: * -> *). MonadPlus m => [Char] -> StateT [Char] m ()
matchString [Char]
rootName)
            StateT [Char] [] [Char]
-> StateT [Char] [] [Char] -> StateT [Char] [] [Char]
forall a.
StateT [Char] [] a -> StateT [Char] [] a -> StateT [Char] [] a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus`
            [Char] -> StateT [Char] [] [Char]
forall a. Read a => [Char] -> StateT [Char] [] a
readsCons [Char]
absDirName

readsSplitDriveRel :: (MonadPlus m) => MS.StateT String m Part.Rel
readsSplitDriveRel :: forall (m :: * -> *). MonadPlus m => StateT [Char] m Rel
readsSplitDriveRel = [Char] -> StateT [Char] m ()
forall (m :: * -> *). MonadPlus m => [Char] -> StateT [Char] m ()
matchString [Char]
currentName StateT [Char] m () -> StateT [Char] m Rel -> StateT [Char] m Rel
forall a b.
StateT [Char] m a -> StateT [Char] m b -> StateT [Char] m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Rel -> StateT [Char] m Rel
forall a. a -> StateT [Char] m a
forall (m :: * -> *) a. Monad m => a -> m a
return Rel
Part.Rel


-- | Convert the 'Path' into a plain 'String' as required for OS calls.
--
-- prop> \p -> Path.asPath (Path.toString p) == (p::Default.AbsFile)
toString ::
    (System os, Class.AbsRel ar, Class.FileDir fd) => Path os ar fd -> String
toString :: forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Path os ar fd -> [Char]
toString = (Path os ar fd -> [Char] -> [Char])
-> [Char] -> Path os ar fd -> [Char]
forall a b c. (a -> b -> c) -> b -> a -> c
flip Path os ar fd -> [Char] -> [Char]
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Path os ar fd -> [Char] -> [Char]
toStringS [Char]
""

{-# DEPRECATED getPathString "Use Path.toString instead." #-}

-- | Synonym of 'toString' intended for unqualified use.
getPathString ::
    (System os, Class.AbsRel ar, Class.FileDir fd) => Path os ar fd -> String
getPathString :: forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Path os ar fd -> [Char]
getPathString = Path os ar fd -> [Char]
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Path os ar fd -> [Char]
toString

toStringS ::
    (System os, Class.AbsRel ar, Class.FileDir fd) => Path os ar fd -> ShowS
toStringS :: forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Path os ar fd -> [Char] -> [Char]
toStringS Path os ar fd
x =
    case Path os ar fd -> (ar, [Component os])
forall fd os ar.
FileDir fd =>
Path os ar fd -> (ar, [Component os])
pathComponents Path os ar fd
x of
        (ar
ar, []) ->
            ([Char] -> [Char] -> [Char])
-> ([Char] -> [Char]) -> ar -> [Char] -> [Char]
forall ar a. AbsRel ar => ([Char] -> a) -> a -> ar -> a
Class.withAbsRel [Char] -> [Char] -> [Char]
showString ([Char] -> [Char] -> [Char]
showString [Char]
currentDirComponent) ar
ar
        (ar
ar, [Component os]
pcs) ->
            [[Char] -> [Char]] -> [Char] -> [Char]
concatS ([[Char] -> [Char]] -> [Char] -> [Char])
-> [[Char] -> [Char]] -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$
            ([Char] -> [[Char] -> [Char]] -> [[Char] -> [Char]])
-> ([[Char] -> [Char]] -> [[Char] -> [Char]])
-> ar
-> [[Char] -> [Char]]
-> [[Char] -> [Char]]
forall ar a. AbsRel ar => ([Char] -> a) -> a -> ar -> a
Class.withAbsRel (\[Char]
drive -> ([Char] -> [Char] -> [Char]
showString [Char]
drive ([Char] -> [Char]) -> [[Char] -> [Char]] -> [[Char] -> [Char]]
forall a. a -> [a] -> [a]
:)) [[Char] -> [Char]] -> [[Char] -> [Char]]
forall a. a -> a
id ar
ar ([[Char] -> [Char]] -> [[Char] -> [Char]])
-> [[Char] -> [Char]] -> [[Char] -> [Char]]
forall a b. (a -> b) -> a -> b
$
            ([Char] -> [Char]) -> [[Char] -> [Char]] -> [[Char] -> [Char]]
forall a. a -> [a] -> [a]
intersperse (Char -> [Char] -> [Char]
showChar (Path os ar fd -> Tagged os Char -> Char
forall os ar fd a. Path os ar fd -> Tagged os a -> a
selTag Path os ar fd
x Tagged os Char
forall os. System os => Tagged os Char
pathSeparator)) ([[Char] -> [Char]] -> [[Char] -> [Char]])
-> [[Char] -> [Char]] -> [[Char] -> [Char]]
forall a b. (a -> b) -> a -> b
$
            (Component os -> [Char] -> [Char])
-> [Component os] -> [[Char] -> [Char]]
forall a b. (a -> b) -> [a] -> [b]
map (\(Component [Char]
pc) -> [Char] -> [Char] -> [Char]
showString [Char]
pc) [Component os]
pcs


------------------------------------------------------------------------
-- Constants

-- prop> Posix.toString Path.rootDir == "/"
-- prop> Windows.toString Path.rootDir == "\\"
rootDir :: (System os) => AbsDir os
rootDir :: forall os. System os => AbsDir os
rootDir = Tagged os (AbsDir os) -> AbsDir os
forall {k} (s :: k) b. Tagged s b -> b
untag Tagged os (AbsDir os)
forall os. System os => Tagged os (AbsDir os)
rootDirTagged

rootDirTagged :: (System os) => Tagged os (AbsDir os)
rootDirTagged :: forall os. System os => Tagged os (AbsDir os)
rootDirTagged = ([Char] -> AbsDir os) -> Tagged os [Char] -> Tagged os (AbsDir os)
forall a b. (a -> b) -> Tagged os a -> Tagged os b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\[Char]
root -> Abs -> [Component os] -> Dir -> AbsDir os
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ([Char] -> Abs
absPC [Char]
root) [] Dir
Part.Dir) Tagged os [Char]
forall os. System os => Tagged os [Char]
rootStringTagged

rootStringTagged :: (System os) => Tagged os String
rootStringTagged :: forall os. System os => Tagged os [Char]
rootStringTagged = (Char -> [Char]) -> Tagged os Char -> Tagged os [Char]
forall a b. (a -> b) -> Tagged os a -> Tagged os b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Char
sep -> [Char
sep]) Tagged os Char
forall os. System os => Tagged os Char
pathSeparator

-- prop> Posix.toString Path.currentDir == "."
-- prop> Windows.toString Path.currentDir == "."
currentDir :: (System os) => RelDir os
currentDir :: forall os. System os => RelDir os
currentDir = RelDir os
forall a. Monoid a => a
mempty

{- |
This is a file with path @\"\"@.
You will not be able to create a file with this name.
We also forbid parsing @\"\"@ by 'relFile'.
You might only need this file path as intermediate step
when manipulating extensions of files like @\".bashrc\"@.
-}
emptyFile :: (System os) => RelFile os
emptyFile :: forall os. System os => RelFile os
emptyFile = File -> RelFile os
forall os. File -> RelFile os
atomicFile (File -> RelFile os) -> File -> RelFile os
forall a b. (a -> b) -> a -> b
$ GenComponent -> File
Part.File GenComponent
forall os. Component os
PC.empty

atomicFile :: Part.File -> RelFile os
atomicFile :: forall os. File -> RelFile os
atomicFile = Rel -> [Component os] -> File -> Path os Rel File
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path Rel
Part.Rel []

rootName :: String
rootName :: [Char]
rootName = [Char]
"rootDir"

currentName :: String
currentName :: [Char]
currentName = [Char]
"currentDir"

currentDirComponent :: String
currentDirComponent :: [Char]
currentDirComponent = [Char]
"."

absDirName :: String
absDirName :: [Char]
absDirName = [Char]
"absDir"

relPathName :: String
relPathName :: [Char]
relPathName = [Char]
"relPath"


------------------------------------------------------------------------
-- Parsing Functions

{-# DEPRECATED maybePath "Use Path.maybe instead." #-}
{-# DEPRECATED parsePath "Use Path.parse instead." #-}

-- | This function is intended for checking and parsing paths
--   provided as user input.
--
-- prop> fmap Posix.toString (Posix.maybePath "/" :: Maybe Posix.AbsDir) == Just "/"
-- prop> fmap Posix.toString (Posix.maybePath "/" :: Maybe Posix.AbsFile) == Nothing
-- prop> fmap Posix.toString (Posix.maybePath "/" :: Maybe Posix.RelDir) == Nothing
-- prop> fmap Posix.toString (Posix.maybePath "/" :: Maybe Posix.RelFile) == Nothing
-- prop> fmap Posix.toString (Posix.maybePath "/tmp" :: Maybe Posix.AbsDir) == Just "/tmp"
-- prop> fmap Posix.toString (Posix.maybePath "/tmp" :: Maybe Posix.AbsFile) == Just "/tmp"
-- prop> fmap Posix.toString (Posix.maybePath "/tmp" :: Maybe Posix.RelDir) == Nothing
-- prop> fmap Posix.toString (Posix.maybePath "/tmp" :: Maybe Posix.RelFile) == Nothing
-- prop> fmap Posix.toString (Posix.maybePath "/tmp/" :: Maybe Posix.AbsDir) == Just "/tmp"
-- prop> fmap Posix.toString (Posix.maybePath "/tmp/" :: Maybe Posix.AbsFile) == Nothing
-- prop> fmap Posix.toString (Posix.maybePath "/tmp/" :: Maybe Posix.RelDir) == Nothing
-- prop> fmap Posix.toString (Posix.maybePath "/tmp/" :: Maybe Posix.RelFile) == Nothing
-- prop> fmap Posix.toString (Posix.maybePath "/tmp" :: Maybe Posix.AbsRelFileDir) == Just "/tmp"
-- prop> fmap Posix.toString (Posix.maybePath "/tmp/" :: Maybe Posix.AbsRelFileDir) == Just "/tmp"
-- prop> fmap Posix.toString (Posix.maybePath "file.txt" :: Maybe Posix.RelFile) == Just "file.txt"
-- prop> fmap Posix.toString (Posix.maybePath "file.txt" :: Maybe Posix.AbsFile) == Nothing
-- prop> fmap Windows.toString (Windows.maybePath "\\tmp" :: Maybe Windows.AbsDir) == Just "\\tmp"
-- prop> fmap Windows.toString (Windows.maybePath "a:\\tmp" :: Maybe Windows.AbsDir) == Just "a:\\tmp"
-- prop> fmap Windows.toString (Windows.maybePath "a:tmp" :: Maybe Windows.AbsDir) == Just "a:tmp"
-- prop> fmap Windows.toString (Windows.maybePath "a:\\" :: Maybe Windows.AbsDir) == Just "a:\\"
-- prop> fmap Windows.toString (Windows.maybePath "a:" :: Maybe Windows.AbsDir) == Just "a:"
-- prop> fmap Windows.toString (Windows.maybePath "tmp" :: Maybe Windows.RelDir) == Just "tmp"
-- prop> fmap Windows.toString (Windows.maybePath "\\tmp" :: Maybe Windows.RelDir) == Nothing
-- prop> fmap Windows.toString (Windows.maybePath "a:\\tmp" :: Maybe Windows.RelDir) == Nothing
-- prop> fmap Windows.toString (Windows.maybePath "a:tmp" :: Maybe Windows.RelDir) == Nothing
-- prop> fmap Windows.toString (Windows.maybePath "tmp" :: Maybe Windows.AbsDir) == Nothing
maybe, maybePath ::
    (System os, Class.AbsRel ar, Class.FileDir fd) =>
    String -> Maybe (Path os ar fd)
maybe :: forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Maybe (Path os ar fd)
maybe [Char]
str = do
    let (AbsRel
ar0, [Component os]
pcs0, Either FileDir Dir
fd0) = Tagged os ([Char] -> (AbsRel, [Component os], Either FileDir Dir))
-> [Char] -> (AbsRel, [Component os], Either FileDir Dir)
forall {k} (s :: k) b. Tagged s b -> b
untag Tagged os ([Char] -> (AbsRel, [Component os], Either FileDir Dir))
forall os.
System os =>
Tagged os ([Char] -> (AbsRel, [Component os], Either FileDir Dir))
makePathComponents [Char]
str
    ar
ar <- AbsRel -> Maybe ar
forall ar. AbsRel ar => AbsRel -> Maybe ar
Class.fromAbsRel AbsRel
ar0
    ([Component os]
pcs, fd
fd) <-
        case Either FileDir Dir
fd0 of
            Left FileDir
Part.FileDir -> [Component os] -> Maybe ([Component os], fd)
forall fd os.
FileDir fd =>
[Component os] -> Maybe ([Component os], fd)
arrangeComponents [Component os]
pcs0
            Right Dir
Part.Dir ->
                (fd -> ([Component os], fd))
-> Maybe fd -> Maybe ([Component os], fd)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((,) [Component os]
pcs0) (Maybe fd -> Maybe ([Component os], fd))
-> Maybe fd -> Maybe ([Component os], fd)
forall a b. (a -> b) -> a -> b
$
                Maybe File -> Maybe Dir -> Maybe FileDir -> Maybe fd
forall fd (f :: * -> *).
FileDir fd =>
f File -> f Dir -> f FileDir -> f fd
forall (f :: * -> *). f File -> f Dir -> f FileDir -> f fd
Class.switchFileDir Maybe File
forall a. Maybe a
Nothing (Dir -> Maybe Dir
forall a. a -> Maybe a
Just Dir
Part.Dir) (FileDir -> Maybe FileDir
forall a. a -> Maybe a
Just FileDir
Part.FileDir)
    Path os ar fd -> Maybe (Path os ar fd)
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (Path os ar fd -> Maybe (Path os ar fd))
-> Path os ar fd -> Maybe (Path os ar fd)
forall a b. (a -> b) -> a -> b
$ ar -> [Component os] -> fd -> Path os ar fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar [Component os]
pcs fd
fd

maybePath :: forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Maybe (Path os ar fd)
maybePath = [Char] -> Maybe (Path os ar fd)
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Maybe (Path os ar fd)
maybe

parse, parsePath ::
    (System os, Class.AbsRel ar, Class.FileDir fd) =>
    String -> Either String (Path os ar fd)
parse :: forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Either [Char] (Path os ar fd)
parse = Const [Char] ar
-> Const [Char] fd -> [Char] -> Either [Char] (Path os ar fd)
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Const [Char] ar
-> Const [Char] fd -> [Char] -> Either [Char] (Path os ar fd)
pathWithNames Const [Char] ar
forall ar. AbsRel ar => Const [Char] ar
arName Const [Char] fd
forall fd. FileDir fd => Const [Char] fd
fdName
parsePath :: forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Either [Char] (Path os ar fd)
parsePath = [Char] -> Either [Char] (Path os ar fd)
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Either [Char] (Path os ar fd)
parse

pathWithNames ::
    (System os, Class.AbsRel ar, Class.FileDir fd) =>
    Const String ar -> Const String fd ->
    String -> Either String (Path os ar fd)
pathWithNames :: forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Const [Char] ar
-> Const [Char] fd -> [Char] -> Either [Char] (Path os ar fd)
pathWithNames (Const [Char]
ar) (Const [Char]
fd) [Char]
str =
    Either [Char] (Path os ar fd)
-> (Path os ar fd -> Either [Char] (Path os ar fd))
-> Maybe (Path os ar fd)
-> Either [Char] (Path os ar fd)
forall b a. b -> (a -> b) -> Maybe a -> b
P.maybe ([Char] -> Either [Char] (Path os ar fd)
forall a b. a -> Either a b
Left ([Char] -> [Char] -> [Char] -> [Char] -> [Char]
forall r. PrintfType r => [Char] -> r
printf [Char]
"\"%s\" is not a valid %s%spath" [Char]
str [Char]
ar [Char]
fd)) Path os ar fd -> Either [Char] (Path os ar fd)
forall a b. b -> Either a b
Right (Maybe (Path os ar fd) -> Either [Char] (Path os ar fd))
-> Maybe (Path os ar fd) -> Either [Char] (Path os ar fd)
forall a b. (a -> b) -> a -> b
$
    [Char] -> Maybe (Path os ar fd)
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Maybe (Path os ar fd)
maybePath [Char]
str

arName :: (Class.AbsRel ar) => Const String ar
arName :: forall ar. AbsRel ar => Const [Char] ar
arName = Const [Char] Abs
-> Const [Char] Rel -> Const [Char] AbsRel -> Const [Char] ar
forall ar (f :: * -> *).
AbsRel ar =>
f Abs -> f Rel -> f AbsRel -> f ar
forall (f :: * -> *). f Abs -> f Rel -> f AbsRel -> f ar
Class.switchAbsRel ([Char] -> Const [Char] Abs
forall {k} a (b :: k). a -> Const a b
Const [Char]
"absolute ") ([Char] -> Const [Char] Rel
forall {k} a (b :: k). a -> Const a b
Const [Char]
"relative ") ([Char] -> Const [Char] AbsRel
forall {k} a (b :: k). a -> Const a b
Const [Char]
"")

fdName :: (Class.FileDir fd) => Const String fd
fdName :: forall fd. FileDir fd => Const [Char] fd
fdName = Const [Char] File
-> Const [Char] Dir -> Const [Char] FileDir -> Const [Char] fd
forall fd (f :: * -> *).
FileDir fd =>
f File -> f Dir -> f FileDir -> f fd
forall (f :: * -> *). f File -> f Dir -> f FileDir -> f fd
Class.switchFileDir ([Char] -> Const [Char] File
forall {k} a (b :: k). a -> Const a b
Const [Char]
"file ") ([Char] -> Const [Char] Dir
forall {k} a (b :: k). a -> Const a b
Const [Char]
"directory ") ([Char] -> Const [Char] FileDir
forall {k} a (b :: k). a -> Const a b
Const [Char]
"")

------------------------------------------------------------------------
-- Checked Construction Functions

-- | This function is intended for converting path strings
--   with known content, e.g. string literals, to the 'Path' type.
path ::
    (System os, Class.AbsRel ar, Class.FileDir fd) =>
    String -> Path os ar fd
path :: forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path = ([Char] -> Path os ar fd)
-> (Path os ar fd -> Path os ar fd)
-> Either [Char] (Path os ar fd)
-> Path os ar fd
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either [Char] -> Path os ar fd
forall a. HasCallStack => [Char] -> a
error Path os ar fd -> Path os ar fd
forall a. a -> a
id (Either [Char] (Path os ar fd) -> Path os ar fd)
-> ([Char] -> Either [Char] (Path os ar fd))
-> [Char]
-> Path os ar fd
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Either [Char] (Path os ar fd)
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Either [Char] (Path os ar fd)
parsePath

-- | Construct a 'RelFile' from a 'String'.
--
-- prop> Posix.toString (Posix.relFile "file.txt") == "file.txt"
-- prop> Posix.toString (Posix.relFile "tmp") == "tmp"
relFile :: (System os) => String -> RelFile os
relFile :: forall os. System os => [Char] -> RelFile os
relFile = [Char] -> Path os Rel File
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path

-- | Construct a 'RelDir' from a 'String'.
--
-- prop> Posix.toString (Posix.relDir ".") == "."
-- prop> Posix.toString (Posix.relDir "file.txt") == "file.txt"
-- prop> Posix.toString (Posix.relDir "tmp") == "tmp"
relDir :: (System os) => String -> RelDir os
relDir :: forall os. System os => [Char] -> RelDir os
relDir = [Char] -> Path os Rel Dir
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path

-- | Construct an 'AbsFile' from a 'String'.
--
-- prop> Posix.toString (Posix.absFile "/file.txt") == "/file.txt"
-- prop> Posix.toString (Posix.absFile "/tmp") == "/tmp"
absFile :: (System os) => String -> AbsFile os
absFile :: forall os. System os => [Char] -> AbsFile os
absFile = [Char] -> Path os Abs File
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path

-- | Construct an 'AbsDir' from a 'String'.
--
-- prop> Posix.toString (Posix.absDir "/file.txt") == "/file.txt"
-- prop> Posix.toString (Posix.absDir "/tmp") == "/tmp"
absDir :: (System os) => String -> AbsDir os
absDir :: forall os. System os => [Char] -> AbsDir os
absDir = [Char] -> Path os Abs Dir
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path

-- | Construct a 'Rel fd' from a 'String'.
rel :: (System os, Class.FileDir fd) => String -> Rel os fd
rel :: forall os fd. (System os, FileDir fd) => [Char] -> Rel os fd
rel = [Char] -> Path os Rel fd
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path

-- | Construct an 'Abs fd' from a 'String'.
abs :: (System os, Class.FileDir fd) => String -> Abs os fd
abs :: forall os fd. (System os, FileDir fd) => [Char] -> Abs os fd
abs = [Char] -> Path os Abs fd
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path

-- | Construct an 'AbsRel fd' from a 'String'.
absRel :: (System os, Class.FileDir fd) => String -> AbsRel os fd
absRel :: forall os fd. (System os, FileDir fd) => [Char] -> AbsRel os fd
absRel = [Char] -> Path os AbsRel fd
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path

-- | Construct a 'File ar' from a 'String'.
file :: (System os, Class.AbsRel ar) => String -> File os ar
file :: forall os ar. (System os, AbsRel ar) => [Char] -> File os ar
file = [Char] -> Path os ar File
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path

-- | Construct a 'Dir ar' from a 'String'.
dir :: (System os, Class.AbsRel ar) => String -> Dir os ar
dir :: forall os ar. (System os, AbsRel ar) => [Char] -> Dir os ar
dir = [Char] -> Path os ar Dir
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path

-- | Construct a 'FileDir ar' from a 'String'.
fileDir :: (System os, Class.AbsRel ar) => String -> FileDir os ar
fileDir :: forall os ar. (System os, AbsRel ar) => [Char] -> FileDir os ar
fileDir = [Char] -> Path os ar FileDir
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path


{-# DEPRECATED relPath    "Use Path.rel instead." #-}
{-# DEPRECATED absPath    "Use Path.abs instead." #-}
{-# DEPRECATED filePath   "Use Path.file instead." #-}
{-# DEPRECATED dirPath    "Use Path.dir instead." #-}

-- | Construct a 'RelPath fd' from a 'String'.
relPath :: (System os, Class.FileDir fd) => String -> RelPath os fd
relPath :: forall os fd. (System os, FileDir fd) => [Char] -> Rel os fd
relPath = [Char] -> Path os Rel fd
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path

-- | Construct an 'AbsPath fd' from a 'String'.
absPath :: (System os, Class.FileDir fd) => String -> AbsPath os fd
absPath :: forall os fd. (System os, FileDir fd) => [Char] -> Abs os fd
absPath = [Char] -> Path os Abs fd
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path

-- | Construct a 'FilePath ar' from a 'String'.
filePath :: (System os, Class.AbsRel ar) => String -> FilePath os ar
filePath :: forall os ar. (System os, AbsRel ar) => [Char] -> File os ar
filePath = [Char] -> Path os ar File
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path

-- | Construct a 'DirPath ar' from a 'String'.
dirPath :: (System os, Class.AbsRel ar) => String -> DirPath os ar
dirPath :: forall os ar. (System os, AbsRel ar) => [Char] -> Dir os ar
dirPath = [Char] -> Path os ar Dir
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path



idAbsRel :: AbsRelPath os fd -> AbsRelPath os fd
idAbsRel :: forall os fd. AbsRelPath os fd -> AbsRelPath os fd
idAbsRel = AbsRelPath os fd -> AbsRelPath os fd
forall a. a -> a
id

idAbs :: AbsPath os fd -> AbsPath os fd
idAbs :: forall os fd. AbsPath os fd -> AbsPath os fd
idAbs = AbsPath os fd -> AbsPath os fd
forall a. a -> a
id

idRel :: RelPath os fd -> RelPath os fd
idRel :: forall os fd. RelPath os fd -> RelPath os fd
idRel = RelPath os fd -> RelPath os fd
forall a. a -> a
id


idFileDir :: FileDirPath os fd -> FileDirPath os fd
idFileDir :: forall os fd. FileDirPath os fd -> FileDirPath os fd
idFileDir = FileDirPath os fd -> FileDirPath os fd
forall a. a -> a
id

idFile :: FilePath os fd -> FilePath os fd
idFile :: forall os fd. FilePath os fd -> FilePath os fd
idFile = FilePath os fd -> FilePath os fd
forall a. a -> a
id

idDir :: DirPath os fd -> DirPath os fd
idDir :: forall os fd. DirPath os fd -> DirPath os fd
idDir = DirPath os fd -> DirPath os fd
forall a. a -> a
id


{-# DEPRECATED asPath "Use 'maybePath', 'parsePath' or 'path' instead." #-}
{-# DEPRECATED asRelFile "Use 'relFile' instead." #-}
{-# DEPRECATED asRelDir "Use 'relDir' instead." #-}
{-# DEPRECATED asAbsFile "Use 'absFile' instead." #-}
{-# DEPRECATED asAbsDir "Use 'absDir' instead." #-}
{-# DEPRECATED asRelPath "Use 'relPath' instead." #-}
{-# DEPRECATED asAbsPath "Use 'absPath' instead." #-}
{-# DEPRECATED asFilePath "Use 'filePath' instead." #-}
{-# DEPRECATED asDirPath "Use 'dirPath' instead." #-}

------------------------------------------------------------------------
-- Unchecked Construction Functions
-- NB - these construction functions are non-IO and do no checking!!

-- | Use a 'String' as a 'Path' whose type is determined by its context.
--   You should not use this and other @as*@ functions,
--   since they may silently turn a relative path to an absolute one,
--   or vice versa, or they may accept a path as file path
--   although it ends on a slash.
--   If you are certain about the string content
--   then you should use 'path'.
--   If you got the string as user input then use 'maybePath' or 'parsePath'.
--
-- prop> Posix.asPath "/tmp" == Posix.absDir "/tmp"
-- prop> Posix.asPath "file.txt" == Posix.relFile "file.txt"
-- prop> Path.isAbsolute (Posix.asAbsDir "/tmp")
-- prop> Path.isRelative (Posix.asRelDir "/tmp")
-- prop> Posix.toString (Posix.asPath "/tmp" :: Posix.AbsDir) == "/tmp"
-- prop> Posix.toString (Posix.asPath "/tmp" :: Posix.RelDir) == "tmp"
-- prop> Windows.toString (Windows.asPath "\\tmp" :: Windows.AbsDir) == "\\tmp"
-- prop> Windows.toString (Windows.asPath "a:\\tmp" :: Windows.AbsDir) == "a:\\tmp"
-- prop> Windows.toString (Windows.asPath "a:tmp" :: Windows.AbsDir) == "a:tmp"
-- prop> Windows.toString (Windows.asPath "tmp" :: Windows.RelDir) == "tmp"
asPath ::
    (System os, Class.AbsRel ar, Class.FileDir fd) => String -> Path os ar fd
asPath :: forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
asPath = (ar -> [Component os] -> Path os ar fd)
-> (ar, [Component os]) -> Path os ar fd
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ar -> [Component os] -> Path os ar fd
forall fd ar os.
FileDir fd =>
ar -> [Component os] -> Path os ar fd
mkPathFromComponents ((ar, [Component os]) -> Path os ar fd)
-> ([Char] -> (ar, [Component os])) -> [Char] -> Path os ar fd
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tagged os ([Char] -> (ar, [Component os]))
-> [Char] -> (ar, [Component os])
forall {k} (s :: k) b. Tagged s b -> b
untag Tagged os ([Char] -> (ar, [Component os]))
forall os ar.
(System os, AbsRel ar) =>
Tagged os ([Char] -> (ar, [Component os]))
mkPathComponents


-- | Use a 'String' as a 'RelFile'. No checking is done.
--
-- prop> Posix.toString (Posix.asRelFile "file.txt") == "file.txt"
-- prop> Posix.toString (Posix.asRelFile "/file.txt") == "file.txt"
-- prop> Posix.toString (Posix.asRelFile "tmp") == "tmp"
-- prop> Posix.toString (Posix.asRelFile "/tmp") == "tmp"
asRelFile :: (System os) => String -> RelFile os
asRelFile :: forall os. System os => [Char] -> RelFile os
asRelFile = [Char] -> Path os Rel File
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
asPath

-- | Use a 'String' as a 'RelDir'. No checking is done.
--
-- prop> Posix.toString (Posix.asRelDir ".") == "."
-- prop> Posix.toString (Posix.asRelDir "file.txt") == "file.txt"
-- prop> Posix.toString (Posix.asRelDir "/file.txt") == "file.txt"
-- prop> Posix.toString (Posix.asRelDir "tmp") == "tmp"
-- prop> Posix.toString (Posix.asRelDir "/tmp") == "tmp"
asRelDir :: (System os) => String -> RelDir os
asRelDir :: forall os. System os => [Char] -> RelDir os
asRelDir = [Char] -> Path os Rel Dir
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
asPath

-- | Use a 'String' as an 'AbsFile'. No checking is done.
--
-- prop> Posix.toString (Posix.asAbsFile "/file.txt") == "/file.txt"
-- prop> Posix.toString (Posix.asAbsFile "/tmp") == "/tmp"
asAbsFile :: (System os) => String -> AbsFile os
asAbsFile :: forall os. System os => [Char] -> AbsFile os
asAbsFile = [Char] -> Path os Abs File
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
asPath

-- | Use a 'String' as an 'AbsDir'. No checking is done.
--
-- prop> Posix.toString (Posix.asAbsDir "/file.txt") == "/file.txt"
-- prop> Posix.toString (Posix.asAbsDir "/tmp") == "/tmp"
asAbsDir :: (System os) => String -> AbsDir os
asAbsDir :: forall os. System os => [Char] -> AbsDir os
asAbsDir = [Char] -> Path os Abs Dir
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
asPath

-- | Use a 'String' as a 'RelPath fd'. No checking is done.
asRelPath :: (System os, Class.FileDir fd) => String -> RelPath os fd
asRelPath :: forall os fd. (System os, FileDir fd) => [Char] -> Rel os fd
asRelPath = [Char] -> Path os Rel fd
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
asPath

-- | Use a 'String' as an 'AbsPath fd'. No checking is done.
asAbsPath :: (System os, Class.FileDir fd) => String -> AbsPath os fd
asAbsPath :: forall os fd. (System os, FileDir fd) => [Char] -> Abs os fd
asAbsPath = [Char] -> Path os Abs fd
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
asPath

-- | Use a 'String' as a 'FilePath ar'. No checking is done.
asFilePath :: (System os, Class.AbsRel ar) => String -> FilePath os ar
asFilePath :: forall os ar. (System os, AbsRel ar) => [Char] -> File os ar
asFilePath = [Char] -> Path os ar File
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
asPath

-- | Use a 'String' as a 'DirPath ar'. No checking is done.
asDirPath :: (System os, Class.AbsRel ar) => String -> DirPath os ar
asDirPath :: forall os ar. (System os, AbsRel ar) => [Char] -> Dir os ar
asDirPath = [Char] -> Path os ar Dir
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
asPath

-- | Forbid use of OverloadedStrings and prevent custom orphan instances
instance
    (ForbiddenSystem os, ForbiddenAbsRel ar, ForbiddenFileDir fd) =>
        IsString (Path os ar fd) where fromString :: [Char] -> Path os ar fd
fromString = [Char] -> Path os ar fd
forall os ar fd. ForbiddenSystem os => [Char] -> Path os ar fd
forall ar fd. [Char] -> Path os ar fd
forbiddenFromString

class System os => ForbiddenSystem os where
    forbiddenFromString :: String -> Path os ar fd

class Class.AbsRel ar => ForbiddenAbsRel ar where
class Class.FileDir fd => ForbiddenFileDir fd where

------------------------------------------------------------------------
-- Checked Construction Functions

{-# DEPRECATED mkPathAbsOrRel "Use Path.absRel instead." #-}

-- | Examines the supplied string and constructs an absolute or
-- relative path as appropriate.
--
-- prop> Path.mkPathAbsOrRel "/tmp" == Left (Posix.absDir "/tmp")
-- prop> Path.mkPathAbsOrRel  "tmp" == Right (Posix.relDir "tmp")
-- prop> Path.mkPathAbsOrRel "\\tmp" == Left (Windows.absDir "\\tmp")
-- prop> Path.mkPathAbsOrRel "d:\\tmp" == Left (Windows.absDir "d:\\tmp")
-- prop> Path.mkPathAbsOrRel "d:tmp" == Left (Windows.absDir "d:tmp")
-- prop> Path.mkPathAbsOrRel "tmp" == Right (Windows.relDir "tmp")
mkPathAbsOrRel, mkPathAbsOrRelPriv ::
    (System os, Class.FileDir fd) =>
    String -> Either (AbsPath os fd) (RelPath os fd)
mkPathAbsOrRel :: forall os fd.
(System os, FileDir fd) =>
[Char] -> Either (AbsPath os fd) (RelPath os fd)
mkPathAbsOrRel = [Char] -> Either (AbsPath os fd) (RelPath os fd)
forall os fd.
(System os, FileDir fd) =>
[Char] -> Either (AbsPath os fd) (RelPath os fd)
mkPathAbsOrRelPriv
mkPathAbsOrRelPriv :: forall os fd.
(System os, FileDir fd) =>
[Char] -> Either (AbsPath os fd) (RelPath os fd)
mkPathAbsOrRelPriv = Path os AbsRel fd -> Either (AbsPath os fd) (RelPath os fd)
forall ar os fd.
AbsRel ar =>
Path os ar fd -> Either (AbsPath os fd) (RelPath os fd)
eitherFromAbsRel (Path os AbsRel fd -> Either (AbsPath os fd) (RelPath os fd))
-> ([Char] -> Path os AbsRel fd)
-> [Char]
-> Either (AbsPath os fd) (RelPath os fd)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Path os AbsRel fd
forall os fd. (System os, FileDir fd) => [Char] -> AbsRel os fd
absRel

{-# DEPRECATED mkPathFileOrDir "Don't let the path type depend on current file system content. Instead choose the path type according to the needed disk object type." #-}

-- | Searches for a file or directory with the supplied path string
--   and returns a 'Part.File' or 'Part.Dir' path as appropriate. If neither exists
--   at the supplied path, 'Nothing' is returned.
mkPathFileOrDir ::
    (System os, Class.AbsRel ar) =>
    String -> IO (Maybe (Either (FilePath os ar) (DirPath os ar)))
mkPathFileOrDir :: forall os ar.
(System os, AbsRel ar) =>
[Char] -> IO (Maybe (Either (FilePath os ar) (DirPath os ar)))
mkPathFileOrDir [Char]
s = do
  Bool
isfile <- [Char] -> IO Bool
SD.doesFileExist [Char]
s
  Bool
isdir <- [Char] -> IO Bool
SD.doesDirectoryExist [Char]
s
  case (Bool
isfile, Bool
isdir) of
    (Bool
False, Bool
False) -> Maybe (Either (FilePath os ar) (DirPath os ar))
-> IO (Maybe (Either (FilePath os ar) (DirPath os ar)))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Either (FilePath os ar) (DirPath os ar))
forall a. Maybe a
Nothing
    (Bool
True,  Bool
False) -> Maybe (Either (FilePath os ar) (DirPath os ar))
-> IO (Maybe (Either (FilePath os ar) (DirPath os ar)))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Either (FilePath os ar) (DirPath os ar))
 -> IO (Maybe (Either (FilePath os ar) (DirPath os ar))))
-> Maybe (Either (FilePath os ar) (DirPath os ar))
-> IO (Maybe (Either (FilePath os ar) (DirPath os ar)))
forall a b. (a -> b) -> a -> b
$ Either (FilePath os ar) (DirPath os ar)
-> Maybe (Either (FilePath os ar) (DirPath os ar))
forall a. a -> Maybe a
Just (Either (FilePath os ar) (DirPath os ar)
 -> Maybe (Either (FilePath os ar) (DirPath os ar)))
-> Either (FilePath os ar) (DirPath os ar)
-> Maybe (Either (FilePath os ar) (DirPath os ar))
forall a b. (a -> b) -> a -> b
$ FilePath os ar -> Either (FilePath os ar) (DirPath os ar)
forall a b. a -> Either a b
Left (FilePath os ar -> Either (FilePath os ar) (DirPath os ar))
-> FilePath os ar -> Either (FilePath os ar) (DirPath os ar)
forall a b. (a -> b) -> a -> b
$ [Char] -> FilePath os ar
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path [Char]
s
    (Bool
False, Bool
True ) -> Maybe (Either (FilePath os ar) (DirPath os ar))
-> IO (Maybe (Either (FilePath os ar) (DirPath os ar)))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Either (FilePath os ar) (DirPath os ar))
 -> IO (Maybe (Either (FilePath os ar) (DirPath os ar))))
-> Maybe (Either (FilePath os ar) (DirPath os ar))
-> IO (Maybe (Either (FilePath os ar) (DirPath os ar)))
forall a b. (a -> b) -> a -> b
$ Either (FilePath os ar) (DirPath os ar)
-> Maybe (Either (FilePath os ar) (DirPath os ar))
forall a. a -> Maybe a
Just (Either (FilePath os ar) (DirPath os ar)
 -> Maybe (Either (FilePath os ar) (DirPath os ar)))
-> Either (FilePath os ar) (DirPath os ar)
-> Maybe (Either (FilePath os ar) (DirPath os ar))
forall a b. (a -> b) -> a -> b
$ DirPath os ar -> Either (FilePath os ar) (DirPath os ar)
forall a b. b -> Either a b
Right (DirPath os ar -> Either (FilePath os ar) (DirPath os ar))
-> DirPath os ar -> Either (FilePath os ar) (DirPath os ar)
forall a b. (a -> b) -> a -> b
$ [Char] -> DirPath os ar
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
[Char] -> Path os ar fd
path [Char]
s
    (Bool
True,  Bool
True ) -> IOError -> IO (Maybe (Either (FilePath os ar) (DirPath os ar)))
forall a. IOError -> IO a
ioError (IOError -> IO (Maybe (Either (FilePath os ar) (DirPath os ar))))
-> IOError -> IO (Maybe (Either (FilePath os ar) (DirPath os ar)))
forall a b. (a -> b) -> a -> b
$ [Char] -> IOError
userError [Char]
"mkPathFileOrDir - object type changed while checking"

{-# DEPRECATED mkAbsPath "Use Path.dynamicMakeAbsolute instead." #-}

-- | Convert a 'String' into an 'AbsPath' by interpreting it as
--   relative to the supplied directory if necessary.
--
-- prop> Path.mkAbsPath (absDir "/tmp") "foo.txt" == Posix.absFile "/tmp/foo.txt"
-- prop> Path.mkAbsPath (absDir "/tmp") "/etc/foo.txt" == Posix.absFile "/etc/foo.txt"
mkAbsPath ::
    (System os, Class.FileDir fd) => AbsDir os -> String -> AbsPath os fd
mkAbsPath :: forall os fd.
(System os, FileDir fd) =>
AbsDir os -> [Char] -> AbsPath os fd
mkAbsPath AbsDir os
d = (AbsPath os fd -> AbsPath os fd)
-> (RelPath os fd -> AbsPath os fd)
-> Either (AbsPath os fd) (RelPath os fd)
-> AbsPath os fd
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either AbsPath os fd -> AbsPath os fd
forall a. a -> a
id (AbsDir os -> RelPath os fd -> AbsPath os fd
forall os fd.
System os =>
AbsDir os -> RelPath os fd -> AbsPath os fd
makeAbsolute AbsDir os
d) (Either (AbsPath os fd) (RelPath os fd) -> AbsPath os fd)
-> ([Char] -> Either (AbsPath os fd) (RelPath os fd))
-> [Char]
-> AbsPath os fd
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Either (AbsPath os fd) (RelPath os fd)
forall os fd.
(System os, FileDir fd) =>
[Char] -> Either (AbsPath os fd) (RelPath os fd)
mkPathAbsOrRelPriv

{-# DEPRECATED mkAbsPathFromCwd "Use Path.dynamicMakeAbsoluteFromCwd instead." #-}

-- | Convert a 'String' into an 'AbsPath' by interpreting it as
--   relative to the cwd if necessary.
mkAbsPathFromCwd ::
    (System os, Class.FileDir fd) => String -> IO (AbsPath os fd)
mkAbsPathFromCwd :: forall os fd.
(System os, FileDir fd) =>
[Char] -> IO (AbsPath os fd)
mkAbsPathFromCwd = (AbsPath os fd -> IO (AbsPath os fd))
-> (RelPath os fd -> IO (AbsPath os fd))
-> Either (AbsPath os fd) (RelPath os fd)
-> IO (AbsPath os fd)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either AbsPath os fd -> IO (AbsPath os fd)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return RelPath os fd -> IO (AbsPath os fd)
forall os fd. System os => RelPath os fd -> IO (AbsPath os fd)
makeAbsoluteFromCwd (Either (AbsPath os fd) (RelPath os fd) -> IO (AbsPath os fd))
-> ([Char] -> Either (AbsPath os fd) (RelPath os fd))
-> [Char]
-> IO (AbsPath os fd)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Either (AbsPath os fd) (RelPath os fd)
forall os fd.
(System os, FileDir fd) =>
[Char] -> Either (AbsPath os fd) (RelPath os fd)
mkPathAbsOrRelPriv


------------------------------------------------------------------------
-- Internal Functions for GenComponent manipulation

mkPathFromComponents ::
    (Class.FileDir fd) => ar -> [Component os] -> Path os ar fd
mkPathFromComponents :: forall fd ar os.
FileDir fd =>
ar -> [Component os] -> Path os ar fd
mkPathFromComponents ar
ar [Component os]
pcs =
    ([Component os] -> fd -> Path os ar fd)
-> ([Component os], fd) -> Path os ar fd
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (ar -> [Component os] -> fd -> Path os ar fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar) (([Component os], fd) -> Path os ar fd)
-> ([Component os], fd) -> Path os ar fd
forall a b. (a -> b) -> a -> b
$
    ([Component os], File)
-> ([Component os], Dir)
-> ([Component os], FileDir)
-> ([Component os], fd)
forall fd (f :: * -> *).
FileDir fd =>
f File -> f Dir -> f FileDir -> f fd
forall (f :: * -> *). f File -> f Dir -> f FileDir -> f fd
Class.switchFileDir
        ((GenComponent -> File)
-> ([Component os], GenComponent) -> ([Component os], File)
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd GenComponent -> File
Part.File (([Component os], GenComponent) -> ([Component os], File))
-> ([Component os], GenComponent) -> ([Component os], File)
forall a b. (a -> b) -> a -> b
$
         ([Component os], GenComponent)
-> ([Component os]
    -> Component os -> ([Component os], GenComponent))
-> [Component os]
-> ([Component os], GenComponent)
forall b a. b -> ([a] -> a -> b) -> [a] -> b
ListHT.switchR ([], GenComponent
forall os. Component os
PC.empty) ((([Component os], Component os) -> ([Component os], GenComponent))
-> [Component os] -> Component os -> ([Component os], GenComponent)
forall a b c. ((a, b) -> c) -> a -> b -> c
curry ((([Component os], Component os) -> ([Component os], GenComponent))
 -> [Component os]
 -> Component os
 -> ([Component os], GenComponent))
-> (([Component os], Component os)
    -> ([Component os], GenComponent))
-> [Component os]
-> Component os
-> ([Component os], GenComponent)
forall a b. (a -> b) -> a -> b
$ (Component os -> GenComponent)
-> ([Component os], Component os) -> ([Component os], GenComponent)
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd Component os -> GenComponent
forall os. Component os -> GenComponent
PC.untag) [Component os]
pcs)
        ([Component os]
pcs, Dir
Part.Dir)
        ([Component os]
pcs, FileDir
Part.FileDir)

maybePathFromComponents ::
    (Class.FileDir fd) => ar -> [Component os] -> Maybe (Path os ar fd)
maybePathFromComponents :: forall fd ar os.
FileDir fd =>
ar -> [Component os] -> Maybe (Path os ar fd)
maybePathFromComponents ar
ar [Component os]
pcs =
    (([Component os], fd) -> Path os ar fd)
-> Maybe ([Component os], fd) -> Maybe (Path os ar fd)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([Component os] -> fd -> Path os ar fd)
-> ([Component os], fd) -> Path os ar fd
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (([Component os] -> fd -> Path os ar fd)
 -> ([Component os], fd) -> Path os ar fd)
-> ([Component os] -> fd -> Path os ar fd)
-> ([Component os], fd)
-> Path os ar fd
forall a b. (a -> b) -> a -> b
$ ar -> [Component os] -> fd -> Path os ar fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar) (Maybe ([Component os], fd) -> Maybe (Path os ar fd))
-> Maybe ([Component os], fd) -> Maybe (Path os ar fd)
forall a b. (a -> b) -> a -> b
$ [Component os] -> Maybe ([Component os], fd)
forall fd os.
FileDir fd =>
[Component os] -> Maybe ([Component os], fd)
arrangeComponents [Component os]
pcs

arrangeComponents ::
    (Class.FileDir fd) => [Component os] -> Maybe ([Component os], fd)
arrangeComponents :: forall fd os.
FileDir fd =>
[Component os] -> Maybe ([Component os], fd)
arrangeComponents [Component os]
pcs =
    Compose Maybe ((,) [Component os]) fd -> Maybe ([Component os], fd)
forall {k1} {k2} (f :: k1 -> *) (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose (Compose Maybe ((,) [Component os]) fd
 -> Maybe ([Component os], fd))
-> Compose Maybe ((,) [Component os]) fd
-> Maybe ([Component os], fd)
forall a b. (a -> b) -> a -> b
$
    Compose Maybe ((,) [Component os]) File
-> Compose Maybe ((,) [Component os]) Dir
-> Compose Maybe ((,) [Component os]) FileDir
-> Compose Maybe ((,) [Component os]) fd
forall fd (f :: * -> *).
FileDir fd =>
f File -> f Dir -> f FileDir -> f fd
forall (f :: * -> *). f File -> f Dir -> f FileDir -> f fd
Class.switchFileDir
        (Maybe ([Component os], File)
-> Compose Maybe ((,) [Component os]) File
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (Maybe ([Component os], File)
 -> Compose Maybe ((,) [Component os]) File)
-> Maybe ([Component os], File)
-> Compose Maybe ((,) [Component os]) File
forall a b. (a -> b) -> a -> b
$ (([Component os], Component os) -> ([Component os], File))
-> Maybe ([Component os], Component os)
-> Maybe ([Component os], File)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Component os -> File)
-> ([Component os], Component os) -> ([Component os], File)
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd (GenComponent -> File
Part.File (GenComponent -> File)
-> (Component os -> GenComponent) -> Component os -> File
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Component os -> GenComponent
forall os. Component os -> GenComponent
PC.untag)) (Maybe ([Component os], Component os)
 -> Maybe ([Component os], File))
-> Maybe ([Component os], Component os)
-> Maybe ([Component os], File)
forall a b. (a -> b) -> a -> b
$ [Component os] -> Maybe ([Component os], Component os)
forall a. [a] -> Maybe ([a], a)
ListHT.viewR [Component os]
pcs)
        (Maybe ([Component os], Dir)
-> Compose Maybe ((,) [Component os]) Dir
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (Maybe ([Component os], Dir)
 -> Compose Maybe ((,) [Component os]) Dir)
-> Maybe ([Component os], Dir)
-> Compose Maybe ((,) [Component os]) Dir
forall a b. (a -> b) -> a -> b
$ ([Component os], Dir) -> Maybe ([Component os], Dir)
forall a. a -> Maybe a
Just ([Component os]
pcs, Dir
Part.Dir))
        (Maybe ([Component os], FileDir)
-> Compose Maybe ((,) [Component os]) FileDir
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (Maybe ([Component os], FileDir)
 -> Compose Maybe ((,) [Component os]) FileDir)
-> Maybe ([Component os], FileDir)
-> Compose Maybe ((,) [Component os]) FileDir
forall a b. (a -> b) -> a -> b
$ ([Component os], FileDir) -> Maybe ([Component os], FileDir)
forall a. a -> Maybe a
Just ([Component os]
pcs, FileDir
Part.FileDir))

mkPathComponents ::
    (System os, Class.AbsRel ar) =>
    Tagged os (String -> (ar, [Component os]))
mkPathComponents :: forall os ar.
(System os, AbsRel ar) =>
Tagged os ([Char] -> (ar, [Component os]))
mkPathComponents =
    ((Char -> Bool)
 -> State [Char] ar -> [Char] -> (ar, [Component os]))
-> Tagged os (Char -> Bool)
-> Tagged os (State [Char] ar)
-> Tagged os ([Char] -> (ar, [Component os]))
forall a b c.
(a -> b -> c) -> Tagged os a -> Tagged os b -> Tagged os c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2
        (\Char -> Bool
isSep State [Char] ar
splDriveOS ->
            ([Char] -> [Component os]) -> (ar, [Char]) -> (ar, [Component os])
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd ([[Char]] -> [Component os]
forall os. [[Char]] -> [Component os]
nonEmptyComponents ([[Char]] -> [Component os])
-> ([Char] -> [[Char]]) -> [Char] -> [Component os]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> [Char] -> [[Char]]
forall a. (a -> Bool) -> [a] -> [[a]]
ListHT.chop Char -> Bool
isSep)
             ((ar, [Char]) -> (ar, [Component os]))
-> ([Char] -> (ar, [Char])) -> [Char] -> (ar, [Component os])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. State [Char] ar -> [Char] -> (ar, [Char])
forall s a. State s a -> s -> (a, s)
MS.runState State [Char] ar
splDriveOS)
        Tagged os (Char -> Bool)
forall os. System os => Tagged os (Char -> Bool)
isPathSeparator Tagged os (State [Char] ar)
forall os ar. (System os, AbsRel ar) => Tagged os (State [Char] ar)
splitDriveOS

{- |
Parse path string independent from expectations
expressed by the type parameters.
-}
makePathComponents ::
    (System os) =>
    Tagged os
        (String ->
            (Part.AbsRel, [Component os], Either Part.FileDir Part.Dir))
makePathComponents :: forall os.
System os =>
Tagged os ([Char] -> (AbsRel, [Component os], Either FileDir Dir))
makePathComponents =
    ((Char -> Bool)
 -> State [Char] AbsRel
 -> [Char]
 -> (AbsRel, [Component os], Either FileDir Dir))
-> Tagged os (Char -> Bool)
-> Tagged os (State [Char] AbsRel)
-> Tagged
     os ([Char] -> (AbsRel, [Component os], Either FileDir Dir))
forall a b c.
(a -> b -> c) -> Tagged os a -> Tagged os b -> Tagged os c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2
        (\Char -> Bool
isSep State [Char] AbsRel
splAbsolute [Char]
str ->
            let (AbsRel
ar, [[Char]]
pct) =
                    ([Char] -> [[Char]]) -> (AbsRel, [Char]) -> (AbsRel, [[Char]])
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd ((Char -> Bool) -> [Char] -> [[Char]]
forall a. (a -> Bool) -> [a] -> [[a]]
ListHT.chop Char -> Bool
isSep) ((AbsRel, [Char]) -> (AbsRel, [[Char]]))
-> (AbsRel, [Char]) -> (AbsRel, [[Char]])
forall a b. (a -> b) -> a -> b
$
                    State [Char] AbsRel -> [Char] -> (AbsRel, [Char])
forall s a. State s a -> s -> (a, s)
MS.runState State [Char] AbsRel
splAbsolute [Char]
str
                ([[Char]]
pcs1, Either FileDir Dir
fd) =
                    case [[Char]] -> Maybe ([[Char]], [Char])
forall a. [a] -> Maybe ([a], a)
ListHT.viewR [[Char]]
pct of
                        Maybe ([[Char]], [Char])
Nothing -> ([], Dir -> Either FileDir Dir
forall a b. b -> Either a b
Right Dir
Part.Dir)
                        Just ([[Char]]
pcs, [Char]
pc) ->
                            if [Char] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Char]
pc -- caused by trailing slash
                              then ([[Char]]
pcs, Dir -> Either FileDir Dir
forall a b. b -> Either a b
Right Dir
Part.Dir)
                              else ([[Char]]
pct, FileDir -> Either FileDir Dir
forall a b. a -> Either a b
Left FileDir
Part.FileDir)
            in  (AbsRel
ar, [[Char]] -> [Component os]
forall os. [[Char]] -> [Component os]
nonEmptyComponents [[Char]]
pcs1, Either FileDir Dir
fd))
        Tagged os (Char -> Bool)
forall os. System os => Tagged os (Char -> Bool)
isPathSeparator Tagged os (State [Char] AbsRel)
forall os. System os => Tagged os (State [Char] AbsRel)
splitAbsoluteO

nonEmptyComponents :: [String] -> [Component os]
nonEmptyComponents :: forall os. [[Char]] -> [Component os]
nonEmptyComponents = ([Char] -> Component os) -> [[Char]] -> [Component os]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> Component os
forall os. [Char] -> Component os
Component ([[Char]] -> [Component os])
-> ([[Char]] -> [[Char]]) -> [[Char]] -> [Component os]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> Bool) -> [[Char]] -> [[Char]]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> ([Char] -> Bool) -> [Char] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null)

splitDriveOS ::
    (System os, Class.AbsRel ar) => Tagged os (MS.State String ar)
splitDriveOS :: forall os ar. (System os, AbsRel ar) => Tagged os (State [Char] ar)
splitDriveOS =
    (StateT [Char] Identity [Char]
 -> State [Char] AbsRel -> State [Char] ar)
-> Tagged os (StateT [Char] Identity [Char])
-> Tagged os (State [Char] AbsRel)
-> Tagged os (State [Char] ar)
forall a b c.
(a -> b -> c) -> Tagged os a -> Tagged os b -> Tagged os c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2
        (\StateT [Char] Identity [Char]
splDrive State [Char] AbsRel
splAbsolute ->
            StateT [Char] Identity Abs
-> StateT [Char] Identity Rel
-> State [Char] AbsRel
-> State [Char] ar
forall ar (f :: * -> *).
AbsRel ar =>
f Abs -> f Rel -> f AbsRel -> f ar
forall (f :: * -> *). f Abs -> f Rel -> f AbsRel -> f ar
Class.switchAbsRel (([Char] -> Abs)
-> StateT [Char] Identity [Char] -> StateT [Char] Identity Abs
forall a b.
(a -> b) -> StateT [Char] Identity a -> StateT [Char] Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Char] -> Abs
absPC StateT [Char] Identity [Char]
splDrive) (Rel -> StateT [Char] Identity Rel
forall a. a -> StateT [Char] Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Rel
Part.Rel) State [Char] AbsRel
splAbsolute)
        Tagged os (StateT [Char] Identity [Char])
forall os. System os => Tagged os (StateT [Char] Identity [Char])
splitDriveAbs Tagged os (State [Char] AbsRel)
forall os. System os => Tagged os (State [Char] AbsRel)
splitAbsoluteO

splitDriveAbs :: (System os) => Tagged os (MS.State String String)
splitDriveAbs :: forall os. System os => Tagged os (StateT [Char] Identity [Char])
splitDriveAbs =
    ((Char -> Bool)
 -> StateT [Char] Identity [Char] -> StateT [Char] Identity [Char])
-> Tagged os (Char -> Bool)
-> Tagged os (StateT [Char] Identity [Char])
-> Tagged os (StateT [Char] Identity [Char])
forall a b c.
(a -> b -> c) -> Tagged os a -> Tagged os b -> Tagged os c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2
        (\Char -> Bool
isSep StateT [Char] Identity [Char]
splDrive -> do
            [Char]
drive <- StateT [Char] Identity [Char]
splDrive
            [Char]
xt <- StateT [Char] Identity [Char]
forall (m :: * -> *) s. Monad m => StateT s m s
MS.get
            case [Char]
xt of
                [] -> [Char] -> StateT [Char] Identity [Char]
forall a. a -> StateT [Char] Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
drive
                Char
x:[Char]
xs ->
                    if Char -> Bool
isSep Char
x
                      then [Char] -> StateT [Char] Identity ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
MS.put [Char]
xs StateT [Char] Identity ()
-> StateT [Char] Identity [Char] -> StateT [Char] Identity [Char]
forall a b.
StateT [Char] Identity a
-> StateT [Char] Identity b -> StateT [Char] Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Char] -> StateT [Char] Identity [Char]
forall a. a -> StateT [Char] Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Char]
drive[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char
x])
                      else [Char] -> StateT [Char] Identity [Char]
forall a. a -> StateT [Char] Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
drive)
        Tagged os (Char -> Bool)
forall os. System os => Tagged os (Char -> Bool)
isPathSeparator Tagged os (StateT [Char] Identity [Char])
forall os. System os => Tagged os (StateT [Char] Identity [Char])
splitDrive

splitAbsoluteO :: (System os) => Tagged os (MS.State String Part.AbsRel)
splitAbsoluteO :: forall os. System os => Tagged os (State [Char] AbsRel)
splitAbsoluteO =
    ([Char] -> AbsRel)
-> StateT [Char] Identity [Char] -> State [Char] AbsRel
forall a b.
(a -> b) -> StateT [Char] Identity a -> StateT [Char] Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\[Char]
drive -> if [Char] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Char]
drive then AbsRel
Part.RelO else GenComponent -> AbsRel
Part.AbsO (GenComponent -> AbsRel) -> GenComponent -> AbsRel
forall a b. (a -> b) -> a -> b
$ [Char] -> GenComponent
forall os. [Char] -> Component os
Component [Char]
drive)
    (StateT [Char] Identity [Char] -> State [Char] AbsRel)
-> Tagged os (StateT [Char] Identity [Char])
-> Tagged os (State [Char] AbsRel)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    Tagged os (StateT [Char] Identity [Char])
forall os. System os => Tagged os (StateT [Char] Identity [Char])
splitAbsolute

-- | > \p -> uncurry Path.mkPathFromComponents (Path.pathComponents p) == (p::Default.AbsDir)
pathComponents ::
    (Class.FileDir fd) => Path os ar fd -> (ar, [Component os])
pathComponents :: forall fd os ar.
FileDir fd =>
Path os ar fd -> (ar, [Component os])
pathComponents (Path ar
ar [Component os]
pcs fd
fd) =
    (ar
ar, [Component os]
pcs [Component os] -> [Component os] -> [Component os]
forall a. [a] -> [a] -> [a]
++ (GenComponent -> [Component os])
-> [Component os] -> [Component os] -> fd -> [Component os]
forall fd a. FileDir fd => (GenComponent -> a) -> a -> a -> fd -> a
Class.withFileDir ((Component os -> [Component os] -> [Component os]
forall a. a -> [a] -> [a]
:[]) (Component os -> [Component os])
-> (GenComponent -> Component os) -> GenComponent -> [Component os]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenComponent -> Component os
forall os. GenComponent -> Component os
PC.retag) [] [] fd
fd)

prop_mkPathFromComponents_pathComponents :: (System os) => AbsDir os -> Property
prop_mkPathFromComponents_pathComponents :: forall os. System os => AbsDir os -> Property
prop_mkPathFromComponents_pathComponents Path os Abs Dir
p =
    Bool -> Property
forall prop. Testable prop => prop -> Property
property (Bool -> Property) -> Bool -> Property
forall a b. (a -> b) -> a -> b
$ (Abs -> [Component os] -> Path os Abs Dir)
-> (Abs, [Component os]) -> Path os Abs Dir
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Abs -> [Component os] -> Path os Abs Dir
forall fd ar os.
FileDir fd =>
ar -> [Component os] -> Path os ar fd
mkPathFromComponents (Path os Abs Dir -> (Abs, [Component os])
forall fd os ar.
FileDir fd =>
Path os ar fd -> (ar, [Component os])
pathComponents Path os Abs Dir
p) Path os Abs Dir -> Path os Abs Dir -> Bool
forall a. Eq a => a -> a -> Bool
== Path os Abs Dir
p



------------------------------------------------------------------------
-- Basic Manipulation Functions

combineOperator :: String
combineOperator :: [Char]
combineOperator = [Char]
"</>"


instance (Class.Rel ar, Class.Dir fd) => Semigroup (Path os ar fd) where
    Path ar
r [Component os]
pcs0 fd
_dir <> :: Path os ar fd -> Path os ar fd -> Path os ar fd
<> Path ar
_rel [Component os]
pcs1 fd
d = ar -> [Component os] -> fd -> Path os ar fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
r ([Component os]
pcs0 [Component os] -> [Component os] -> [Component os]
forall a. [a] -> [a] -> [a]
++ [Component os]
pcs1) fd
d
    sconcat :: NonEmpty (Path os ar fd) -> Path os ar fd
sconcat NonEmpty (Path os ar fd)
paths =
        ar -> [Component os] -> fd -> Path os ar fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
forall ar. Rel ar => ar
Class.relVar
            (NonEmpty [Component os] -> [Component os]
forall a. Semigroup a => NonEmpty a -> a
sconcat (NonEmpty [Component os] -> [Component os])
-> NonEmpty [Component os] -> [Component os]
forall a b. (a -> b) -> a -> b
$ (Path os ar fd -> [Component os])
-> NonEmpty (Path os ar fd) -> NonEmpty [Component os]
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Path ar
_rel [Component os]
pcs fd
_dir) -> [Component os]
pcs) NonEmpty (Path os ar fd)
paths) fd
forall fd. Dir fd => fd
Class.dirVar

instance (Class.Rel ar, Class.Dir fd) => Monoid (Path os ar fd) where
    mempty :: Path os ar fd
mempty = ar -> [Component os] -> fd -> Path os ar fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
forall ar. Rel ar => ar
Class.relVar [] fd
forall fd. Dir fd => fd
Class.dirVar
    mappend :: Path os ar fd -> Path os ar fd -> Path os ar fd
mappend (Path ar
r [Component os]
pcs0 fd
_dir) (Path ar
_rel [Component os]
pcs1 fd
d) = ar -> [Component os] -> fd -> Path os ar fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
r ([Component os]
pcs0 [Component os] -> [Component os] -> [Component os]
forall a. [a] -> [a] -> [a]
++ [Component os]
pcs1) fd
d
    mconcat :: [Path os ar fd] -> Path os ar fd
mconcat [Path os ar fd]
paths =
        ar -> [Component os] -> fd -> Path os ar fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
forall ar. Rel ar => ar
Class.relVar
            ((Path os ar fd -> [Component os])
-> [Path os ar fd] -> [Component os]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(Path ar
_rel [Component os]
pcs fd
_dir) -> [Component os]
pcs) [Path os ar fd]
paths) fd
forall fd. Dir fd => fd
Class.dirVar


-- | Infix variant of 'combine'.
--
-- prop> Posix.toString (Posix.absDir "/tmp" </> Posix.relFile "file.txt") == "/tmp/file.txt"
-- prop> Posix.toString (Posix.absDir "/tmp" </> Posix.relDir "dir" </> Posix.relFile "file.txt") == "/tmp/dir/file.txt"
-- prop> Posix.toString (Posix.relDir "dir" </> Posix.relFile "file.txt") == "dir/file.txt"
-- prop> Windows.toString (Windows.absDir "\\tmp" </> Windows.relFile "file.txt") == "\\tmp\\file.txt"
-- prop> Windows.toString (Windows.absDir "c:\\tmp" </> Windows.relFile "file.txt") == "c:\\tmp\\file.txt"
-- prop> Windows.toString (Windows.absDir "c:tmp" </> Windows.relFile "file.txt") == "c:tmp\\file.txt"
-- prop> Windows.toString (Windows.absDir "c:\\" </> Windows.relDir "tmp" </> Windows.relFile "file.txt") == "c:\\tmp\\file.txt"
-- prop> Windows.toString (Windows.absDir "c:" </> Windows.relDir "tmp" </> Windows.relFile "file.txt") == "c:tmp\\file.txt"
-- prop> Windows.toString (Windows.relDir "dir" </> Windows.relFile "file.txt") == "dir\\file.txt"
(</>) :: DirPath os ar -> RelPath os fd -> Path os ar fd
Path ar
ar [Component os]
pcs0 Dir
Part.Dir  </> :: forall os ar fd. DirPath os ar -> RelPath os fd -> Path os ar fd
</>  Path Rel
Part.Rel [Component os]
pcs1 fd
fd  =  ar -> [Component os] -> fd -> Path os ar fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar ([Component os]
pcs0 [Component os] -> [Component os] -> [Component os]
forall a. [a] -> [a] -> [a]
++ [Component os]
pcs1) fd
fd

infixr 5  </>

-- | Infix variant of 'addExtension'.
--   We only allow files (and not directories) to have extensions added
--   by this function. This is because it's the vastly common case and
--   an attempt to add one to a directory will - more often than not -
--   represent an error.
--   We don't however want to prevent the corresponding operation on
--   directories, and so we provide a function that is more flexible:
--   'genericAddExtension'.
(<.>) :: FilePath os ar -> String -> FilePath os ar
FilePath os ar
p <.> :: forall os ar. FilePath os ar -> [Char] -> FilePath os ar
<.> [Char]
ext = (GenComponent -> GenComponent) -> FilePath os ar -> FilePath os ar
forall os ar.
(GenComponent -> GenComponent) -> FilePath os ar -> FilePath os ar
mapFilePart ((GenComponent -> [Char] -> GenComponent)
-> [Char] -> GenComponent -> GenComponent
forall a b c. (a -> b -> c) -> b -> a -> c
flip GenComponent -> [Char] -> GenComponent
forall os. Component os -> [Char] -> Component os
PC.addExtension [Char]
ext) FilePath os ar
p

infixl 7  <.>

(<++>) :: FilePath os ar -> String -> FilePath os ar
FilePath os ar
p <++> :: forall os ar. FilePath os ar -> [Char] -> FilePath os ar
<++> [Char]
str = ([Char] -> [Char]) -> FilePath os ar -> FilePath os ar
forall os ar.
([Char] -> [Char]) -> FilePath os ar -> FilePath os ar
mapFileName ([Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
str) FilePath os ar
p

infixl 7  <++>

-- | Add an extension, even if there is already one there.
--   E.g. @addExtension \"foo.txt\" \"bat\" -> \"foo.txt.bat\"@.
--
-- prop> Path.addExtension (relFile "file.txt") "bib" == Posix.relFile "file.txt.bib"
-- prop> Path.addExtension (relFile "file.") ".bib" == Posix.relFile "file..bib"
-- prop> Path.addExtension (relFile "file") ".bib" == Posix.relFile "file.bib"
-- prop> Path.addExtension Path.emptyFile "bib" == Posix.relFile ".bib"
-- prop> Path.addExtension Path.emptyFile ".bib" == Posix.relFile ".bib"
-- prop> Path.takeFileName (Path.addExtension Path.emptyFile "ext") == Posix.relFile ".ext"
addExtension :: FilePath os ar -> String -> FilePath os ar
addExtension :: forall os ar. FilePath os ar -> [Char] -> FilePath os ar
addExtension = FilePath os ar -> [Char] -> FilePath os ar
forall os ar. FilePath os ar -> [Char] -> FilePath os ar
(<.>)

-- | Join an (absolute or relative) directory path with a relative
--   (file or directory) path to form a new path.
--
-- prop> \p -> Path.combine Path.currentDir p == (p::Default.RelDir)
combine :: DirPath os ar -> RelPath os fd -> Path os ar fd
combine :: forall os ar fd. DirPath os ar -> RelPath os fd -> Path os ar fd
combine = DirPath os ar -> RelPath os fd -> Path os ar fd
forall os ar fd. DirPath os ar -> RelPath os fd -> Path os ar fd
(</>)


-- | Remove last extension, and the \".\" preceding it.
--
-- prop> forAllAbsRel $ \x -> Path.dropExtension x == fst (Path.splitExtension x)
dropExtension :: FilePath os ar -> FilePath os ar
dropExtension :: forall os fd. FilePath os fd -> FilePath os fd
dropExtension = (FilePath os ar, [Char]) -> FilePath os ar
forall a b. (a, b) -> a
fst ((FilePath os ar, [Char]) -> FilePath os ar)
-> (FilePath os ar -> (FilePath os ar, [Char]))
-> FilePath os ar
-> FilePath os ar
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath os ar -> (FilePath os ar, [Char])
forall os ar. FilePath os ar -> (FilePath os ar, [Char])
splitExtension

-- | Drop all extensions
--
-- prop> forAllAbsRel $ \x -> not $ Path.hasAnExtension (Path.dropExtensions x)
dropExtensions :: FilePath os ar -> FilePath os ar
dropExtensions :: forall os fd. FilePath os fd -> FilePath os fd
dropExtensions = (FilePath os ar, [Char]) -> FilePath os ar
forall a b. (a, b) -> a
fst ((FilePath os ar, [Char]) -> FilePath os ar)
-> (FilePath os ar -> (FilePath os ar, [Char]))
-> FilePath os ar
-> FilePath os ar
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath os ar -> (FilePath os ar, [Char])
forall os ar. FilePath os ar -> (FilePath os ar, [Char])
splitExtensions

-- | Synonym for 'takeDirectory'
dropFileName :: FilePath os ar -> DirPath os ar
dropFileName :: forall os ar. FilePath os ar -> DirPath os ar
dropFileName = (DirPath os ar, RelFile os) -> DirPath os ar
forall a b. (a, b) -> a
fst ((DirPath os ar, RelFile os) -> DirPath os ar)
-> (FilePath os ar -> (DirPath os ar, RelFile os))
-> FilePath os ar
-> DirPath os ar
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath os ar -> (DirPath os ar, RelFile os)
forall os ar. FilePath os ar -> (DirPath os ar, RelFile os)
splitFileName


-- | Set the extension of a file, overwriting one if already present.
--
-- prop> Path.replaceExtension (relFile "file.txt") ".bob" == Posix.relFile "file.bob"
-- prop> Path.replaceExtension (relFile "file.txt") "bob" == Posix.relFile "file.bob"
-- prop> Path.replaceExtension (relFile "file") ".bob" == Posix.relFile "file.bob"
-- prop> Path.replaceExtension (relFile "file.txt") "" == Posix.relFile "file"
-- prop> Path.replaceExtension (relFile "file.fred.bob") "txt" == Posix.relFile "file.fred.txt"
replaceExtension :: FilePath os ar -> String -> FilePath os ar
replaceExtension :: forall os ar. FilePath os ar -> [Char] -> FilePath os ar
replaceExtension FilePath os ar
p [Char]
ext = FilePath os ar -> FilePath os ar
forall os fd. FilePath os fd -> FilePath os fd
dropExtension FilePath os ar
p FilePath os ar -> [Char] -> FilePath os ar
forall os ar. FilePath os ar -> [Char] -> FilePath os ar
<.> [Char]
ext

replaceBaseName :: FilePath os ar -> String -> FilePath os ar
replaceBaseName :: forall os ar. FilePath os ar -> [Char] -> FilePath os ar
replaceBaseName FilePath os ar
p [Char]
bn =
    (GenComponent -> GenComponent) -> FilePath os ar -> FilePath os ar
forall os ar.
(GenComponent -> GenComponent) -> FilePath os ar -> FilePath os ar
mapFilePart (GenComponent -> [Char] -> GenComponent
forall os. Component os -> [Char] -> Component os
PC.addExtension ([Char] -> GenComponent
forall os. [Char] -> Component os
Component [Char]
bn) ([Char] -> GenComponent)
-> (GenComponent -> [Char]) -> GenComponent -> GenComponent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GenComponent, [Char]) -> [Char]
forall a b. (a, b) -> b
snd ((GenComponent, [Char]) -> [Char])
-> (GenComponent -> (GenComponent, [Char]))
-> GenComponent
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenComponent -> (GenComponent, [Char])
forall os. Component os -> (Component os, [Char])
PC.splitExtension) FilePath os ar
p

replaceDirectory :: FilePath os ar1 -> DirPath os ar2 -> FilePath os ar2
replaceDirectory :: forall os ar1 ar2.
FilePath os ar1 -> DirPath os ar2 -> FilePath os ar2
replaceDirectory (Path ar1
_ [Component os]
_ File
fd) (Path ar2
ar [Component os]
pcs Dir
_) = ar2 -> [Component os] -> File -> Path os ar2 File
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar2
ar [Component os]
pcs File
fd

replaceFileName :: FilePath os ar -> String -> FilePath os ar
replaceFileName :: forall os ar. FilePath os ar -> [Char] -> FilePath os ar
replaceFileName FilePath os ar
p [Char]
fn = (GenComponent -> GenComponent) -> FilePath os ar -> FilePath os ar
forall os ar.
(GenComponent -> GenComponent) -> FilePath os ar -> FilePath os ar
mapFilePart (GenComponent -> GenComponent -> GenComponent
forall a b. a -> b -> a
const ([Char] -> GenComponent
forall os. [Char] -> Component os
Component [Char]
fn)) FilePath os ar
p


-- | Split on the extension. 'addExtension' is the inverse.
--
-- prop> forAllAbsRel $ \x -> uncurry (<.>) (Path.splitExtension x) == x
-- prop> forAllAbsRel $ \x -> uncurry Path.addExtension (Path.splitExtension x) == x
-- prop> Path.splitExtension (relFile "file.txt") == (Posix.relFile "file",".txt")
-- prop> Path.splitExtension (relFile ".bashrc") == (Posix.emptyFile, ".bashrc")
-- prop> Path.splitExtension (relFile "file") == (Posix.relFile "file","")
-- prop> Path.splitExtension (relFile "file/file.txt") == (Posix.relFile "file/file",".txt")
-- prop> Path.splitExtension (relFile "file.txt/boris") == (Posix.relFile "file.txt/boris","")
-- prop> Path.splitExtension (relFile "file.txt/boris.ext") == (Posix.relFile "file.txt/boris",".ext")
-- prop> Path.splitExtension (relFile "file/path.txt.bob.fred") == (Posix.relFile "file/path.txt.bob",".fred")
splitExtension :: FilePath os ar -> (FilePath os ar, String)
splitExtension :: forall os ar. FilePath os ar -> (FilePath os ar, [Char])
splitExtension = (GenComponent -> (GenComponent, [Char]))
-> FilePath os ar -> (FilePath os ar, [Char])
forall a os ar.
(GenComponent -> (GenComponent, a))
-> FilePath os ar -> (FilePath os ar, a)
splitFilePart GenComponent -> (GenComponent, [Char])
forall os. Component os -> (Component os, [Char])
PC.splitExtension

-- | Split on all extensions
--
-- prop> Path.splitExtensions (relFile "file.tar.gz") == (Posix.relFile "file",".tar.gz")
-- prop> \p -> uncurry (<.>) (Path.splitExtension p) == (p::Default.AbsFile)
splitExtensions :: FilePath os ar -> (FilePath os ar, String)
splitExtensions :: forall os ar. FilePath os ar -> (FilePath os ar, [Char])
splitExtensions = (GenComponent -> (GenComponent, [Char]))
-> FilePath os ar -> (FilePath os ar, [Char])
forall a os ar.
(GenComponent -> (GenComponent, a))
-> FilePath os ar -> (FilePath os ar, a)
splitFilePart GenComponent -> (GenComponent, [Char])
forall os. Component os -> (Component os, [Char])
PC.splitExtensions

-- | prop> \p -> uncurry Path.combine (Path.splitFileName p) == (p::Default.AbsFile)
splitFileName :: FilePath os ar -> (DirPath os ar, RelFile os)
splitFileName :: forall os ar. FilePath os ar -> (DirPath os ar, RelFile os)
splitFileName (Path ar
ar [Component os]
pcs File
fd) = (ar -> [Component os] -> Dir -> Path os ar Dir
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar [Component os]
pcs Dir
Part.Dir, File -> RelFile os
forall os. File -> RelFile os
atomicFile File
fd)

-- | > \p -> (uncurry Path.combine <$> Path.splitDirName p) == toMaybe (not $ Default.isDrive p) (p::Default.AbsDir)
splitDirName :: DirPath os ar -> Maybe (DirPath os ar, RelDir os)
splitDirName :: forall os ar. DirPath os ar -> Maybe (DirPath os ar, RelDir os)
splitDirName = (FilePath os ar -> (DirPath os ar, RelDir os))
-> Maybe (FilePath os ar) -> Maybe (DirPath os ar, RelDir os)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((FilePath os Rel -> RelDir os)
-> (DirPath os ar, FilePath os Rel) -> (DirPath os ar, RelDir os)
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd FilePath os Rel -> RelDir os
forall os ar. FilePath os ar -> DirPath os ar
dirFromFile ((DirPath os ar, FilePath os Rel) -> (DirPath os ar, RelDir os))
-> (FilePath os ar -> (DirPath os ar, FilePath os Rel))
-> FilePath os ar
-> (DirPath os ar, RelDir os)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath os ar -> (DirPath os ar, FilePath os Rel)
forall os ar. FilePath os ar -> (DirPath os ar, RelFile os)
splitFileName) (Maybe (FilePath os ar) -> Maybe (DirPath os ar, RelDir os))
-> (DirPath os ar -> Maybe (FilePath os ar))
-> DirPath os ar
-> Maybe (DirPath os ar, RelDir os)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DirPath os ar -> Maybe (FilePath os ar)
forall os ar. DirPath os ar -> Maybe (FilePath os ar)
fileFromDir

prop_splitDir_combine :: (System os) => AbsDir os -> Property
prop_splitDir_combine :: forall os. System os => AbsDir os -> Property
prop_splitDir_combine Path os Abs Dir
p =
    Bool -> Property
forall prop. Testable prop => prop -> Property
property (Bool -> Property) -> Bool -> Property
forall a b. (a -> b) -> a -> b
$
    ((Path os Abs Dir -> RelPath os Dir -> Path os Abs Dir)
-> (Path os Abs Dir, RelPath os Dir) -> Path os Abs Dir
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Path os Abs Dir -> RelPath os Dir -> Path os Abs Dir
forall os ar fd. DirPath os ar -> RelPath os fd -> Path os ar fd
combine ((Path os Abs Dir, RelPath os Dir) -> Path os Abs Dir)
-> Maybe (Path os Abs Dir, RelPath os Dir)
-> Maybe (Path os Abs Dir)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Path os Abs Dir -> Maybe (Path os Abs Dir, RelPath os Dir)
forall os ar. DirPath os ar -> Maybe (DirPath os ar, RelDir os)
splitDirName Path os Abs Dir
p) Maybe (Path os Abs Dir) -> Maybe (Path os Abs Dir) -> Bool
forall a. Eq a => a -> a -> Bool
== Bool -> Path os Abs Dir -> Maybe (Path os Abs Dir)
forall a. Bool -> a -> Maybe a
toMaybe (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Path os Abs Dir -> Bool
forall os. AbsDir os -> Bool
isDrive Path os Abs Dir
p) Path os Abs Dir
p


-- | Get the basename of a file
--
-- prop> Path.takeBaseName (absFile "/tmp/somedir/myfile.txt") == Posix.relFile "myfile"
-- prop> Path.takeBaseName (relFile "./myfile.txt") == Posix.relFile "myfile"
-- prop> Path.takeBaseName (relFile "myfile.txt") == Posix.relFile "myfile"
takeBaseName :: FilePath os ar -> RelFile os
takeBaseName :: forall os ar. FilePath os ar -> RelFile os
takeBaseName = FilePath os ar -> RelFile os
forall os ar. FilePath os ar -> RelFile os
takeFileName (FilePath os ar -> RelFile os)
-> (FilePath os ar -> FilePath os ar)
-> FilePath os ar
-> RelFile os
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath os ar -> FilePath os ar
forall os fd. FilePath os fd -> FilePath os fd
dropExtension

takeDirectory :: FilePath os ar -> DirPath os ar
takeDirectory :: forall os ar. FilePath os ar -> DirPath os ar
takeDirectory = (DirPath os ar, RelFile os) -> DirPath os ar
forall a b. (a, b) -> a
fst ((DirPath os ar, RelFile os) -> DirPath os ar)
-> (FilePath os ar -> (DirPath os ar, RelFile os))
-> FilePath os ar
-> DirPath os ar
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath os ar -> (DirPath os ar, RelFile os)
forall os ar. FilePath os ar -> (DirPath os ar, RelFile os)
splitFileName

-- prop> Path.takeSuperDirectory (Posix.absDir "/tmp/somedir") == Just (absDir "/tmp")
-- prop> Path.takeSuperDirectory (Posix.absDir "/tmp/") == Just (absDir "/")
-- prop> Path.takeSuperDirectory (Posix.absDir "/") == Nothing
-- prop> Path.takeSuperDirectory (Posix.relDir "tmp/somedir") == Just (relDir "tmp")
-- prop> Path.takeSuperDirectory (Posix.relDir "./somedir") == Just (relDir ".")
-- prop> Path.takeSuperDirectory (Posix.relDir "somedir") == Just Path.currentDir
-- prop> Path.takeSuperDirectory (Posix.relDir "") == Nothing
takeSuperDirectory :: DirPath os ar -> Maybe (DirPath os ar)
takeSuperDirectory :: forall os ar. DirPath os ar -> Maybe (DirPath os ar)
takeSuperDirectory = (FilePath os ar -> DirPath os ar)
-> Maybe (FilePath os ar) -> Maybe (DirPath os ar)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FilePath os ar -> DirPath os ar
forall os ar. FilePath os ar -> DirPath os ar
takeDirectory (Maybe (FilePath os ar) -> Maybe (DirPath os ar))
-> (DirPath os ar -> Maybe (FilePath os ar))
-> DirPath os ar
-> Maybe (DirPath os ar)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DirPath os ar -> Maybe (FilePath os ar)
forall os ar. DirPath os ar -> Maybe (FilePath os ar)
fileFromDir

-- | Get the extension of a file, returns @\"\"@ for no extension, @.ext@ otherwise.
--
-- prop> forAllAbsRel $ \x -> Path.takeExtension x == snd (Path.splitExtension x)
-- prop> forAllAbsRel $ \x -> Path.takeExtension (Path.addExtension x "ext") == ".ext"
-- prop> forAllAbsRel $ \x -> Path.takeExtension (Path.replaceExtension x "ext") == ".ext"
takeExtension :: FilePath os ar -> String
takeExtension :: forall os ar. FilePath os ar -> [Char]
takeExtension = (FilePath os ar, [Char]) -> [Char]
forall a b. (a, b) -> b
snd ((FilePath os ar, [Char]) -> [Char])
-> (FilePath os ar -> (FilePath os ar, [Char]))
-> FilePath os ar
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath os ar -> (FilePath os ar, [Char])
forall os ar. FilePath os ar -> (FilePath os ar, [Char])
splitExtension

-- | Get all extensions
--
-- prop> Path.takeExtensions (Posix.relFile "file.tar.gz") == ".tar.gz"
takeExtensions :: FilePath os ar -> String
takeExtensions :: forall os ar. FilePath os ar -> [Char]
takeExtensions = (FilePath os ar, [Char]) -> [Char]
forall a b. (a, b) -> b
snd ((FilePath os ar, [Char]) -> [Char])
-> (FilePath os ar -> (FilePath os ar, [Char]))
-> FilePath os ar
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath os ar -> (FilePath os ar, [Char])
forall os ar. FilePath os ar -> (FilePath os ar, [Char])
splitExtensions

-- | Get the filename component of a file path (ie stripping all parent dirs)
--
-- prop> Path.takeFileName (absFile "/tmp/somedir/myfile.txt") == Posix.relFile "myfile.txt"
-- prop> Path.takeFileName (relFile "./myfile.txt") == Posix.relFile "myfile.txt"
-- prop> Path.takeFileName (relFile "myfile.txt") == Posix.relFile "myfile.txt"
-- prop> \p -> Path.toString (Path.takeFileName p) `isSuffixOf` Path.toString (p::Default.AbsFile)
takeFileName :: FilePath os ar -> RelFile os
takeFileName :: forall os ar. FilePath os ar -> RelFile os
takeFileName (Path ar
_ [Component os]
_ File
fd) = File -> RelFile os
forall os. File -> RelFile os
atomicFile File
fd

-- | > \p -> fmap (\d -> toString d `isSuffixOf` toString p) (takeDirName p) == toMaybe (not $ isDrive p) True
takeDirName :: DirPath os ar -> Maybe (RelDir os)
takeDirName :: forall os ar. DirPath os ar -> Maybe (RelDir os)
takeDirName = ((DirPath os ar, RelDir os) -> RelDir os)
-> Maybe (DirPath os ar, RelDir os) -> Maybe (RelDir os)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (DirPath os ar, RelDir os) -> RelDir os
forall a b. (a, b) -> b
snd (Maybe (DirPath os ar, RelDir os) -> Maybe (RelDir os))
-> (DirPath os ar -> Maybe (DirPath os ar, RelDir os))
-> DirPath os ar
-> Maybe (RelDir os)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DirPath os ar -> Maybe (DirPath os ar, RelDir os)
forall os ar. DirPath os ar -> Maybe (DirPath os ar, RelDir os)
splitDirName

prop_takeDirName_end :: (System os) => AbsDir os -> Property
prop_takeDirName_end :: forall os. System os => AbsDir os -> Property
prop_takeDirName_end AbsDir os
p =
    Bool -> Property
forall prop. Testable prop => prop -> Property
property (Bool -> Property) -> Bool -> Property
forall a b. (a -> b) -> a -> b
$
    (Path os Rel Dir -> Bool) -> Maybe (Path os Rel Dir) -> Maybe Bool
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Path os Rel Dir
d -> Path os Rel Dir -> [Char]
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Path os ar fd -> [Char]
toString Path os Rel Dir
d [Char] -> [Char] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` AbsDir os -> [Char]
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Path os ar fd -> [Char]
toString AbsDir os
p) (AbsDir os -> Maybe (Path os Rel Dir)
forall os ar. DirPath os ar -> Maybe (RelDir os)
takeDirName AbsDir os
p)
    Maybe Bool -> Maybe Bool -> Bool
forall a. Eq a => a -> a -> Bool
==
    Bool -> Bool -> Maybe Bool
forall a. Bool -> a -> Maybe a
toMaybe (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ AbsDir os -> Bool
forall os. AbsDir os -> Bool
isDrive AbsDir os
p) Bool
True

mapFileName :: (String -> String) -> FilePath os ar -> FilePath os ar
mapFileName :: forall os ar.
([Char] -> [Char]) -> FilePath os ar -> FilePath os ar
mapFileName = (GenComponent -> GenComponent) -> FilePath os ar -> FilePath os ar
forall os ar.
(GenComponent -> GenComponent) -> FilePath os ar -> FilePath os ar
mapFilePart ((GenComponent -> GenComponent)
 -> FilePath os ar -> FilePath os ar)
-> (([Char] -> [Char]) -> GenComponent -> GenComponent)
-> ([Char] -> [Char])
-> FilePath os ar
-> FilePath os ar
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> [Char]) -> GenComponent -> GenComponent
forall os. ([Char] -> [Char]) -> Component os -> Component os
PC.map

mapFileNameF ::
    (Functor f) =>
    (String -> f String) -> FilePath os ar -> f (FilePath os ar)
mapFileNameF :: forall (f :: * -> *) os ar.
Functor f =>
([Char] -> f [Char]) -> FilePath os ar -> f (FilePath os ar)
mapFileNameF = (GenComponent -> f GenComponent)
-> FilePath os ar -> f (FilePath os ar)
forall (f :: * -> *) os ar.
Functor f =>
(GenComponent -> f GenComponent)
-> FilePath os ar -> f (FilePath os ar)
mapFilePartF ((GenComponent -> f GenComponent)
 -> FilePath os ar -> f (FilePath os ar))
-> (([Char] -> f [Char]) -> GenComponent -> f GenComponent)
-> ([Char] -> f [Char])
-> FilePath os ar
-> f (FilePath os ar)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> f [Char]) -> GenComponent -> f GenComponent
forall (f :: * -> *) os.
Functor f =>
([Char] -> f [Char]) -> Component os -> f (Component os)
PC.mapF


------------------------------------------------------------------------
-- Auxillary Manipulation Functions

-- | Check whether two strings are equal as file paths.
--
-- prop>       Posix.equalFilePath "abc/def" "abc/def"
-- prop>       Posix.equalFilePath "abc/def" "abc//def"
-- prop>       Posix.equalFilePath "/tmp/" "/tmp"
-- prop>       Posix.equalFilePath "/tmp" "//tmp"
-- prop>       Posix.equalFilePath "/tmp" "///tmp"
-- prop> not $ Posix.equalFilePath "abc" "def"
-- prop> not $ Posix.equalFilePath "/tmp" "tmp"
-- prop>       Windows.equalFilePath "abc\\def" "abc\\def"
-- prop>       Windows.equalFilePath "abc\\def" "abc\\\\def"
-- prop>       Windows.equalFilePath "file" "File"
-- prop>       Windows.equalFilePath "\\file" "\\\\file"
-- prop>       Windows.equalFilePath "\\file" "\\\\\\file"
-- prop> not $ Windows.equalFilePath "abc" "def"
-- prop> not $ Windows.equalFilePath "file" "dir"
equalFilePath :: (System os) => Tagged os (String -> String -> Bool)
equalFilePath :: forall os. System os => Tagged os ([Char] -> [Char] -> Bool)
equalFilePath = ([Char] -> Either (AbsFileDir os) (RelFileDir os))
-> [Char] -> [Char] -> Bool
forall b a. Eq b => (a -> b) -> a -> a -> Bool
equating (([Char] -> Either (AbsFileDir os) (RelFileDir os))
 -> [Char] -> [Char] -> Bool)
-> Tagged os ([Char] -> Either (AbsFileDir os) (RelFileDir os))
-> Tagged os ([Char] -> [Char] -> Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Tagged os ([Char] -> Either (AbsFileDir os) (RelFileDir os))
forall os.
System os =>
Tagged os ([Char] -> Either (AbsFileDir os) (RelFileDir os))
mkPathAbsOrRelTagged

mkPathAbsOrRelTagged ::
    (System os) =>
    Tagged os (String -> Either (AbsFileDir os) (RelFileDir os))
mkPathAbsOrRelTagged :: forall os.
System os =>
Tagged os ([Char] -> Either (AbsFileDir os) (RelFileDir os))
mkPathAbsOrRelTagged = ([Char] -> Either (AbsFileDir os) (RelFileDir os))
-> Tagged os ([Char] -> Either (AbsFileDir os) (RelFileDir os))
forall {k} (s :: k) b. b -> Tagged s b
Tagged [Char] -> Either (AbsFileDir os) (RelFileDir os)
forall os fd.
(System os, FileDir fd) =>
[Char] -> Either (AbsPath os fd) (RelPath os fd)
mkPathAbsOrRelPriv

-- | Constructs a 'RelPath' from a list of components.
--   It is an unchecked error if the path components contain path separators.
--   It is an unchecked error if a 'RelFile' path is empty.
--
-- prop> Path.joinPath ["tmp","someDir","dir"] == Posix.relDir "tmp/someDir/dir"
-- prop> Path.joinPath ["tmp","someDir","file.txt"] == Posix.relFile "tmp/someDir/file.txt"
joinPath :: (Class.FileDir fd) => [String] -> RelPath os fd
joinPath :: forall fd os. FileDir fd => [[Char]] -> RelPath os fd
joinPath = Rel -> [Component os] -> Path os Rel fd
forall fd ar os.
FileDir fd =>
ar -> [Component os] -> Path os ar fd
mkPathFromComponents Rel
Part.Rel ([Component os] -> Path os Rel fd)
-> ([[Char]] -> [Component os]) -> [[Char]] -> Path os Rel fd
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> Component os) -> [[Char]] -> [Component os]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> Component os
forall os. [Char] -> Component os
Component

-- | Currently just transforms:
--
-- prop> Path.normalise (absFile "/tmp/fred/./jim/./file") == Posix.absFile "/tmp/fred/jim/file"
normalise :: (System os) => Path os ar fd -> Path os ar fd
normalise :: forall os ar fd. System os => Path os ar fd -> Path os ar fd
normalise = ([Component os] -> [Component os])
-> Path os ar fd -> Path os ar fd
forall os ar fd.
([Component os] -> [Component os])
-> Path os ar fd -> Path os ar fd
mapPathDirs ((Component os -> Bool) -> [Component os] -> [Component os]
forall a. (a -> Bool) -> [a] -> [a]
filter ([Char] -> Component os
forall os. [Char] -> Component os
Component [Char]
currentDirComponent Component os -> Component os -> Bool
forall a. Eq a => a -> a -> Bool
/=))

-- | Deconstructs a path into its components.
--
-- prop> Path.splitPath (Posix.absDir "/tmp/someDir/mydir.dir") == (True, map relDir ["tmp","someDir","mydir.dir"], Nothing)
-- prop> Path.splitPath (Posix.absFile "/tmp/someDir/myfile.txt") == (True, map relDir ["tmp","someDir"], Just $ relFile "myfile.txt")
splitPath ::
    (Class.AbsRel ar, Class.FileOrDir fd) =>
    Path os ar fd -> (Bool, [RelDir os], Maybe (RelFile os))
splitPath :: forall ar fd os.
(AbsRel ar, FileOrDir fd) =>
Path os ar fd -> (Bool, [RelDir os], Maybe (RelFile os))
splitPath (Path ar
ar [Component os]
pcs fd
fd) =
    (ar -> Bool
forall ar. AbsRel ar => ar -> Bool
Class.isAbsolute ar
ar,
     (Component os -> RelDir os) -> [Component os] -> [RelDir os]
forall a b. (a -> b) -> [a] -> [b]
map (\Component os
pc -> Rel -> [Component os] -> Dir -> RelDir os
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path Rel
Part.Rel [Component os
pc] Dir
Part.Dir) [Component os]
pcs,
     fd -> Maybe (RelFile os)
forall fd os. FileOrDir fd => fd -> Maybe (RelFile os)
maybeFileDir fd
fd)

maybeFileDir :: (Class.FileOrDir fd) => fd -> Maybe (RelFile os)
maybeFileDir :: forall fd os. FileOrDir fd => fd -> Maybe (RelFile os)
maybeFileDir = (GenComponent -> Maybe (RelFile os))
-> Maybe (RelFile os) -> fd -> Maybe (RelFile os)
forall fd a. FileOrDir fd => (GenComponent -> a) -> a -> fd -> a
Class.withFileOrDir (RelFile os -> Maybe (RelFile os)
forall a. a -> Maybe a
Just (RelFile os -> Maybe (RelFile os))
-> (GenComponent -> RelFile os)
-> GenComponent
-> Maybe (RelFile os)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. File -> RelFile os
forall os. File -> RelFile os
atomicFile (File -> RelFile os)
-> (GenComponent -> File) -> GenComponent -> RelFile os
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenComponent -> File
Part.File) Maybe (RelFile os)
forall a. Maybe a
Nothing

-- | This function can be used to construct a relative path by removing
--   the supplied 'AbsDir' from the front. It is a runtime 'error' if the
--   supplied 'AbsPath' doesn't start with the 'AbsDir'.
--
-- prop> Path.makeRelative (absDir "/tmp/somedir") (absFile "/tmp/somedir/anotherdir/file.txt") == Posix.relFile "anotherdir/file.txt"
-- prop> Path.makeRelative (absDir "/tmp/somedir") (absDir "/tmp/somedir/anotherdir/dir") == Posix.relDir "anotherdir/dir"
-- prop> Path.makeRelative (absDir "c:\\tmp\\somedir") (absFile "C:\\Tmp\\SomeDir\\AnotherDir\\File.txt") == Windows.relFile "AnotherDir\\File.txt"
-- prop> Path.makeRelative (absDir "c:\\tmp\\somedir") (absDir "c:\\tmp\\somedir\\anotherdir\\dir") == Windows.relDir "anotherdir\\dir"
-- prop> Path.makeRelative (absDir "c:tmp\\somedir") (absDir "c:tmp\\somedir\\anotherdir\\dir") == Windows.relDir "anotherdir\\dir"
makeRelative ::
    (System os, Class.FileDir fd) =>
    AbsDir os -> AbsPath os fd -> RelPath os fd
makeRelative :: forall os fd.
(System os, FileDir fd) =>
AbsDir os -> AbsPath os fd -> RelPath os fd
makeRelative AbsDir os
relTo AbsPath os fd
orig =
    RelPath os fd -> Maybe (RelPath os fd) -> RelPath os fd
forall a. a -> Maybe a -> a
fromMaybe
        ([Char] -> RelPath os fd
forall a. HasCallStack => [Char] -> a
error ([Char] -> RelPath os fd) -> [Char] -> RelPath os fd
forall a b. (a -> b) -> a -> b
$
            [Char] -> [Char] -> [Char] -> [Char]
forall r. PrintfType r => [Char] -> r
printf [Char]
"System.Path can't make (%s) relative to (%s)"
                (AbsPath os fd -> [Char]
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Path os ar fd -> [Char]
toString AbsPath os fd
orig) (AbsDir os -> [Char]
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Path os ar fd -> [Char]
toString AbsDir os
relTo)) (Maybe (RelPath os fd) -> RelPath os fd)
-> Maybe (RelPath os fd) -> RelPath os fd
forall a b. (a -> b) -> a -> b
$
    AbsDir os -> AbsPath os fd -> Maybe (RelPath os fd)
forall os fd.
(System os, FileDir fd) =>
AbsDir os -> AbsPath os fd -> Maybe (RelPath os fd)
makeRelativeMaybe AbsDir os
relTo AbsPath os fd
orig

-- prop> Path.makeRelativeMaybe (Posix.absDir "/tmp/somedir") (absFile "/tmp/anotherdir/file.txt") == Nothing
-- prop> Path.makeRelativeMaybe (Posix.absDir "/Tmp") (absFile "/tmp/anotherdir/file.txt") == Nothing
-- prop> Path.makeRelativeMaybe (Windows.absDir "\\Tmp") (absFile "\\tmp\\anotherdir\\file.txt") == Just (relFile "anotherdir\\file.txt")
makeRelativeMaybe ::
    (System os, Class.FileDir fd) =>
    AbsDir os -> AbsPath os fd -> Maybe (RelPath os fd)
makeRelativeMaybe :: forall os fd.
(System os, FileDir fd) =>
AbsDir os -> AbsPath os fd -> Maybe (RelPath os fd)
makeRelativeMaybe AbsDir os
relTo AbsPath os fd
orig =
    case (AbsDir os
-> (WrapAbsRel os Abs, [Component os], WrapFileDir os Dir)
forall os ar fd.
Path os ar fd
-> (WrapAbsRel os ar, [Component os], WrapFileDir os fd)
inspectPath AbsDir os
relTo, AbsPath os fd
-> (WrapAbsRel os Abs, [Component os], WrapFileDir os fd)
forall os ar fd.
Path os ar fd
-> (WrapAbsRel os ar, [Component os], WrapFileDir os fd)
inspectPath AbsPath os fd
orig) of
        ((WrapAbsRel os Abs
relToAR, [Component os]
relToPCs, WrapFileDir Dir
Part.Dir),
         (WrapAbsRel os Abs
origAR, [Component os]
origPCs, WrapFileDir fd
fd)) ->
            ([Component os] -> RelPath os fd)
-> Maybe [Component os] -> Maybe (RelPath os fd)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([Component os] -> fd -> RelPath os fd)
-> fd -> [Component os] -> RelPath os fd
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Rel -> [Component os] -> fd -> RelPath os fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path Rel
Part.Rel) fd
fd) (Maybe [Component os] -> Maybe (RelPath os fd))
-> Maybe [Component os] -> Maybe (RelPath os fd)
forall a b. (a -> b) -> a -> b
$
                Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (WrapAbsRel os Abs
relToAR WrapAbsRel os Abs -> WrapAbsRel os Abs -> Bool
forall a. Eq a => a -> a -> Bool
== WrapAbsRel os Abs
origAR) Maybe () -> Maybe [Component os] -> Maybe [Component os]
forall a b. Maybe a -> Maybe b -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Component os] -> [Component os] -> Maybe [Component os]
forall a. Eq a => [a] -> [a] -> Maybe [a]
stripPrefix [Component os]
relToPCs [Component os]
origPCs

-- | Joins an absolute directory with a relative path to construct a
--   new absolute path.
--
-- prop> Path.makeAbsolute (absDir "/tmp") (relFile "file.txt")      == Posix.absFile "/tmp/file.txt"
-- prop> Path.makeAbsolute (absDir "/tmp") (relFile "adir/file.txt") == Posix.absFile "/tmp/adir/file.txt"
-- prop> Path.makeAbsolute (absDir "/tmp") (relDir  "adir/dir")      == Posix.absDir "/tmp/adir/dir"
-- prop> \base p -> Default.toString p `isSuffixOf` Path.toString (Path.makeAbsolute base (Path.idFile p))
-- prop> \base p -> Default.toString base `isPrefixOf` Path.toString (Path.makeAbsolute base (Path.idFile p))
makeAbsolute :: (System os) => AbsDir os -> RelPath os fd -> AbsPath os fd
makeAbsolute :: forall os fd.
System os =>
AbsDir os -> RelPath os fd -> AbsPath os fd
makeAbsolute = AbsDir os -> Path os Rel fd -> AbsPath os fd
forall os ar fd.
(System os, AbsRel ar) =>
AbsDir os -> Path os ar fd -> AbsPath os fd
genericMakeAbsolute

-- | Converts a relative path into an absolute one by
--   prepending the current working directory.
makeAbsoluteFromCwd :: (System os) => RelPath os fd -> IO (AbsPath os fd)
makeAbsoluteFromCwd :: forall os fd. System os => RelPath os fd -> IO (AbsPath os fd)
makeAbsoluteFromCwd = Path os Rel fd -> IO (AbsPath os fd)
forall os ar fd.
(System os, AbsRel ar) =>
Path os ar fd -> IO (AbsPath os fd)
genericMakeAbsoluteFromCwd

dynamicMakeAbsolute ::
    (System os) => AbsDir os -> AbsRelPath os fd -> AbsPath os fd
dynamicMakeAbsolute :: forall os fd.
System os =>
AbsDir os -> AbsRelPath os fd -> AbsPath os fd
dynamicMakeAbsolute = AbsDir os -> Path os AbsRel fd -> AbsPath os fd
forall os ar fd.
(System os, AbsRel ar) =>
AbsDir os -> Path os ar fd -> AbsPath os fd
genericMakeAbsolute

dynamicMakeAbsoluteFromCwd ::
    (System os) => AbsRelPath os fd -> IO (AbsPath os fd)
dynamicMakeAbsoluteFromCwd :: forall os fd. System os => AbsRelPath os fd -> IO (AbsPath os fd)
dynamicMakeAbsoluteFromCwd = Path os AbsRel fd -> IO (AbsPath os fd)
forall os ar fd.
(System os, AbsRel ar) =>
Path os ar fd -> IO (AbsPath os fd)
genericMakeAbsoluteFromCwd

-- | As for 'makeAbsolute', but for use when the path may already be
--   absolute (in which case it is left unchanged).
--   You should avoid the use of 'genericMakeAbsolute'-type functions,
--   because then you avoid to absolutize a path that was already absolutized.
--
-- prop> Path.genericMakeAbsolute (absDir "/tmp") (relFile "file.txt")       == Posix.absFile "/tmp/file.txt"
-- prop> Path.genericMakeAbsolute (absDir "/tmp") (relFile "adir/file.txt")  == Posix.absFile "/tmp/adir/file.txt"
-- prop> Path.genericMakeAbsolute (absDir "/tmp") (absFile "/adir/file.txt") == Posix.absFile "/adir/file.txt"
genericMakeAbsolute ::
    (System os, Class.AbsRel ar) => AbsDir os -> Path os ar fd -> AbsPath os fd
genericMakeAbsolute :: forall os ar fd.
(System os, AbsRel ar) =>
AbsDir os -> Path os ar fd -> AbsPath os fd
genericMakeAbsolute AbsDir os
base Path os ar fd
p = (AbsPath os fd -> AbsPath os fd)
-> (RelPath os fd -> AbsPath os fd)
-> Path os ar fd
-> AbsPath os fd
forall ar os fd a.
AbsRel ar =>
(AbsPath os fd -> a) -> (RelPath os fd -> a) -> Path os ar fd -> a
withAbsRel AbsPath os fd -> AbsPath os fd
forall a. a -> a
id (AbsDir os
base AbsDir os -> RelPath os fd -> AbsPath os fd
forall os ar fd. DirPath os ar -> RelPath os fd -> Path os ar fd
</>) Path os ar fd
p

-- | As for 'makeAbsoluteFromCwd', but for use when the path may already be
--   absolute (in which case it is left unchanged).
genericMakeAbsoluteFromCwd ::
    (System os, Class.AbsRel ar) => Path os ar fd -> IO (AbsPath os fd)
genericMakeAbsoluteFromCwd :: forall os ar fd.
(System os, AbsRel ar) =>
Path os ar fd -> IO (AbsPath os fd)
genericMakeAbsoluteFromCwd Path os ar fd
p = do
  [Char]
cwdString <- IO [Char]
SD.getCurrentDirectory -- we don't use System.Path.Directory impl here to avoid module cycle
  AbsPath os fd -> IO (AbsPath os fd)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (AbsPath os fd -> IO (AbsPath os fd))
-> AbsPath os fd -> IO (AbsPath os fd)
forall a b. (a -> b) -> a -> b
$ AbsDir os -> Path os ar fd -> AbsPath os fd
forall os ar fd.
(System os, AbsRel ar) =>
AbsDir os -> Path os ar fd -> AbsPath os fd
genericMakeAbsolute ([Char] -> AbsDir os
forall os. System os => [Char] -> AbsDir os
asAbsDir [Char]
cwdString) Path os ar fd
p

-- prop_makeAbsoluteFromDir_startSameAbs :: AbsDir os -> AbsFile -> Property
-- prop_makeAbsoluteFromDir_startSameAbs base p = property $ show base `isPrefixOf` show (makeAbsolute base p)


-- | Convert a file to a directory path.
--   Obviously, the corresponding disk object won't change accordingly.
--   The purpose of this function is to be an intermediate step
--   when deriving a directory name from a file name.
dirFromFile :: FilePath os ar -> DirPath os ar
dirFromFile :: forall os ar. FilePath os ar -> DirPath os ar
dirFromFile FilePath os ar
p = (ar -> [Component os] -> Dir -> DirPath os ar)
-> (ar, [Component os]) -> Dir -> DirPath os ar
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ar -> [Component os] -> Dir -> DirPath os ar
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path (FilePath os ar -> (ar, [Component os])
forall fd os ar.
FileDir fd =>
Path os ar fd -> (ar, [Component os])
pathComponents FilePath os ar
p) Dir
Part.Dir

-- | Convert a directory to a file path.
--   The function returns 'Nothing' if the directory path is empty.
--   The purpose of this function is to be an intermediate step
--   when deriving a file name from a directory name.
fileFromDir :: DirPath os ar -> Maybe (FilePath os ar)
fileFromDir :: forall os ar. DirPath os ar -> Maybe (FilePath os ar)
fileFromDir = Path os ar Dir -> Maybe (FilePath os ar)
forall os ar fd. Path os ar fd -> Maybe (FilePath os ar)
fileFromAny

toFileDir :: (Class.FileDir fd) => Path os ar fd -> FileDirPath os ar
toFileDir :: forall fd os ar. FileDir fd => Path os ar fd -> FileDirPath os ar
toFileDir Path os ar fd
p = (ar -> [Component os] -> FileDir -> FileDirPath os ar)
-> (ar, [Component os]) -> FileDir -> FileDirPath os ar
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ar -> [Component os] -> FileDir -> FileDirPath os ar
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path (Path os ar fd -> (ar, [Component os])
forall fd os ar.
FileDir fd =>
Path os ar fd -> (ar, [Component os])
pathComponents Path os ar fd
p) FileDir
Part.FileDir

fromFileDir ::
    (Class.FileDir fd) => FileDirPath os ar -> Maybe (Path os ar fd)
fromFileDir :: forall fd os ar.
FileDir fd =>
FileDirPath os ar -> Maybe (Path os ar fd)
fromFileDir FileDirPath os ar
p =
    Maybe (FilePath os ar)
-> Maybe (DirPath os ar)
-> Maybe (FileDirPath os ar)
-> Maybe (Path os ar fd)
forall fd (f :: * -> *) os ar.
FileDir fd =>
f (FilePath os ar)
-> f (DirPath os ar) -> f (FileDirPath os ar) -> f (Path os ar fd)
switchFileDir
        (FileDirPath os ar -> Maybe (FilePath os ar)
forall os ar. FileDirPath os ar -> Maybe (FilePath os ar)
fileFromFileDir FileDirPath os ar
p)
        (DirPath os ar -> Maybe (DirPath os ar)
forall a. a -> Maybe a
Just (DirPath os ar -> Maybe (DirPath os ar))
-> DirPath os ar -> Maybe (DirPath os ar)
forall a b. (a -> b) -> a -> b
$ FileDirPath os ar -> DirPath os ar
forall os ar. FileDirPath os ar -> DirPath os ar
dirFromFileDir FileDirPath os ar
p)
        (FileDirPath os ar -> Maybe (FileDirPath os ar)
forall a. a -> Maybe a
Just FileDirPath os ar
p)

fileFromFileDir :: FileDirPath os ar -> Maybe (FilePath os ar)
fileFromFileDir :: forall os ar. FileDirPath os ar -> Maybe (FilePath os ar)
fileFromFileDir = Path os ar FileDir -> Maybe (FilePath os ar)
forall os ar fd. Path os ar fd -> Maybe (FilePath os ar)
fileFromAny

fileFromAny :: Path os ar fd -> Maybe (FilePath os ar)
fileFromAny :: forall os ar fd. Path os ar fd -> Maybe (FilePath os ar)
fileFromAny (Path ar
ar [Component os]
pcs fd
_) =
    (([Component os], Component os) -> FilePath os ar)
-> Maybe ([Component os], Component os) -> Maybe (FilePath os ar)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([Component os] -> File -> FilePath os ar)
-> ([Component os], File) -> FilePath os ar
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (ar -> [Component os] -> File -> FilePath os ar
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar) (([Component os], File) -> FilePath os ar)
-> (([Component os], Component os) -> ([Component os], File))
-> ([Component os], Component os)
-> FilePath os ar
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Component os -> File)
-> ([Component os], Component os) -> ([Component os], File)
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd (GenComponent -> File
Part.File (GenComponent -> File)
-> (Component os -> GenComponent) -> Component os -> File
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Component os -> GenComponent
forall os. Component os -> GenComponent
PC.untag)) (Maybe ([Component os], Component os) -> Maybe (FilePath os ar))
-> Maybe ([Component os], Component os) -> Maybe (FilePath os ar)
forall a b. (a -> b) -> a -> b
$ [Component os] -> Maybe ([Component os], Component os)
forall a. [a] -> Maybe ([a], a)
ListHT.viewR [Component os]
pcs

dirFromFileDir :: FileDirPath os ar -> DirPath os ar
dirFromFileDir :: forall os ar. FileDirPath os ar -> DirPath os ar
dirFromFileDir (Path ar
ar [Component os]
pcs FileDir
Part.FileDir) = ar -> [Component os] -> Dir -> Path os ar Dir
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar [Component os]
pcs Dir
Part.Dir


toAbsRel :: (Class.AbsRel ar) => Path os ar fd -> AbsRelPath os fd
toAbsRel :: forall ar os fd. AbsRel ar => Path os ar fd -> AbsRelPath os fd
toAbsRel (Path ar
ar [Component os]
pcs fd
fd) = AbsRel -> [Component os] -> fd -> Path os AbsRel fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path (ar -> AbsRel
forall ar. AbsRel ar => ar -> AbsRel
Class.toAbsRel ar
ar) [Component os]
pcs fd
fd

fromAbsRel :: (Class.AbsRel ar) => AbsRelPath os fd -> Maybe (Path os ar fd)
fromAbsRel :: forall ar os fd.
AbsRel ar =>
AbsRelPath os fd -> Maybe (Path os ar fd)
fromAbsRel (Path AbsRel
ar0 [Component os]
pcs fd
fd) = (\ar
ar -> ar -> [Component os] -> fd -> Path os ar fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar [Component os]
pcs fd
fd) (ar -> Path os ar fd) -> Maybe ar -> Maybe (Path os ar fd)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AbsRel -> Maybe ar
forall ar. AbsRel ar => AbsRel -> Maybe ar
Class.fromAbsRel AbsRel
ar0


------------------------------------------------------------------------
-- NYI - Not Yet Implemented

{-
splitSearchPath  :: String   -> [String]
getSearchPath    :: IO [String]
splitDrive       :: String   -> (String, String)
joinDrive        :: String   -> String -> String
takeDrive        :: String   -> String
hasDrive         :: String   -> Bool
dropDrive        :: String   -> String
isDrive          :: String   -> Bool
isValid          :: String   -> Bool
makeValid        :: String   -> String
-}

isDrive :: AbsDir os -> Bool
isDrive :: forall os. AbsDir os -> Bool
isDrive (Path Abs
_ [Component os]
pcs Dir
_) = [Component os] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Component os]
pcs


------------------------------------------------------------------------
-- Path Predicates

-- | Test whether a @'Path' ar fd@ is absolute.
--
-- prop> Path.isAbsolute (Posix.absFile "/fred")
-- prop> Path.isAbsolute (Windows.absFile "\\fred")
-- prop> Path.isAbsolute (Windows.absFile "c:\\fred")
-- prop> Path.isAbsolute (Windows.absFile "c:fred")
isAbsolute :: Class.AbsRel ar => Path os ar fd -> Bool
isAbsolute :: forall ar os fd. AbsRel ar => Path os ar fd -> Bool
isAbsolute = (AbsPath os fd -> Bool)
-> (RelPath os fd -> Bool) -> Path os ar fd -> Bool
forall ar os fd a.
AbsRel ar =>
(AbsPath os fd -> a) -> (RelPath os fd -> a) -> Path os ar fd -> a
withAbsRel (Bool -> AbsPath os fd -> Bool
forall a b. a -> b -> a
const Bool
True) (Bool -> RelPath os fd -> Bool
forall a b. a -> b -> a
const Bool
False)

-- | Invariant - this should return True iff arg is of type @'Path' Part.Rel _@
--
-- > isRelative = not . isAbsolute
-- prop> Path.isRelative (Posix.relFile "fred")
-- prop> Path.isRelative (Windows.relFile "fred")
isRelative :: Class.AbsRel ar => Path os ar fd -> Bool
isRelative :: forall ar os fd. AbsRel ar => Path os ar fd -> Bool
isRelative = Bool -> Bool
not (Bool -> Bool) -> (Path os ar fd -> Bool) -> Path os ar fd -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Path os ar fd -> Bool
forall ar os fd. AbsRel ar => Path os ar fd -> Bool
isAbsolute


{- |
Test whether the 'String' would correspond
to an absolute path if interpreted as a 'Path'.
-}
isAbsoluteString :: (System os) => Tagged os (String -> Bool)
isAbsoluteString :: forall os. System os => Tagged os ([Char] -> Bool)
isAbsoluteString =
    (StateT [Char] Identity [Char] -> [Char] -> Bool)
-> Tagged os (StateT [Char] Identity [Char])
-> Tagged os ([Char] -> Bool)
forall a b. (a -> b) -> Tagged os a -> Tagged os b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\StateT [Char] Identity [Char]
split -> Bool -> Bool
not (Bool -> Bool) -> ([Char] -> Bool) -> [Char] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Char] -> Bool) -> ([Char] -> [Char]) -> [Char] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StateT [Char] Identity [Char] -> [Char] -> [Char]
forall s a. State s a -> s -> a
MS.evalState StateT [Char] Identity [Char]
split) Tagged os (StateT [Char] Identity [Char])
forall os. System os => Tagged os (StateT [Char] Identity [Char])
splitAbsolute

{- |
Test whether the 'String' would correspond
to a relative path if interpreted as a 'Path'.

> isRelativeString = not . isAbsoluteString
-}
isRelativeString :: (System os) => Tagged os (String -> Bool)
isRelativeString :: forall os. System os => Tagged os ([Char] -> Bool)
isRelativeString = (Bool -> Bool
not (Bool -> Bool) -> ([Char] -> Bool) -> [Char] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) (([Char] -> Bool) -> [Char] -> Bool)
-> Tagged os ([Char] -> Bool) -> Tagged os ([Char] -> Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Tagged os ([Char] -> Bool)
forall os. System os => Tagged os ([Char] -> Bool)
isAbsoluteString


-- | Does the given filename have an extension?
--
-- prop> forAllAbsRel $ \x -> null (Path.takeExtension x) == not (Path.hasAnExtension x)
hasAnExtension :: FilePath os ar -> Bool
hasAnExtension :: forall os ar. FilePath os ar -> Bool
hasAnExtension = Bool -> Bool
not (Bool -> Bool)
-> (FilePath os ar -> Bool) -> FilePath os ar -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Char] -> Bool)
-> (FilePath os ar -> [Char]) -> FilePath os ar -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath os ar, [Char]) -> [Char]
forall a b. (a, b) -> b
snd ((FilePath os ar, [Char]) -> [Char])
-> (FilePath os ar -> (FilePath os ar, [Char]))
-> FilePath os ar
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath os ar -> (FilePath os ar, [Char])
forall os ar. FilePath os ar -> (FilePath os ar, [Char])
splitExtension

-- | Does the given filename have the given extension?
--
-- prop> Path.hasExtension ".hs" (Posix.relFile "MyCode.hs")
-- prop> Path.hasExtension ".hs" (Posix.relFile "MyCode.bak.hs")
-- prop> not $ Path.hasExtension ".hs" (Posix.relFile "MyCode.hs.bak")
hasExtension :: String -> FilePath os ar -> Bool
hasExtension :: forall os ar. [Char] -> FilePath os ar -> Bool
hasExtension [Char]
ext = ([Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
==[Char]
ext) ([Char] -> Bool)
-> (FilePath os ar -> [Char]) -> FilePath os ar -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath os ar, [Char]) -> [Char]
forall a b. (a, b) -> b
snd ((FilePath os ar, [Char]) -> [Char])
-> (FilePath os ar -> (FilePath os ar, [Char]))
-> FilePath os ar
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath os ar -> (FilePath os ar, [Char])
forall os ar. FilePath os ar -> (FilePath os ar, [Char])
splitExtension


------------------------------------------------------------------------
-- Separators

-- | Part.File extension character
--
-- prop> Posix.extSeparator == '.'
extSeparator :: Char
extSeparator :: Char
extSeparator = Char
Sep.extension

-- | The character that is used to separate the entries in the $PATH environment variable.
--
searchPathSeparator :: Char
searchPathSeparator :: Char
searchPathSeparator = Char
Sep.searchPath

-- | Is the character an extension character?
--
-- prop> \a -> Posix.isExtSeparator a == (a == Posix.extSeparator)
isExtSeparator :: Char -> Bool
isExtSeparator :: Char -> Bool
isExtSeparator = Char -> Bool
Sep.isExtension

-- | Is the character a file separator?
--
-- prop> \a -> Posix.isSearchPathSeparator a == (a == Posix.searchPathSeparator)
isSearchPathSeparator :: Char -> Bool
isSearchPathSeparator :: Char -> Bool
isSearchPathSeparator = Char -> Bool
Sep.isSearchPath


------------------------------------------------------------------------
-- Generic Manipulation Functions

-- These functions support manipulation of extensions on directories
-- as well as files. They have looser types than the corresponding
-- 'Basic Manipulation Functions', but it is expected that the basic
-- functions will be used more frequently as they provide more checks.

-- | This is a more flexible variant of 'addExtension' / '<.>' which can
--   work with files or directories
--
-- prop> Path.genericAddExtension (absDir "/") "x" == Posix.absDir "/.x"
-- prop> Path.genericAddExtension (absDir "/a") "x" == Posix.absDir "/a.x"
-- prop> Path.genericAddExtension Path.emptyFile "x" == Posix.relFile ".x"
-- prop> Path.genericAddExtension Path.emptyFile "" == Posix.emptyFile
genericAddExtension ::
    (Class.FileDir fd) => Path os ar fd -> String -> Path os ar fd
genericAddExtension :: forall fd os ar.
FileDir fd =>
Path os ar fd -> [Char] -> Path os ar fd
genericAddExtension =
    ([Char] -> Path os ar fd -> Path os ar fd)
-> Path os ar fd -> [Char] -> Path os ar fd
forall a b c. (a -> b -> c) -> b -> a -> c
flip (([Char] -> Path os ar fd -> Path os ar fd)
 -> Path os ar fd -> [Char] -> Path os ar fd)
-> ([Char] -> Path os ar fd -> Path os ar fd)
-> Path os ar fd
-> [Char]
-> Path os ar fd
forall a b. (a -> b) -> a -> b
$ \[Char]
ext ->
        Endo (Path os ar fd) -> Path os ar fd -> Path os ar fd
forall a. Endo a -> a -> a
appEndo (Endo (Path os ar fd) -> Path os ar fd -> Path os ar fd)
-> Endo (Path os ar fd) -> Path os ar fd -> Path os ar fd
forall a b. (a -> b) -> a -> b
$ Bool -> Endo (Path os ar fd) -> Endo (Path os ar fd)
forall m. Monoid m => Bool -> m -> m
MonHT.when (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Char] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Char]
ext) (Endo (Path os ar fd) -> Endo (Path os ar fd))
-> Endo (Path os ar fd) -> Endo (Path os ar fd)
forall a b. (a -> b) -> a -> b
$
        Endo (FilePath os ar)
-> Endo (DirPath os ar)
-> Endo (FileDirPath os ar)
-> Endo (Path os ar fd)
forall fd (f :: * -> *) os ar.
FileDir fd =>
f (FilePath os ar)
-> f (DirPath os ar) -> f (FileDirPath os ar) -> f (Path os ar fd)
switchFileDir
            ((FilePath os ar -> FilePath os ar) -> Endo (FilePath os ar)
forall a. (a -> a) -> Endo a
Endo ((FilePath os ar -> FilePath os ar) -> Endo (FilePath os ar))
-> (FilePath os ar -> FilePath os ar) -> Endo (FilePath os ar)
forall a b. (a -> b) -> a -> b
$ (FilePath os ar -> [Char] -> FilePath os ar)
-> [Char] -> FilePath os ar -> FilePath os ar
forall a b c. (a -> b -> c) -> b -> a -> c
flip FilePath os ar -> [Char] -> FilePath os ar
forall os ar. FilePath os ar -> [Char] -> FilePath os ar
addExtension [Char]
ext)
            ((DirPath os ar -> DirPath os ar) -> Endo (DirPath os ar)
forall a. (a -> a) -> Endo a
Endo ((DirPath os ar -> DirPath os ar) -> Endo (DirPath os ar))
-> (DirPath os ar -> DirPath os ar) -> Endo (DirPath os ar)
forall a b. (a -> b) -> a -> b
$ [Char] -> DirPath os ar -> DirPath os ar
forall os ar fd. [Char] -> Path os ar fd -> Path os ar fd
componentsAddExtension [Char]
ext)
            ((FileDirPath os ar -> FileDirPath os ar)
-> Endo (FileDirPath os ar)
forall a. (a -> a) -> Endo a
Endo ((FileDirPath os ar -> FileDirPath os ar)
 -> Endo (FileDirPath os ar))
-> (FileDirPath os ar -> FileDirPath os ar)
-> Endo (FileDirPath os ar)
forall a b. (a -> b) -> a -> b
$ [Char] -> FileDirPath os ar -> FileDirPath os ar
forall os ar fd. [Char] -> Path os ar fd -> Path os ar fd
componentsAddExtension [Char]
ext)

componentsAddExtension :: String -> Path os ar fd -> Path os ar fd
componentsAddExtension :: forall os ar fd. [Char] -> Path os ar fd -> Path os ar fd
componentsAddExtension [Char]
ext (Path ar
ar [Component os]
pcs0 fd
fd) =
    let pcs :: [Component os]
pcs = if [Component os] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Component os]
pcs0 then [Component os
forall os. Component os
PC.empty] else [Component os]
pcs0
    in  ar -> [Component os] -> fd -> Path os ar fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar ((Component os -> Component os) -> [Component os] -> [Component os]
forall a. (a -> a) -> [a] -> [a]
mapLast ((Component os -> [Char] -> Component os)
-> [Char] -> Component os -> Component os
forall a b c. (a -> b -> c) -> b -> a -> c
flip Component os -> [Char] -> Component os
forall os. Component os -> [Char] -> Component os
PC.addExtension [Char]
ext) [Component os]
pcs) fd
fd

genericDropExtension :: (Class.FileDir fd) => Path os ar fd -> Path os ar fd
genericDropExtension :: forall fd os ar. FileDir fd => Path os ar fd -> Path os ar fd
genericDropExtension = (Path os ar fd, [Char]) -> Path os ar fd
forall a b. (a, b) -> a
fst ((Path os ar fd, [Char]) -> Path os ar fd)
-> (Path os ar fd -> (Path os ar fd, [Char]))
-> Path os ar fd
-> Path os ar fd
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Path os ar fd -> (Path os ar fd, [Char])
forall fd os ar.
FileDir fd =>
Path os ar fd -> (Path os ar fd, [Char])
genericSplitExtension

genericDropExtensions :: (Class.FileDir fd) => Path os ar fd -> Path os ar fd
genericDropExtensions :: forall fd os ar. FileDir fd => Path os ar fd -> Path os ar fd
genericDropExtensions = (Path os ar fd, [Char]) -> Path os ar fd
forall a b. (a, b) -> a
fst ((Path os ar fd, [Char]) -> Path os ar fd)
-> (Path os ar fd -> (Path os ar fd, [Char]))
-> Path os ar fd
-> Path os ar fd
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Path os ar fd -> (Path os ar fd, [Char])
forall fd os ar.
FileDir fd =>
Path os ar fd -> (Path os ar fd, [Char])
genericSplitExtensions

genericSplitExtension ::
    (Class.FileDir fd) => Path os ar fd -> (Path os ar fd, String)
genericSplitExtension :: forall fd os ar.
FileDir fd =>
Path os ar fd -> (Path os ar fd, [Char])
genericSplitExtension =
    SplitExtension (Path os ar fd)
-> Path os ar fd -> (Path os ar fd, [Char])
forall path. SplitExtension path -> path -> (path, [Char])
runSplitExtension (SplitExtension (Path os ar fd)
 -> Path os ar fd -> (Path os ar fd, [Char]))
-> SplitExtension (Path os ar fd)
-> Path os ar fd
-> (Path os ar fd, [Char])
forall a b. (a -> b) -> a -> b
$
    SplitExtension (FilePath os ar)
-> SplitExtension (DirPath os ar)
-> SplitExtension (FileDirPath os ar)
-> SplitExtension (Path os ar fd)
forall fd (f :: * -> *) os ar.
FileDir fd =>
f (FilePath os ar)
-> f (DirPath os ar) -> f (FileDirPath os ar) -> f (Path os ar fd)
switchFileDir
        ((FilePath os ar -> (FilePath os ar, [Char]))
-> SplitExtension (FilePath os ar)
forall path. (path -> (path, [Char])) -> SplitExtension path
SplitExtension FilePath os ar -> (FilePath os ar, [Char])
forall os ar. FilePath os ar -> (FilePath os ar, [Char])
splitExtension)
        ((DirPath os ar -> (DirPath os ar, [Char]))
-> SplitExtension (DirPath os ar)
forall path. (path -> (path, [Char])) -> SplitExtension path
SplitExtension DirPath os ar -> (DirPath os ar, [Char])
forall os ar b. Path os ar b -> (Path os ar b, [Char])
componentsSplitExtension)
        ((FileDirPath os ar -> (FileDirPath os ar, [Char]))
-> SplitExtension (FileDirPath os ar)
forall path. (path -> (path, [Char])) -> SplitExtension path
SplitExtension FileDirPath os ar -> (FileDirPath os ar, [Char])
forall os ar b. Path os ar b -> (Path os ar b, [Char])
componentsSplitExtension)

componentsSplitExtension :: Path os ar b -> (Path os ar b, String)
componentsSplitExtension :: forall os ar b. Path os ar b -> (Path os ar b, [Char])
componentsSplitExtension (Path ar
ar [Component os]
pcs b
fd) =
    ([Component os] -> Path os ar b)
-> ([Component os], [Char]) -> (Path os ar b, [Char])
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (([Component os] -> b -> Path os ar b)
-> b -> [Component os] -> Path os ar b
forall a b c. (a -> b -> c) -> b -> a -> c
flip (ar -> [Component os] -> b -> Path os ar b
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar) b
fd) (([Component os], [Char]) -> (Path os ar b, [Char]))
-> ([Component os], [Char]) -> (Path os ar b, [Char])
forall a b. (a -> b) -> a -> b
$
    [Char]
-> (Component os -> (Component os, [Char]))
-> [Component os]
-> ([Component os], [Char])
forall b a. b -> (a -> (a, b)) -> [a] -> ([a], b)
mapLastPair
        ([Char] -> [Char]
forall a. HasCallStack => [Char] -> a
error [Char]
"genericSplitExtension: empty path")
        Component os -> (Component os, [Char])
forall os. Component os -> (Component os, [Char])
PC.splitExtension [Component os]
pcs

genericSplitExtensions ::
    (Class.FileDir fd) => Path os ar fd -> (Path os ar fd, String)
genericSplitExtensions :: forall fd os ar.
FileDir fd =>
Path os ar fd -> (Path os ar fd, [Char])
genericSplitExtensions =
    SplitExtension (Path os ar fd)
-> Path os ar fd -> (Path os ar fd, [Char])
forall path. SplitExtension path -> path -> (path, [Char])
runSplitExtension (SplitExtension (Path os ar fd)
 -> Path os ar fd -> (Path os ar fd, [Char]))
-> SplitExtension (Path os ar fd)
-> Path os ar fd
-> (Path os ar fd, [Char])
forall a b. (a -> b) -> a -> b
$
    SplitExtension (FilePath os ar)
-> SplitExtension (DirPath os ar)
-> SplitExtension (FileDirPath os ar)
-> SplitExtension (Path os ar fd)
forall fd (f :: * -> *) os ar.
FileDir fd =>
f (FilePath os ar)
-> f (DirPath os ar) -> f (FileDirPath os ar) -> f (Path os ar fd)
switchFileDir
        ((FilePath os ar -> (FilePath os ar, [Char]))
-> SplitExtension (FilePath os ar)
forall path. (path -> (path, [Char])) -> SplitExtension path
SplitExtension FilePath os ar -> (FilePath os ar, [Char])
forall os ar. FilePath os ar -> (FilePath os ar, [Char])
splitExtensions)
        ((DirPath os ar -> (DirPath os ar, [Char]))
-> SplitExtension (DirPath os ar)
forall path. (path -> (path, [Char])) -> SplitExtension path
SplitExtension DirPath os ar -> (DirPath os ar, [Char])
forall os ar b. Path os ar b -> (Path os ar b, [Char])
componentsSplitExtensions)
        ((FileDirPath os ar -> (FileDirPath os ar, [Char]))
-> SplitExtension (FileDirPath os ar)
forall path. (path -> (path, [Char])) -> SplitExtension path
SplitExtension FileDirPath os ar -> (FileDirPath os ar, [Char])
forall os ar b. Path os ar b -> (Path os ar b, [Char])
componentsSplitExtensions)

componentsSplitExtensions :: Path os ar b -> (Path os ar b, String)
componentsSplitExtensions :: forall os ar b. Path os ar b -> (Path os ar b, [Char])
componentsSplitExtensions (Path ar
ar [Component os]
pcs b
fd) =
    ([Component os] -> Path os ar b)
-> ([Component os], [Char]) -> (Path os ar b, [Char])
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (([Component os] -> b -> Path os ar b)
-> b -> [Component os] -> Path os ar b
forall a b c. (a -> b -> c) -> b -> a -> c
flip (ar -> [Component os] -> b -> Path os ar b
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar) b
fd) (([Component os], [Char]) -> (Path os ar b, [Char]))
-> ([Component os], [Char]) -> (Path os ar b, [Char])
forall a b. (a -> b) -> a -> b
$
    [Char]
-> (Component os -> (Component os, [Char]))
-> [Component os]
-> ([Component os], [Char])
forall b a. b -> (a -> (a, b)) -> [a] -> ([a], b)
mapLastPair
        ([Char] -> [Char]
forall a. HasCallStack => [Char] -> a
error [Char]
"genericSplitExtensions: empty path")
        Component os -> (Component os, [Char])
forall os. Component os -> (Component os, [Char])
PC.splitExtensions [Component os]
pcs

genericTakeExtension :: (Class.FileDir fd) => Path os ar fd -> String
genericTakeExtension :: forall fd os ar. FileDir fd => Path os ar fd -> [Char]
genericTakeExtension = (Path os ar fd, [Char]) -> [Char]
forall a b. (a, b) -> b
snd ((Path os ar fd, [Char]) -> [Char])
-> (Path os ar fd -> (Path os ar fd, [Char]))
-> Path os ar fd
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Path os ar fd -> (Path os ar fd, [Char])
forall fd os ar.
FileDir fd =>
Path os ar fd -> (Path os ar fd, [Char])
genericSplitExtension

genericTakeExtensions :: (Class.FileDir fd) => Path os ar fd -> String
genericTakeExtensions :: forall fd os ar. FileDir fd => Path os ar fd -> [Char]
genericTakeExtensions = (Path os ar fd, [Char]) -> [Char]
forall a b. (a, b) -> b
snd ((Path os ar fd, [Char]) -> [Char])
-> (Path os ar fd -> (Path os ar fd, [Char]))
-> Path os ar fd
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Path os ar fd -> (Path os ar fd, [Char])
forall fd os ar.
FileDir fd =>
Path os ar fd -> (Path os ar fd, [Char])
genericSplitExtension

newtype
    SplitExtension path =
        SplitExtension {forall path. SplitExtension path -> path -> (path, [Char])
runSplitExtension :: path -> (path, String)}


-- move to utility-ht
mapLast :: (a -> a) -> [a] -> [a]
mapLast :: forall a. (a -> a) -> [a] -> [a]
mapLast a -> a
f [a]
xs = ((a -> a) -> a -> a) -> [a -> a] -> [a] -> [a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (a -> a) -> a -> a
forall a. a -> a
id (Int -> [a -> a] -> [a -> a]
forall a. Int -> [a] -> [a]
drop Int
1 ([a -> a] -> [a -> a]) -> [a -> a] -> [a -> a]
forall a b. (a -> b) -> a -> b
$ (a -> a -> a) -> [a] -> [a -> a]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> a) -> a -> a -> a
forall a b. a -> b -> a
const a -> a
forall a. a -> a
id) [a]
xs [a -> a] -> [a -> a] -> [a -> a]
forall a. [a] -> [a] -> [a]
++ [a -> a
f]) [a]
xs

mapLastPair :: b -> (a -> (a,b)) -> [a] -> ([a], b)
mapLastPair :: forall b a. b -> (a -> (a, b)) -> [a] -> ([a], b)
mapLastPair b
b a -> (a, b)
f =
    ([a], b) -> ([a] -> a -> ([a], b)) -> [a] -> ([a], b)
forall b a. b -> ([a] -> a -> b) -> [a] -> b
ListHT.switchR ([], b
b) (\[a]
as a
a -> (a -> [a]) -> (a, b) -> ([a], b)
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (([a]
as[a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++) ([a] -> [a]) -> (a -> [a]) -> a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> [a] -> [a]
forall a. a -> [a] -> [a]
:[])) ((a, b) -> ([a], b)) -> (a, b) -> ([a], b)
forall a b. (a -> b) -> a -> b
$ a -> (a, b)
f a
a)

mapLastPairFoldr :: b -> (a -> (a,b)) -> [a] -> ([a], b)
mapLastPairFoldr :: forall b a. b -> (a -> (a, b)) -> [a] -> ([a], b)
mapLastPairFoldr b
b a -> (a, b)
_ [] = ([], b
b)
mapLastPairFoldr b
_ a -> (a, b)
f (a
x:[a]
xs) =
    (a -> (a -> ([a], b)) -> a -> ([a], b))
-> (a -> ([a], b)) -> [a] -> a -> ([a], b)
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr
        (\a
y1 a -> ([a], b)
go a
y0 -> ([a] -> [a]) -> ([a], b) -> ([a], b)
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (a
y0a -> [a] -> [a]
forall a. a -> [a] -> [a]
:) (([a], b) -> ([a], b)) -> ([a], b) -> ([a], b)
forall a b. (a -> b) -> a -> b
$ a -> ([a], b)
go a
y1)
        (\a
y -> (a -> [a]) -> (a, b) -> ([a], b)
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (a -> [a] -> [a]
forall a. a -> [a] -> [a]
:[]) ((a, b) -> ([a], b)) -> (a, b) -> ([a], b)
forall a b. (a -> b) -> a -> b
$ a -> (a, b)
f a
y)
        [a]
xs a
x

mapLastPairRec :: b -> (a -> (a,b)) -> [a] -> ([a], b)
mapLastPairRec :: forall b a. b -> (a -> (a, b)) -> [a] -> ([a], b)
mapLastPairRec b
b a -> (a, b)
_ [] = ([], b
b)
mapLastPairRec b
_ a -> (a, b)
f (a
x:[a]
xs) =
    let go :: a -> [a] -> ([a], b)
go a
y [] = (a -> [a]) -> (a, b) -> ([a], b)
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (a -> [a] -> [a]
forall a. a -> [a] -> [a]
:[]) ((a, b) -> ([a], b)) -> (a, b) -> ([a], b)
forall a b. (a -> b) -> a -> b
$ a -> (a, b)
f a
y
        go a
y0 (a
y1:[a]
ys) = ([a] -> [a]) -> ([a], b) -> ([a], b)
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (a
y0a -> [a] -> [a]
forall a. a -> [a] -> [a]
:) (([a], b) -> ([a], b)) -> ([a], b) -> ([a], b)
forall a b. (a -> b) -> a -> b
$ a -> [a] -> ([a], b)
go a
y1 [a]
ys
    in  a -> [a] -> ([a], b)
go a
x [a]
xs

mapLastPairRev :: b -> (a -> (a,b)) -> [a] -> ([a], b)
mapLastPairRev :: forall b a. b -> (a -> (a, b)) -> [a] -> ([a], b)
mapLastPairRev b
b0 a -> (a, b)
f [a]
xs =
    case [a] -> [a]
forall a. [a] -> [a]
reverse [a]
xs of
        [] -> ([a]
xs, b
b0)
        a
y:[a]
ys ->
            let (a
a, b
b) = a -> (a, b)
f a
y
            in  ([a] -> [a]
forall a. [a] -> [a]
reverse [a]
ys [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a
a], b
b)

_prop_mapLastPair :: String -> Int -> [String] -> Bool
_prop_mapLastPair :: [Char] -> Int -> [[Char]] -> Bool
_prop_mapLastPair [Char]
b Int
n [[Char]]
strs =
    let f :: [a] -> ([a], [a])
f = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
n
    in  (([[Char]], [Char]) -> Bool) -> [([[Char]], [Char])] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ([Char]
-> ([Char] -> ([Char], [Char])) -> [[Char]] -> ([[Char]], [Char])
forall b a. b -> (a -> (a, b)) -> [a] -> ([a], b)
mapLastPair [Char]
b [Char] -> ([Char], [Char])
forall {a}. [a] -> ([a], [a])
f [[Char]]
strs ([[Char]], [Char]) -> ([[Char]], [Char]) -> Bool
forall a. Eq a => a -> a -> Bool
==) ([([[Char]], [Char])] -> Bool) -> [([[Char]], [Char])] -> Bool
forall a b. (a -> b) -> a -> b
$
            [Char]
-> ([Char] -> ([Char], [Char])) -> [[Char]] -> ([[Char]], [Char])
forall b a. b -> (a -> (a, b)) -> [a] -> ([a], b)
mapLastPairFoldr [Char]
b [Char] -> ([Char], [Char])
forall {a}. [a] -> ([a], [a])
f [[Char]]
strs ([[Char]], [Char]) -> [([[Char]], [Char])] -> [([[Char]], [Char])]
forall a. a -> [a] -> [a]
:
            [Char]
-> ([Char] -> ([Char], [Char])) -> [[Char]] -> ([[Char]], [Char])
forall b a. b -> (a -> (a, b)) -> [a] -> ([a], b)
mapLastPairRev [Char]
b [Char] -> ([Char], [Char])
forall {a}. [a] -> ([a], [a])
f [[Char]]
strs ([[Char]], [Char]) -> [([[Char]], [Char])] -> [([[Char]], [Char])]
forall a. a -> [a] -> [a]
:
            [Char]
-> ([Char] -> ([Char], [Char])) -> [[Char]] -> ([[Char]], [Char])
forall b a. b -> (a -> (a, b)) -> [a] -> ([a], b)
mapLastPairRec [Char]
b [Char] -> ([Char], [Char])
forall {a}. [a] -> ([a], [a])
f [[Char]]
strs ([[Char]], [Char]) -> [([[Char]], [Char])] -> [([[Char]], [Char])]
forall a. a -> [a] -> [a]
:
            []



{- |
Check internal integrity of the path data structure.
-}
isValid ::
    (System os, Class.AbsRel ar, Class.FileDir fd) =>
    Path os ar fd -> Bool
isValid :: forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Path os ar fd -> Bool
isValid = Tagged os (Path os ar fd -> Bool) -> Path os ar fd -> Bool
forall {k} (s :: k) b. Tagged s b -> b
untag Tagged os (Path os ar fd -> Bool)
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Tagged os (Path os ar fd -> Bool)
isValidTagged

isValidTagged ::
    (System os, Class.AbsRel ar, Class.FileDir fd) =>
    Tagged os (Path os ar fd -> Bool)
isValidTagged :: forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Tagged os (Path os ar fd -> Bool)
isValidTagged =
    ((Component os -> Bool) -> Path os ar fd -> Bool)
-> Tagged os (Component os -> Bool)
-> Tagged os (Path os ar fd -> Bool)
forall a b. (a -> b) -> Tagged os a -> Tagged os b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
        (\Component os -> Bool
isValidPC (Path ar
ar [Component os]
pcs fd
fd) ->
            ([Char] -> Bool) -> Bool -> ar -> Bool
forall ar a. AbsRel ar => ([Char] -> a) -> a -> ar -> a
Class.withAbsRel [Char] -> Bool
isValidComponent Bool
True ar
ar
            Bool -> Bool -> Bool
&&
            (Component os -> Bool) -> [Component os] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Component os -> Bool
isValidPC [Component os]
pcs
            Bool -> Bool -> Bool
&&
            (GenComponent -> Bool) -> Bool -> Bool -> fd -> Bool
forall fd a. FileDir fd => (GenComponent -> a) -> a -> a -> fd -> a
Class.withFileDir (Component os -> Bool
isValidPC (Component os -> Bool)
-> (GenComponent -> Component os) -> GenComponent -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenComponent -> Component os
forall os. GenComponent -> Component os
PC.retag) Bool
True Bool
True fd
fd)
        Tagged os (Component os -> Bool)
forall os. System os => Tagged os (Component os -> Bool)
isValidPathComponent

isValidComponent :: String -> Bool
isValidComponent :: [Char] -> Bool
isValidComponent = Bool -> Bool
not (Bool -> Bool) -> ([Char] -> Bool) -> [Char] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null

isValidPathComponent ::
    (System os) => Tagged os (Component os -> Bool)
isValidPathComponent :: forall os. System os => Tagged os (Component os -> Bool)
isValidPathComponent =
    ((Char -> Bool) -> Component os -> Bool)
-> Tagged os (Char -> Bool) -> Tagged os (Component os -> Bool)
forall a b. (a -> b) -> Tagged os a -> Tagged os b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
        (\Char -> Bool
isSep (Component [Char]
str) ->
            [Char] -> Bool
isValidComponent [Char]
str  Bool -> Bool -> Bool
&&  Bool -> Bool
not ((Char -> Bool) -> [Char] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Char -> Bool
isSep [Char]
str))
        Tagged os (Char -> Bool)
forall os. System os => Tagged os (Char -> Bool)
isPathSeparator

------------------------------------------------------------------------
-- QuickCheck

testAll :: (System os) => os -> [(String, DocTest.T ())]
testAll :: forall os. System os => os -> [([Char], T ())]
testAll os
os =
    ([Char]
"mkPathFromComponents_pathComponents",
        os -> (Path os Abs Dir -> Property) -> T ()
forall prop os fd ar.
(Testable prop, System os, FileDir fd, AbsRel ar) =>
os -> (Path os ar fd -> prop) -> T ()
quickCheck os
os Path os Abs Dir -> Property
forall os. System os => AbsDir os -> Property
prop_mkPathFromComponents_pathComponents) ([Char], T ()) -> [([Char], T ())] -> [([Char], T ())]
forall a. a -> [a] -> [a]
:
    ([Char]
"splitDir_combine",
        os -> (Path os Abs Dir -> Property) -> T ()
forall prop os fd ar.
(Testable prop, System os, FileDir fd, AbsRel ar) =>
os -> (Path os ar fd -> prop) -> T ()
quickCheck os
os Path os Abs Dir -> Property
forall os. System os => AbsDir os -> Property
prop_splitDir_combine) ([Char], T ()) -> [([Char], T ())] -> [([Char], T ())]
forall a. a -> [a] -> [a]
:
    ([Char]
"takeDirName_end",
        os -> (Path os Abs Dir -> Property) -> T ()
forall prop os fd ar.
(Testable prop, System os, FileDir fd, AbsRel ar) =>
os -> (Path os ar fd -> prop) -> T ()
quickCheck os
os Path os Abs Dir -> Property
forall os. System os => AbsDir os -> Property
prop_takeDirName_end) ([Char], T ()) -> [([Char], T ())] -> [([Char], T ())]
forall a. a -> [a] -> [a]
:
    []

quickCheck ::
    (QC.Testable prop, System os, Class.FileDir fd, Class.AbsRel ar) =>
    os -> (Path os ar fd -> prop) -> DocTest.T ()
quickCheck :: forall prop os fd ar.
(Testable prop, System os, FileDir fd, AbsRel ar) =>
os -> (Path os ar fd -> prop) -> T ()
quickCheck os
_ = (Path os ar fd -> prop) -> T ()
forall prop. Testable prop => prop -> T ()
DocTest.property

-- test :: Testable a => a -> IO ()
-- test = quickCheck

qcFileComponent :: Gen (Component os)
qcFileComponent :: forall os. Gen (Component os)
qcFileComponent = [Char] -> Component os
forall os. [Char] -> Component os
Component ([Char] -> Component os) -> Gen [Char] -> Gen (Component os)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Int, Gen [Char])] -> Gen [Char]
forall a. [(Int, Gen a)] -> Gen a
frequency [
                    (Int
1, [Char] -> Gen [Char]
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"someFile"),
                    (Int
1, [Char] -> Gen [Char]
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"fileWith.ext"),
                    (Int
1, [Char] -> Gen [Char]
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"file.with.multiple.exts"),
                    (Int
1, [Char] -> Gen [Char]
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"file with spcs")
                  ]

qcDirComponent :: Gen (Component os)
qcDirComponent :: forall os. Gen (Component os)
qcDirComponent = [Char] -> Component os
forall os. [Char] -> Component os
Component ([Char] -> Component os) -> Gen [Char] -> Gen (Component os)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Int, Gen [Char])] -> Gen [Char]
forall a. [(Int, Gen a)] -> Gen a
frequency [
                    (Int
1, [Char] -> Gen [Char]
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"someDir"),
                    (Int
1, [Char] -> Gen [Char]
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"aDir"),
                    (Int
1, [Char] -> Gen [Char]
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"aFolder"),
                    (Int
1, [Char] -> Gen [Char]
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"a folder"),
                    (Int
1, [Char] -> Gen [Char]
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"directory")
                  ]


qcAbsRel :: (System os, Class.AbsRel ar) => Tagged os (Gen ar)
qcAbsRel :: forall os ar. (System os, AbsRel ar) => Tagged os (Gen ar)
qcAbsRel =
    ((Gen [Char] -> Gen ar)
 -> Tagged os (Gen [Char]) -> Tagged os (Gen ar))
-> Tagged os (Gen [Char])
-> (Gen [Char] -> Gen ar)
-> Tagged os (Gen ar)
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Gen [Char] -> Gen ar)
-> Tagged os (Gen [Char]) -> Tagged os (Gen ar)
forall a b. (a -> b) -> Tagged os a -> Tagged os b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Tagged os (Gen [Char])
forall os. System os => Tagged os (Gen [Char])
genDrive ((Gen [Char] -> Gen ar) -> Tagged os (Gen ar))
-> (Gen [Char] -> Gen ar) -> Tagged os (Gen ar)
forall a b. (a -> b) -> a -> b
$ \Gen [Char]
drive ->
        Gen Abs -> Gen Rel -> Gen AbsRel -> Gen ar
forall ar (f :: * -> *).
AbsRel ar =>
f Abs -> f Rel -> f AbsRel -> f ar
forall (f :: * -> *). f Abs -> f Rel -> f AbsRel -> f ar
Class.switchAbsRel (([Char] -> Abs) -> Gen [Char] -> Gen Abs
forall a b. (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Char] -> Abs
absPC Gen [Char]
drive) (Rel -> Gen Rel
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return Rel
Part.Rel)
            ([Gen AbsRel] -> Gen AbsRel
forall a. [Gen a] -> Gen a
QC.oneof
                [([Char] -> AbsRel) -> Gen [Char] -> Gen AbsRel
forall a b. (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (GenComponent -> AbsRel
Part.AbsO (GenComponent -> AbsRel)
-> ([Char] -> GenComponent) -> [Char] -> AbsRel
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> GenComponent
forall os. [Char] -> Component os
Component) Gen [Char]
drive, AbsRel -> Gen AbsRel
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return AbsRel
Part.RelO])

qcGenPath ::
    Tagged os (Gen ar) ->
    (Gen ar -> Gen (Path os ar fd)) ->
    Gen (Path os ar fd)
qcGenPath :: forall os ar fd.
Tagged os (Gen ar)
-> (Gen ar -> Gen (Path os ar fd)) -> Gen (Path os ar fd)
qcGenPath Tagged os (Gen ar)
qcAR Gen ar -> Gen (Path os ar fd)
gen = Gen ar -> Gen (Path os ar fd)
gen (Gen ar -> Gen (Path os ar fd)) -> Gen ar -> Gen (Path os ar fd)
forall a b. (a -> b) -> a -> b
$ Tagged os (Gen ar) -> Gen ar
forall {k} (s :: k) b. Tagged s b -> b
untag Tagged os (Gen ar)
qcAR

qcFilePath :: (System os, Class.AbsRel ar) => Gen (FilePath os ar)
qcFilePath :: forall os ar. (System os, AbsRel ar) => Gen (FilePath os ar)
qcFilePath = Tagged os (Gen ar)
-> (Gen ar -> Gen (Path os ar File)) -> Gen (Path os ar File)
forall os ar fd.
Tagged os (Gen ar)
-> (Gen ar -> Gen (Path os ar fd)) -> Gen (Path os ar fd)
qcGenPath Tagged os (Gen ar)
forall os ar. (System os, AbsRel ar) => Tagged os (Gen ar)
qcAbsRel ((Gen ar -> Gen (Path os ar File)) -> Gen (Path os ar File))
-> (Gen ar -> Gen (Path os ar File)) -> Gen (Path os ar File)
forall a b. (a -> b) -> a -> b
$ \Gen ar
qcAR -> do
    ar
ar <- Gen ar
qcAR
    [Component os]
pcs <- Gen (Component os) -> Gen [Component os]
forall a. Gen a -> Gen [a]
QC.listOf Gen (Component os)
forall os. Gen (Component os)
qcDirComponent
    GenComponent
pc <- Gen GenComponent
forall os. Gen (Component os)
qcFileComponent
    Path os ar File -> Gen (Path os ar File)
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return (Path os ar File -> Gen (Path os ar File))
-> Path os ar File -> Gen (Path os ar File)
forall a b. (a -> b) -> a -> b
$ ar -> [Component os] -> File -> Path os ar File
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar [Component os]
pcs (File -> Path os ar File) -> File -> Path os ar File
forall a b. (a -> b) -> a -> b
$ GenComponent -> File
Part.File GenComponent
pc

qcDirPath :: (System os, Class.AbsRel ar) => fd -> Gen (Path os ar fd)
qcDirPath :: forall os ar fd.
(System os, AbsRel ar) =>
fd -> Gen (Path os ar fd)
qcDirPath fd
fd = Tagged os (Gen ar)
-> (Gen ar -> Gen (Path os ar fd)) -> Gen (Path os ar fd)
forall os ar fd.
Tagged os (Gen ar)
-> (Gen ar -> Gen (Path os ar fd)) -> Gen (Path os ar fd)
qcGenPath Tagged os (Gen ar)
forall os ar. (System os, AbsRel ar) => Tagged os (Gen ar)
qcAbsRel ((Gen ar -> Gen (Path os ar fd)) -> Gen (Path os ar fd))
-> (Gen ar -> Gen (Path os ar fd)) -> Gen (Path os ar fd)
forall a b. (a -> b) -> a -> b
$ \Gen ar
qcAR -> do
    ar
ar <- Gen ar
qcAR
    [Component os]
pcs <- Gen (Component os) -> Gen [Component os]
forall a. Gen a -> Gen [a]
QC.listOf Gen (Component os)
forall os. Gen (Component os)
qcDirComponent
    Path os ar fd -> Gen (Path os ar fd)
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return (Path os ar fd -> Gen (Path os ar fd))
-> Path os ar fd -> Gen (Path os ar fd)
forall a b. (a -> b) -> a -> b
$ ar -> [Component os] -> fd -> Path os ar fd
forall os ar fd. ar -> [Component os] -> fd -> Path os ar fd
Path ar
ar [Component os]
pcs fd
fd

qcPath ::
    (System os, Class.AbsRel ar, Class.FileDir fd) => Gen (Path os ar fd)
qcPath :: forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Gen (Path os ar fd)
qcPath =
    Gen (FilePath os ar)
-> Gen (DirPath os ar)
-> Gen (FileDirPath os ar)
-> Gen (Path os ar fd)
forall fd (f :: * -> *) os ar.
FileDir fd =>
f (FilePath os ar)
-> f (DirPath os ar) -> f (FileDirPath os ar) -> f (Path os ar fd)
switchFileDir Gen (FilePath os ar)
forall os ar. (System os, AbsRel ar) => Gen (FilePath os ar)
qcFilePath (Dir -> Gen (DirPath os ar)
forall os ar fd.
(System os, AbsRel ar) =>
fd -> Gen (Path os ar fd)
qcDirPath Dir
Part.Dir) (FileDir -> Gen (FileDirPath os ar)
forall os ar fd.
(System os, AbsRel ar) =>
fd -> Gen (Path os ar fd)
qcDirPath FileDir
Part.FileDir)

instance
    (System os, Class.AbsRel ar, Class.FileDir fd) =>
        Arbitrary (Path os ar fd) where
    arbitrary :: Gen (Path os ar fd)
arbitrary = Gen (Path os ar fd)
forall os ar fd.
(System os, AbsRel ar, FileDir fd) =>
Gen (Path os ar fd)
qcPath