{-# language DeriveDataTypeable #-}
{-# language DeriveFoldable #-}
{-# language DeriveFunctor #-}
{-# language DeriveGeneric #-}
{-# language DeriveTraversable #-}
{-# language LambdaCase #-}
{-|
Description:
  Contains the tree data structure used to store directory hierarchies
-}
module System.Directory.Contents.Types where

import Data.Data
import Data.Map (Map)
import qualified Data.Map as Map
import GHC.Generics
import System.FilePath

-- | The contents of a directory, represented as a tree. See 'Symlink' for
-- special handling of symlinks.
data DirTree a
  = DirTree_Dir FilePath (Map FileName (DirTree a))
  | DirTree_File FilePath a
  | DirTree_Symlink FilePath (Symlink a)
  deriving (Int -> DirTree a -> ShowS
[DirTree a] -> ShowS
DirTree a -> String
(Int -> DirTree a -> ShowS)
-> (DirTree a -> String)
-> ([DirTree a] -> ShowS)
-> Show (DirTree a)
forall a. Show a => Int -> DirTree a -> ShowS
forall a. Show a => [DirTree a] -> ShowS
forall a. Show a => DirTree a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DirTree a] -> ShowS
$cshowList :: forall a. Show a => [DirTree a] -> ShowS
show :: DirTree a -> String
$cshow :: forall a. Show a => DirTree a -> String
showsPrec :: Int -> DirTree a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> DirTree a -> ShowS
Show, ReadPrec [DirTree a]
ReadPrec (DirTree a)
Int -> ReadS (DirTree a)
ReadS [DirTree a]
(Int -> ReadS (DirTree a))
-> ReadS [DirTree a]
-> ReadPrec (DirTree a)
-> ReadPrec [DirTree a]
-> Read (DirTree a)
forall a. Read a => ReadPrec [DirTree a]
forall a. Read a => ReadPrec (DirTree a)
forall a. Read a => Int -> ReadS (DirTree a)
forall a. Read a => ReadS [DirTree a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [DirTree a]
$creadListPrec :: forall a. Read a => ReadPrec [DirTree a]
readPrec :: ReadPrec (DirTree a)
$creadPrec :: forall a. Read a => ReadPrec (DirTree a)
readList :: ReadS [DirTree a]
$creadList :: forall a. Read a => ReadS [DirTree a]
readsPrec :: Int -> ReadS (DirTree a)
$creadsPrec :: forall a. Read a => Int -> ReadS (DirTree a)
Read, DirTree a -> DirTree a -> Bool
(DirTree a -> DirTree a -> Bool)
-> (DirTree a -> DirTree a -> Bool) -> Eq (DirTree a)
forall a. Eq a => DirTree a -> DirTree a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DirTree a -> DirTree a -> Bool
$c/= :: forall a. Eq a => DirTree a -> DirTree a -> Bool
== :: DirTree a -> DirTree a -> Bool
$c== :: forall a. Eq a => DirTree a -> DirTree a -> Bool
Eq, Eq (DirTree a)
Eq (DirTree a)
-> (DirTree a -> DirTree a -> Ordering)
-> (DirTree a -> DirTree a -> Bool)
-> (DirTree a -> DirTree a -> Bool)
-> (DirTree a -> DirTree a -> Bool)
-> (DirTree a -> DirTree a -> Bool)
-> (DirTree a -> DirTree a -> DirTree a)
-> (DirTree a -> DirTree a -> DirTree a)
-> Ord (DirTree a)
DirTree a -> DirTree a -> Bool
DirTree a -> DirTree a -> Ordering
DirTree a -> DirTree a -> DirTree a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (DirTree a)
forall a. Ord a => DirTree a -> DirTree a -> Bool
forall a. Ord a => DirTree a -> DirTree a -> Ordering
forall a. Ord a => DirTree a -> DirTree a -> DirTree a
min :: DirTree a -> DirTree a -> DirTree a
$cmin :: forall a. Ord a => DirTree a -> DirTree a -> DirTree a
max :: DirTree a -> DirTree a -> DirTree a
$cmax :: forall a. Ord a => DirTree a -> DirTree a -> DirTree a
>= :: DirTree a -> DirTree a -> Bool
$c>= :: forall a. Ord a => DirTree a -> DirTree a -> Bool
> :: DirTree a -> DirTree a -> Bool
$c> :: forall a. Ord a => DirTree a -> DirTree a -> Bool
<= :: DirTree a -> DirTree a -> Bool
$c<= :: forall a. Ord a => DirTree a -> DirTree a -> Bool
< :: DirTree a -> DirTree a -> Bool
$c< :: forall a. Ord a => DirTree a -> DirTree a -> Bool
compare :: DirTree a -> DirTree a -> Ordering
$ccompare :: forall a. Ord a => DirTree a -> DirTree a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (DirTree a)
Ord, a -> DirTree b -> DirTree a
(a -> b) -> DirTree a -> DirTree b
(forall a b. (a -> b) -> DirTree a -> DirTree b)
-> (forall a b. a -> DirTree b -> DirTree a) -> Functor DirTree
forall a b. a -> DirTree b -> DirTree a
forall a b. (a -> b) -> DirTree a -> DirTree b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> DirTree b -> DirTree a
$c<$ :: forall a b. a -> DirTree b -> DirTree a
fmap :: (a -> b) -> DirTree a -> DirTree b
$cfmap :: forall a b. (a -> b) -> DirTree a -> DirTree b
Functor, DirTree a -> Bool
(a -> m) -> DirTree a -> m
(a -> b -> b) -> b -> DirTree a -> b
(forall m. Monoid m => DirTree m -> m)
-> (forall m a. Monoid m => (a -> m) -> DirTree a -> m)
-> (forall m a. Monoid m => (a -> m) -> DirTree a -> m)
-> (forall a b. (a -> b -> b) -> b -> DirTree a -> b)
-> (forall a b. (a -> b -> b) -> b -> DirTree a -> b)
-> (forall b a. (b -> a -> b) -> b -> DirTree a -> b)
-> (forall b a. (b -> a -> b) -> b -> DirTree a -> b)
-> (forall a. (a -> a -> a) -> DirTree a -> a)
-> (forall a. (a -> a -> a) -> DirTree a -> a)
-> (forall a. DirTree a -> [a])
-> (forall a. DirTree a -> Bool)
-> (forall a. DirTree a -> Int)
-> (forall a. Eq a => a -> DirTree a -> Bool)
-> (forall a. Ord a => DirTree a -> a)
-> (forall a. Ord a => DirTree a -> a)
-> (forall a. Num a => DirTree a -> a)
-> (forall a. Num a => DirTree a -> a)
-> Foldable DirTree
forall a. Eq a => a -> DirTree a -> Bool
forall a. Num a => DirTree a -> a
forall a. Ord a => DirTree a -> a
forall m. Monoid m => DirTree m -> m
forall a. DirTree a -> Bool
forall a. DirTree a -> Int
forall a. DirTree a -> [a]
forall a. (a -> a -> a) -> DirTree a -> a
forall m a. Monoid m => (a -> m) -> DirTree a -> m
forall b a. (b -> a -> b) -> b -> DirTree a -> b
forall a b. (a -> b -> b) -> b -> DirTree a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: DirTree a -> a
$cproduct :: forall a. Num a => DirTree a -> a
sum :: DirTree a -> a
$csum :: forall a. Num a => DirTree a -> a
minimum :: DirTree a -> a
$cminimum :: forall a. Ord a => DirTree a -> a
maximum :: DirTree a -> a
$cmaximum :: forall a. Ord a => DirTree a -> a
elem :: a -> DirTree a -> Bool
$celem :: forall a. Eq a => a -> DirTree a -> Bool
length :: DirTree a -> Int
$clength :: forall a. DirTree a -> Int
null :: DirTree a -> Bool
$cnull :: forall a. DirTree a -> Bool
toList :: DirTree a -> [a]
$ctoList :: forall a. DirTree a -> [a]
foldl1 :: (a -> a -> a) -> DirTree a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> DirTree a -> a
foldr1 :: (a -> a -> a) -> DirTree a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> DirTree a -> a
foldl' :: (b -> a -> b) -> b -> DirTree a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> DirTree a -> b
foldl :: (b -> a -> b) -> b -> DirTree a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> DirTree a -> b
foldr' :: (a -> b -> b) -> b -> DirTree a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> DirTree a -> b
foldr :: (a -> b -> b) -> b -> DirTree a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> DirTree a -> b
foldMap' :: (a -> m) -> DirTree a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> DirTree a -> m
foldMap :: (a -> m) -> DirTree a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> DirTree a -> m
fold :: DirTree m -> m
$cfold :: forall m. Monoid m => DirTree m -> m
Foldable, Functor DirTree
Foldable DirTree
Functor DirTree
-> Foldable DirTree
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> DirTree a -> f (DirTree b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    DirTree (f a) -> f (DirTree a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> DirTree a -> m (DirTree b))
-> (forall (m :: * -> *) a.
    Monad m =>
    DirTree (m a) -> m (DirTree a))
-> Traversable DirTree
(a -> f b) -> DirTree a -> f (DirTree b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => DirTree (m a) -> m (DirTree a)
forall (f :: * -> *) a.
Applicative f =>
DirTree (f a) -> f (DirTree a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> DirTree a -> m (DirTree b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> DirTree a -> f (DirTree b)
sequence :: DirTree (m a) -> m (DirTree a)
$csequence :: forall (m :: * -> *) a. Monad m => DirTree (m a) -> m (DirTree a)
mapM :: (a -> m b) -> DirTree a -> m (DirTree b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> DirTree a -> m (DirTree b)
sequenceA :: DirTree (f a) -> f (DirTree a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
DirTree (f a) -> f (DirTree a)
traverse :: (a -> f b) -> DirTree a -> f (DirTree b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> DirTree a -> f (DirTree b)
$cp2Traversable :: Foldable DirTree
$cp1Traversable :: Functor DirTree
Traversable, (forall x. DirTree a -> Rep (DirTree a) x)
-> (forall x. Rep (DirTree a) x -> DirTree a)
-> Generic (DirTree a)
forall x. Rep (DirTree a) x -> DirTree a
forall x. DirTree a -> Rep (DirTree a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (DirTree a) x -> DirTree a
forall a x. DirTree a -> Rep (DirTree a) x
$cto :: forall a x. Rep (DirTree a) x -> DirTree a
$cfrom :: forall a x. DirTree a -> Rep (DirTree a) x
Generic, Typeable (DirTree a)
DataType
Constr
Typeable (DirTree a)
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DirTree a -> c (DirTree a))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (DirTree a))
-> (DirTree a -> Constr)
-> (DirTree a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (DirTree a)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (DirTree a)))
-> ((forall b. Data b => b -> b) -> DirTree a -> DirTree a)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DirTree a -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DirTree a -> r)
-> (forall u. (forall d. Data d => d -> u) -> DirTree a -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> DirTree a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DirTree a -> m (DirTree a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DirTree a -> m (DirTree a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DirTree a -> m (DirTree a))
-> Data (DirTree a)
DirTree a -> DataType
DirTree a -> Constr
(forall d. Data d => c (t d)) -> Maybe (c (DirTree a))
(forall b. Data b => b -> b) -> DirTree a -> DirTree a
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DirTree a -> c (DirTree a)
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (DirTree a)
forall a. Data a => Typeable (DirTree a)
forall a. Data a => DirTree a -> DataType
forall a. Data a => DirTree a -> Constr
forall a.
Data a =>
(forall b. Data b => b -> b) -> DirTree a -> DirTree a
forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> DirTree a -> u
forall a u.
Data a =>
(forall d. Data d => d -> u) -> DirTree a -> [u]
forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DirTree a -> r
forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DirTree a -> r
forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> DirTree a -> m (DirTree a)
forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> DirTree a -> m (DirTree a)
forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (DirTree a)
forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DirTree a -> c (DirTree a)
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (DirTree a))
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (DirTree a))
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> DirTree a -> u
forall u. (forall d. Data d => d -> u) -> DirTree a -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DirTree a -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DirTree a -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DirTree a -> m (DirTree a)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DirTree a -> m (DirTree a)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (DirTree a)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DirTree a -> c (DirTree a)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (DirTree a))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (DirTree a))
$cDirTree_Symlink :: Constr
$cDirTree_File :: Constr
$cDirTree_Dir :: Constr
$tDirTree :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> DirTree a -> m (DirTree a)
$cgmapMo :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> DirTree a -> m (DirTree a)
gmapMp :: (forall d. Data d => d -> m d) -> DirTree a -> m (DirTree a)
$cgmapMp :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> DirTree a -> m (DirTree a)
gmapM :: (forall d. Data d => d -> m d) -> DirTree a -> m (DirTree a)
$cgmapM :: forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> DirTree a -> m (DirTree a)
gmapQi :: Int -> (forall d. Data d => d -> u) -> DirTree a -> u
$cgmapQi :: forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> DirTree a -> u
gmapQ :: (forall d. Data d => d -> u) -> DirTree a -> [u]
$cgmapQ :: forall a u.
Data a =>
(forall d. Data d => d -> u) -> DirTree a -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DirTree a -> r
$cgmapQr :: forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DirTree a -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DirTree a -> r
$cgmapQl :: forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DirTree a -> r
gmapT :: (forall b. Data b => b -> b) -> DirTree a -> DirTree a
$cgmapT :: forall a.
Data a =>
(forall b. Data b => b -> b) -> DirTree a -> DirTree a
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (DirTree a))
$cdataCast2 :: forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (DirTree a))
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (DirTree a))
$cdataCast1 :: forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (DirTree a))
dataTypeOf :: DirTree a -> DataType
$cdataTypeOf :: forall a. Data a => DirTree a -> DataType
toConstr :: DirTree a -> Constr
$ctoConstr :: forall a. Data a => DirTree a -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (DirTree a)
$cgunfold :: forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (DirTree a)
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DirTree a -> c (DirTree a)
$cgfoldl :: forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DirTree a -> c (DirTree a)
$cp1Data :: forall a. Data a => Typeable (DirTree a)
Data)

-- | Symlink cycles are prevented by separating symlinks into two categories:
-- those that point to paths already within the directory hierarchy being
-- recursively listed, and those that are not. In the former case, rather than
-- following the symlink and listing the target redundantly, we simply store
-- the symlink reference itself. In the latter case, we treat the symlink as we
-- would any other folder and produce a list of its contents.
--
-- The 'String' argument represents the symlink reference (e.g., "../somefile").
-- In the 'Symlink_Internal' case, the second ('FilePath') argument is the path
-- to the symlink target.
-- In the 'Symlink_External' case, the second (@[DirTree a]@) argument contains
-- the contents of the symlink target.
data Symlink a
  = Symlink_Internal String FilePath
  | Symlink_External String (Map FileName (DirTree a))
  deriving (Int -> Symlink a -> ShowS
[Symlink a] -> ShowS
Symlink a -> String
(Int -> Symlink a -> ShowS)
-> (Symlink a -> String)
-> ([Symlink a] -> ShowS)
-> Show (Symlink a)
forall a. Show a => Int -> Symlink a -> ShowS
forall a. Show a => [Symlink a] -> ShowS
forall a. Show a => Symlink a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Symlink a] -> ShowS
$cshowList :: forall a. Show a => [Symlink a] -> ShowS
show :: Symlink a -> String
$cshow :: forall a. Show a => Symlink a -> String
showsPrec :: Int -> Symlink a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Symlink a -> ShowS
Show, ReadPrec [Symlink a]
ReadPrec (Symlink a)
Int -> ReadS (Symlink a)
ReadS [Symlink a]
(Int -> ReadS (Symlink a))
-> ReadS [Symlink a]
-> ReadPrec (Symlink a)
-> ReadPrec [Symlink a]
-> Read (Symlink a)
forall a. Read a => ReadPrec [Symlink a]
forall a. Read a => ReadPrec (Symlink a)
forall a. Read a => Int -> ReadS (Symlink a)
forall a. Read a => ReadS [Symlink a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Symlink a]
$creadListPrec :: forall a. Read a => ReadPrec [Symlink a]
readPrec :: ReadPrec (Symlink a)
$creadPrec :: forall a. Read a => ReadPrec (Symlink a)
readList :: ReadS [Symlink a]
$creadList :: forall a. Read a => ReadS [Symlink a]
readsPrec :: Int -> ReadS (Symlink a)
$creadsPrec :: forall a. Read a => Int -> ReadS (Symlink a)
Read, Symlink a -> Symlink a -> Bool
(Symlink a -> Symlink a -> Bool)
-> (Symlink a -> Symlink a -> Bool) -> Eq (Symlink a)
forall a. Eq a => Symlink a -> Symlink a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Symlink a -> Symlink a -> Bool
$c/= :: forall a. Eq a => Symlink a -> Symlink a -> Bool
== :: Symlink a -> Symlink a -> Bool
$c== :: forall a. Eq a => Symlink a -> Symlink a -> Bool
Eq, Eq (Symlink a)
Eq (Symlink a)
-> (Symlink a -> Symlink a -> Ordering)
-> (Symlink a -> Symlink a -> Bool)
-> (Symlink a -> Symlink a -> Bool)
-> (Symlink a -> Symlink a -> Bool)
-> (Symlink a -> Symlink a -> Bool)
-> (Symlink a -> Symlink a -> Symlink a)
-> (Symlink a -> Symlink a -> Symlink a)
-> Ord (Symlink a)
Symlink a -> Symlink a -> Bool
Symlink a -> Symlink a -> Ordering
Symlink a -> Symlink a -> Symlink a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Symlink a)
forall a. Ord a => Symlink a -> Symlink a -> Bool
forall a. Ord a => Symlink a -> Symlink a -> Ordering
forall a. Ord a => Symlink a -> Symlink a -> Symlink a
min :: Symlink a -> Symlink a -> Symlink a
$cmin :: forall a. Ord a => Symlink a -> Symlink a -> Symlink a
max :: Symlink a -> Symlink a -> Symlink a
$cmax :: forall a. Ord a => Symlink a -> Symlink a -> Symlink a
>= :: Symlink a -> Symlink a -> Bool
$c>= :: forall a. Ord a => Symlink a -> Symlink a -> Bool
> :: Symlink a -> Symlink a -> Bool
$c> :: forall a. Ord a => Symlink a -> Symlink a -> Bool
<= :: Symlink a -> Symlink a -> Bool
$c<= :: forall a. Ord a => Symlink a -> Symlink a -> Bool
< :: Symlink a -> Symlink a -> Bool
$c< :: forall a. Ord a => Symlink a -> Symlink a -> Bool
compare :: Symlink a -> Symlink a -> Ordering
$ccompare :: forall a. Ord a => Symlink a -> Symlink a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (Symlink a)
Ord, a -> Symlink b -> Symlink a
(a -> b) -> Symlink a -> Symlink b
(forall a b. (a -> b) -> Symlink a -> Symlink b)
-> (forall a b. a -> Symlink b -> Symlink a) -> Functor Symlink
forall a b. a -> Symlink b -> Symlink a
forall a b. (a -> b) -> Symlink a -> Symlink b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Symlink b -> Symlink a
$c<$ :: forall a b. a -> Symlink b -> Symlink a
fmap :: (a -> b) -> Symlink a -> Symlink b
$cfmap :: forall a b. (a -> b) -> Symlink a -> Symlink b
Functor, Symlink a -> Bool
(a -> m) -> Symlink a -> m
(a -> b -> b) -> b -> Symlink a -> b
(forall m. Monoid m => Symlink m -> m)
-> (forall m a. Monoid m => (a -> m) -> Symlink a -> m)
-> (forall m a. Monoid m => (a -> m) -> Symlink a -> m)
-> (forall a b. (a -> b -> b) -> b -> Symlink a -> b)
-> (forall a b. (a -> b -> b) -> b -> Symlink a -> b)
-> (forall b a. (b -> a -> b) -> b -> Symlink a -> b)
-> (forall b a. (b -> a -> b) -> b -> Symlink a -> b)
-> (forall a. (a -> a -> a) -> Symlink a -> a)
-> (forall a. (a -> a -> a) -> Symlink a -> a)
-> (forall a. Symlink a -> [a])
-> (forall a. Symlink a -> Bool)
-> (forall a. Symlink a -> Int)
-> (forall a. Eq a => a -> Symlink a -> Bool)
-> (forall a. Ord a => Symlink a -> a)
-> (forall a. Ord a => Symlink a -> a)
-> (forall a. Num a => Symlink a -> a)
-> (forall a. Num a => Symlink a -> a)
-> Foldable Symlink
forall a. Eq a => a -> Symlink a -> Bool
forall a. Num a => Symlink a -> a
forall a. Ord a => Symlink a -> a
forall m. Monoid m => Symlink m -> m
forall a. Symlink a -> Bool
forall a. Symlink a -> Int
forall a. Symlink a -> [a]
forall a. (a -> a -> a) -> Symlink a -> a
forall m a. Monoid m => (a -> m) -> Symlink a -> m
forall b a. (b -> a -> b) -> b -> Symlink a -> b
forall a b. (a -> b -> b) -> b -> Symlink a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: Symlink a -> a
$cproduct :: forall a. Num a => Symlink a -> a
sum :: Symlink a -> a
$csum :: forall a. Num a => Symlink a -> a
minimum :: Symlink a -> a
$cminimum :: forall a. Ord a => Symlink a -> a
maximum :: Symlink a -> a
$cmaximum :: forall a. Ord a => Symlink a -> a
elem :: a -> Symlink a -> Bool
$celem :: forall a. Eq a => a -> Symlink a -> Bool
length :: Symlink a -> Int
$clength :: forall a. Symlink a -> Int
null :: Symlink a -> Bool
$cnull :: forall a. Symlink a -> Bool
toList :: Symlink a -> [a]
$ctoList :: forall a. Symlink a -> [a]
foldl1 :: (a -> a -> a) -> Symlink a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Symlink a -> a
foldr1 :: (a -> a -> a) -> Symlink a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Symlink a -> a
foldl' :: (b -> a -> b) -> b -> Symlink a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Symlink a -> b
foldl :: (b -> a -> b) -> b -> Symlink a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Symlink a -> b
foldr' :: (a -> b -> b) -> b -> Symlink a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Symlink a -> b
foldr :: (a -> b -> b) -> b -> Symlink a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Symlink a -> b
foldMap' :: (a -> m) -> Symlink a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Symlink a -> m
foldMap :: (a -> m) -> Symlink a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Symlink a -> m
fold :: Symlink m -> m
$cfold :: forall m. Monoid m => Symlink m -> m
Foldable, Functor Symlink
Foldable Symlink
Functor Symlink
-> Foldable Symlink
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Symlink a -> f (Symlink b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Symlink (f a) -> f (Symlink a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Symlink a -> m (Symlink b))
-> (forall (m :: * -> *) a.
    Monad m =>
    Symlink (m a) -> m (Symlink a))
-> Traversable Symlink
(a -> f b) -> Symlink a -> f (Symlink b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Symlink (m a) -> m (Symlink a)
forall (f :: * -> *) a.
Applicative f =>
Symlink (f a) -> f (Symlink a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Symlink a -> m (Symlink b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Symlink a -> f (Symlink b)
sequence :: Symlink (m a) -> m (Symlink a)
$csequence :: forall (m :: * -> *) a. Monad m => Symlink (m a) -> m (Symlink a)
mapM :: (a -> m b) -> Symlink a -> m (Symlink b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Symlink a -> m (Symlink b)
sequenceA :: Symlink (f a) -> f (Symlink a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
Symlink (f a) -> f (Symlink a)
traverse :: (a -> f b) -> Symlink a -> f (Symlink b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Symlink a -> f (Symlink b)
$cp2Traversable :: Foldable Symlink
$cp1Traversable :: Functor Symlink
Traversable, (forall x. Symlink a -> Rep (Symlink a) x)
-> (forall x. Rep (Symlink a) x -> Symlink a)
-> Generic (Symlink a)
forall x. Rep (Symlink a) x -> Symlink a
forall x. Symlink a -> Rep (Symlink a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Symlink a) x -> Symlink a
forall a x. Symlink a -> Rep (Symlink a) x
$cto :: forall a x. Rep (Symlink a) x -> Symlink a
$cfrom :: forall a x. Symlink a -> Rep (Symlink a) x
Generic, Typeable (Symlink a)
DataType
Constr
Typeable (Symlink a)
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Symlink a -> c (Symlink a))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Symlink a))
-> (Symlink a -> Constr)
-> (Symlink a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Symlink a)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Symlink a)))
-> ((forall b. Data b => b -> b) -> Symlink a -> Symlink a)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Symlink a -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Symlink a -> r)
-> (forall u. (forall d. Data d => d -> u) -> Symlink a -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> Symlink a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Symlink a -> m (Symlink a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Symlink a -> m (Symlink a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Symlink a -> m (Symlink a))
-> Data (Symlink a)
Symlink a -> DataType
Symlink a -> Constr
(forall d. Data d => c (t d)) -> Maybe (c (Symlink a))
(forall b. Data b => b -> b) -> Symlink a -> Symlink a
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Symlink a -> c (Symlink a)
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Symlink a)
forall a. Data a => Typeable (Symlink a)
forall a. Data a => Symlink a -> DataType
forall a. Data a => Symlink a -> Constr
forall a.
Data a =>
(forall b. Data b => b -> b) -> Symlink a -> Symlink a
forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> Symlink a -> u
forall a u.
Data a =>
(forall d. Data d => d -> u) -> Symlink a -> [u]
forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Symlink a -> r
forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Symlink a -> r
forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Symlink a -> m (Symlink a)
forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Symlink a -> m (Symlink a)
forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Symlink a)
forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Symlink a -> c (Symlink a)
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Symlink a))
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Symlink a))
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Symlink a -> u
forall u. (forall d. Data d => d -> u) -> Symlink a -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Symlink a -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Symlink a -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Symlink a -> m (Symlink a)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Symlink a -> m (Symlink a)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Symlink a)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Symlink a -> c (Symlink a)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Symlink a))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Symlink a))
$cSymlink_External :: Constr
$cSymlink_Internal :: Constr
$tSymlink :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Symlink a -> m (Symlink a)
$cgmapMo :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Symlink a -> m (Symlink a)
gmapMp :: (forall d. Data d => d -> m d) -> Symlink a -> m (Symlink a)
$cgmapMp :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Symlink a -> m (Symlink a)
gmapM :: (forall d. Data d => d -> m d) -> Symlink a -> m (Symlink a)
$cgmapM :: forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Symlink a -> m (Symlink a)
gmapQi :: Int -> (forall d. Data d => d -> u) -> Symlink a -> u
$cgmapQi :: forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> Symlink a -> u
gmapQ :: (forall d. Data d => d -> u) -> Symlink a -> [u]
$cgmapQ :: forall a u.
Data a =>
(forall d. Data d => d -> u) -> Symlink a -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Symlink a -> r
$cgmapQr :: forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Symlink a -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Symlink a -> r
$cgmapQl :: forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Symlink a -> r
gmapT :: (forall b. Data b => b -> b) -> Symlink a -> Symlink a
$cgmapT :: forall a.
Data a =>
(forall b. Data b => b -> b) -> Symlink a -> Symlink a
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Symlink a))
$cdataCast2 :: forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Symlink a))
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (Symlink a))
$cdataCast1 :: forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Symlink a))
dataTypeOf :: Symlink a -> DataType
$cdataTypeOf :: forall a. Data a => Symlink a -> DataType
toConstr :: Symlink a -> Constr
$ctoConstr :: forall a. Data a => Symlink a -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Symlink a)
$cgunfold :: forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Symlink a)
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Symlink a -> c (Symlink a)
$cgfoldl :: forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Symlink a -> c (Symlink a)
$cp1Data :: forall a. Data a => Typeable (Symlink a)
Data)

-- * Utilities

-- | Extract the 'FilePath' from a 'DirTree' node
filePath :: DirTree a -> FilePath
filePath :: DirTree a -> String
filePath = \case
  DirTree_Dir String
f Map String (DirTree a)
_ -> String
f
  DirTree_File String
f a
_ -> String
f
  DirTree_Symlink String
f Symlink a
_ -> String
f

-- | File names, as opposed to file paths, are used to uniquely identify
-- siblings at each level
type FileName = String

-- | Generate the key used to identify siblings
fileName :: DirTree a -> FileName
fileName :: DirTree a -> String
fileName = ShowS
takeFileName ShowS -> (DirTree a -> String) -> DirTree a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DirTree a -> String
forall a. DirTree a -> String
filePath

-- | Construct a map of files indexed by filename. Should only be used for a
-- particular generation or level in the directory hierarchy (since that's the
-- only time we can be sure that names are unique)
fileNameMap :: [DirTree a] -> Map FileName (DirTree a)
fileNameMap :: [DirTree a] -> Map String (DirTree a)
fileNameMap [DirTree a]
xs = [(String, DirTree a)] -> Map String (DirTree a)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(String, DirTree a)] -> Map String (DirTree a))
-> [(String, DirTree a)] -> Map String (DirTree a)
forall a b. (a -> b) -> a -> b
$ [String] -> [DirTree a] -> [(String, DirTree a)]
forall a b. [a] -> [b] -> [(a, b)]
zip (DirTree a -> String
forall a. DirTree a -> String
fileName (DirTree a -> String) -> [DirTree a] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [DirTree a]
xs) [DirTree a]
xs

-- | Add a sibling to a map of files
insertSibling :: DirTree a -> Map FileName (DirTree a) -> Map FileName (DirTree a)
insertSibling :: DirTree a -> Map String (DirTree a) -> Map String (DirTree a)
insertSibling DirTree a
a = String
-> DirTree a -> Map String (DirTree a) -> Map String (DirTree a)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert (DirTree a -> String
forall a. DirTree a -> String
fileName DirTree a
a) DirTree a
a

-- | Remove sibling from a map of files
removeSibling :: DirTree a -> Map FileName (DirTree a) -> Map FileName (DirTree a)
removeSibling :: DirTree a -> Map String (DirTree a) -> Map String (DirTree a)
removeSibling DirTree a
a = String -> Map String (DirTree a) -> Map String (DirTree a)
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete (DirTree a -> String
forall a. DirTree a -> String
fileName DirTree a
a)

-- | Map a function over the first child and the rest of the children
withFirstChild
  :: Map FileName (DirTree a)
  -> (DirTree a -> Map FileName (DirTree a) -> x)
  -> Maybe x
withFirstChild :: Map String (DirTree a)
-> (DirTree a -> Map String (DirTree a) -> x) -> Maybe x
withFirstChild Map String (DirTree a)
m DirTree a -> Map String (DirTree a) -> x
f = case Map String (DirTree a) -> Maybe (DirTree a, Map String (DirTree a))
forall k a. Map k a -> Maybe (a, Map k a)
Map.minView Map String (DirTree a)
m of
  Maybe (DirTree a, Map String (DirTree a))
Nothing -> Maybe x
forall a. Maybe a
Nothing
  Just (DirTree a
firstChild, Map String (DirTree a)
children) -> x -> Maybe x
forall a. a -> Maybe a
Just (x -> Maybe x) -> x -> Maybe x
forall a b. (a -> b) -> a -> b
$ DirTree a -> Map String (DirTree a) -> x
f DirTree a
firstChild Map String (DirTree a)
children