{-# LANGUAGE CPP, GeneralizedNewtypeDeriving, BangPatterns, DeriveTraversable, ScopedTypeVariables, RankNTypes #-}
module Codec.Archive.Tar.Types (
GenEntry(..),
Entry,
entryPath,
GenEntryContent(..),
EntryContent,
FileSize,
Permissions,
Ownership(..),
EpochTime,
TypeCode,
DevMajor,
DevMinor,
Format(..),
simpleEntry,
longLinkEntry,
longSymLinkEntry,
fileEntry,
symlinkEntry,
directoryEntry,
ordinaryFilePermissions,
symbolicLinkPermission,
executableFilePermissions,
directoryPermissions,
TarPath(..),
toTarPath,
toTarPath',
ToTarPathResult(..),
fromTarPath,
fromTarPathToPosixPath,
fromTarPathToWindowsPath,
fromFilePathToNative,
LinkTarget(..),
toLinkTarget,
fromLinkTarget,
fromLinkTargetToPosixPath,
fromLinkTargetToWindowsPath,
fromFilePathToWindowsPath,
GenEntries(..),
Entries,
mapEntries,
mapEntriesNoFail,
foldEntries,
foldlEntries,
unfoldEntries,
) where
import Data.Int (Int64)
import Data.List.NonEmpty (NonEmpty(..))
import Data.Monoid (Monoid(..))
import Data.Semigroup as Sem
import Data.Typeable
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BS.Char8
import qualified Data.ByteString.Lazy as LBS
import Control.DeepSeq
import Control.Exception (Exception, displayException)
import qualified System.FilePath as FilePath.Native
( joinPath, splitDirectories, addTrailingPathSeparator, hasTrailingPathSeparator, pathSeparator, isAbsolute, hasTrailingPathSeparator )
import qualified System.FilePath.Posix as FilePath.Posix
( joinPath, splitPath, splitDirectories, hasTrailingPathSeparator
, addTrailingPathSeparator, pathSeparator )
import qualified System.FilePath.Windows as FilePath.Windows
( joinPath, addTrailingPathSeparator, pathSeparator )
import System.Posix.Types
( FileMode )
import Codec.Archive.Tar.PackAscii
type FileSize = Int64
type EpochTime = Int64
type DevMajor = Int
type DevMinor = Int
type TypeCode = Char
type Permissions = FileMode
data GenEntry tarPath linkTarget = Entry {
forall tarPath linkTarget. GenEntry tarPath linkTarget -> tarPath
entryTarPath :: !tarPath,
forall tarPath linkTarget.
GenEntry tarPath linkTarget -> GenEntryContent linkTarget
entryContent :: !(GenEntryContent linkTarget),
forall tarPath linkTarget.
GenEntry tarPath linkTarget -> Permissions
entryPermissions :: {-# UNPACK #-} !Permissions,
forall tarPath linkTarget. GenEntry tarPath linkTarget -> Ownership
entryOwnership :: {-# UNPACK #-} !Ownership,
forall tarPath linkTarget. GenEntry tarPath linkTarget -> EpochTime
entryTime :: {-# UNPACK #-} !EpochTime,
forall tarPath linkTarget. GenEntry tarPath linkTarget -> Format
entryFormat :: !Format
}
deriving (GenEntry tarPath linkTarget -> GenEntry tarPath linkTarget -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall tarPath linkTarget.
(Eq tarPath, Eq linkTarget) =>
GenEntry tarPath linkTarget -> GenEntry tarPath linkTarget -> Bool
/= :: GenEntry tarPath linkTarget -> GenEntry tarPath linkTarget -> Bool
$c/= :: forall tarPath linkTarget.
(Eq tarPath, Eq linkTarget) =>
GenEntry tarPath linkTarget -> GenEntry tarPath linkTarget -> Bool
== :: GenEntry tarPath linkTarget -> GenEntry tarPath linkTarget -> Bool
$c== :: forall tarPath linkTarget.
(Eq tarPath, Eq linkTarget) =>
GenEntry tarPath linkTarget -> GenEntry tarPath linkTarget -> Bool
Eq, Int -> GenEntry tarPath linkTarget -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall tarPath linkTarget.
(Show tarPath, Show linkTarget) =>
Int -> GenEntry tarPath linkTarget -> ShowS
forall tarPath linkTarget.
(Show tarPath, Show linkTarget) =>
[GenEntry tarPath linkTarget] -> ShowS
forall tarPath linkTarget.
(Show tarPath, Show linkTarget) =>
GenEntry tarPath linkTarget -> String
showList :: [GenEntry tarPath linkTarget] -> ShowS
$cshowList :: forall tarPath linkTarget.
(Show tarPath, Show linkTarget) =>
[GenEntry tarPath linkTarget] -> ShowS
show :: GenEntry tarPath linkTarget -> String
$cshow :: forall tarPath linkTarget.
(Show tarPath, Show linkTarget) =>
GenEntry tarPath linkTarget -> String
showsPrec :: Int -> GenEntry tarPath linkTarget -> ShowS
$cshowsPrec :: forall tarPath linkTarget.
(Show tarPath, Show linkTarget) =>
Int -> GenEntry tarPath linkTarget -> ShowS
Show)
type Entry = GenEntry TarPath LinkTarget
entryPath :: GenEntry TarPath linkTarget -> FilePath
entryPath :: forall linkTarget. GenEntry TarPath linkTarget -> String
entryPath = TarPath -> String
fromTarPath forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall tarPath linkTarget. GenEntry tarPath linkTarget -> tarPath
entryTarPath
data GenEntryContent linkTarget
= NormalFile LBS.ByteString {-# UNPACK #-} !FileSize
| Directory
| SymbolicLink !linkTarget
| HardLink !linkTarget
| CharacterDevice {-# UNPACK #-} !DevMajor
{-# UNPACK #-} !DevMinor
| BlockDevice {-# UNPACK #-} !DevMajor
{-# UNPACK #-} !DevMinor
| NamedPipe
| OtherEntryType {-# UNPACK #-} !TypeCode LBS.ByteString
{-# UNPACK #-} !FileSize
deriving (GenEntryContent linkTarget -> GenEntryContent linkTarget -> Bool
forall linkTarget.
Eq linkTarget =>
GenEntryContent linkTarget -> GenEntryContent linkTarget -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GenEntryContent linkTarget -> GenEntryContent linkTarget -> Bool
$c/= :: forall linkTarget.
Eq linkTarget =>
GenEntryContent linkTarget -> GenEntryContent linkTarget -> Bool
== :: GenEntryContent linkTarget -> GenEntryContent linkTarget -> Bool
$c== :: forall linkTarget.
Eq linkTarget =>
GenEntryContent linkTarget -> GenEntryContent linkTarget -> Bool
Eq, GenEntryContent linkTarget
-> GenEntryContent linkTarget -> Ordering
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 {linkTarget}.
Ord linkTarget =>
Eq (GenEntryContent linkTarget)
forall linkTarget.
Ord linkTarget =>
GenEntryContent linkTarget -> GenEntryContent linkTarget -> Bool
forall linkTarget.
Ord linkTarget =>
GenEntryContent linkTarget
-> GenEntryContent linkTarget -> Ordering
forall linkTarget.
Ord linkTarget =>
GenEntryContent linkTarget
-> GenEntryContent linkTarget -> GenEntryContent linkTarget
min :: GenEntryContent linkTarget
-> GenEntryContent linkTarget -> GenEntryContent linkTarget
$cmin :: forall linkTarget.
Ord linkTarget =>
GenEntryContent linkTarget
-> GenEntryContent linkTarget -> GenEntryContent linkTarget
max :: GenEntryContent linkTarget
-> GenEntryContent linkTarget -> GenEntryContent linkTarget
$cmax :: forall linkTarget.
Ord linkTarget =>
GenEntryContent linkTarget
-> GenEntryContent linkTarget -> GenEntryContent linkTarget
>= :: GenEntryContent linkTarget -> GenEntryContent linkTarget -> Bool
$c>= :: forall linkTarget.
Ord linkTarget =>
GenEntryContent linkTarget -> GenEntryContent linkTarget -> Bool
> :: GenEntryContent linkTarget -> GenEntryContent linkTarget -> Bool
$c> :: forall linkTarget.
Ord linkTarget =>
GenEntryContent linkTarget -> GenEntryContent linkTarget -> Bool
<= :: GenEntryContent linkTarget -> GenEntryContent linkTarget -> Bool
$c<= :: forall linkTarget.
Ord linkTarget =>
GenEntryContent linkTarget -> GenEntryContent linkTarget -> Bool
< :: GenEntryContent linkTarget -> GenEntryContent linkTarget -> Bool
$c< :: forall linkTarget.
Ord linkTarget =>
GenEntryContent linkTarget -> GenEntryContent linkTarget -> Bool
compare :: GenEntryContent linkTarget
-> GenEntryContent linkTarget -> Ordering
$ccompare :: forall linkTarget.
Ord linkTarget =>
GenEntryContent linkTarget
-> GenEntryContent linkTarget -> Ordering
Ord, Int -> GenEntryContent linkTarget -> ShowS
forall linkTarget.
Show linkTarget =>
Int -> GenEntryContent linkTarget -> ShowS
forall linkTarget.
Show linkTarget =>
[GenEntryContent linkTarget] -> ShowS
forall linkTarget.
Show linkTarget =>
GenEntryContent linkTarget -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GenEntryContent linkTarget] -> ShowS
$cshowList :: forall linkTarget.
Show linkTarget =>
[GenEntryContent linkTarget] -> ShowS
show :: GenEntryContent linkTarget -> String
$cshow :: forall linkTarget.
Show linkTarget =>
GenEntryContent linkTarget -> String
showsPrec :: Int -> GenEntryContent linkTarget -> ShowS
$cshowsPrec :: forall linkTarget.
Show linkTarget =>
Int -> GenEntryContent linkTarget -> ShowS
Show)
type EntryContent = GenEntryContent LinkTarget
data Ownership = Ownership {
Ownership -> String
ownerName :: String,
Ownership -> String
groupName :: String,
Ownership -> Int
ownerId :: {-# UNPACK #-} !Int,
Ownership -> Int
groupId :: {-# UNPACK #-} !Int
}
deriving (Ownership -> Ownership -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Ownership -> Ownership -> Bool
$c/= :: Ownership -> Ownership -> Bool
== :: Ownership -> Ownership -> Bool
$c== :: Ownership -> Ownership -> Bool
Eq, Eq Ownership
Ownership -> Ownership -> Bool
Ownership -> Ownership -> Ordering
Ownership -> Ownership -> Ownership
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
min :: Ownership -> Ownership -> Ownership
$cmin :: Ownership -> Ownership -> Ownership
max :: Ownership -> Ownership -> Ownership
$cmax :: Ownership -> Ownership -> Ownership
>= :: Ownership -> Ownership -> Bool
$c>= :: Ownership -> Ownership -> Bool
> :: Ownership -> Ownership -> Bool
$c> :: Ownership -> Ownership -> Bool
<= :: Ownership -> Ownership -> Bool
$c<= :: Ownership -> Ownership -> Bool
< :: Ownership -> Ownership -> Bool
$c< :: Ownership -> Ownership -> Bool
compare :: Ownership -> Ownership -> Ordering
$ccompare :: Ownership -> Ownership -> Ordering
Ord, Int -> Ownership -> ShowS
[Ownership] -> ShowS
Ownership -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Ownership] -> ShowS
$cshowList :: [Ownership] -> ShowS
show :: Ownership -> String
$cshow :: Ownership -> String
showsPrec :: Int -> Ownership -> ShowS
$cshowsPrec :: Int -> Ownership -> ShowS
Show)
data Format =
V7Format
| UstarFormat
| GnuFormat
deriving (Format -> Format -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Format -> Format -> Bool
$c/= :: Format -> Format -> Bool
== :: Format -> Format -> Bool
$c== :: Format -> Format -> Bool
Eq, Eq Format
Format -> Format -> Bool
Format -> Format -> Ordering
Format -> Format -> Format
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
min :: Format -> Format -> Format
$cmin :: Format -> Format -> Format
max :: Format -> Format -> Format
$cmax :: Format -> Format -> Format
>= :: Format -> Format -> Bool
$c>= :: Format -> Format -> Bool
> :: Format -> Format -> Bool
$c> :: Format -> Format -> Bool
<= :: Format -> Format -> Bool
$c<= :: Format -> Format -> Bool
< :: Format -> Format -> Bool
$c< :: Format -> Format -> Bool
compare :: Format -> Format -> Ordering
$ccompare :: Format -> Format -> Ordering
Ord, Int -> Format -> ShowS
[Format] -> ShowS
Format -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Format] -> ShowS
$cshowList :: [Format] -> ShowS
show :: Format -> String
$cshow :: Format -> String
showsPrec :: Int -> Format -> ShowS
$cshowsPrec :: Int -> Format -> ShowS
Show)
instance (NFData tarPath, NFData linkTarget) => NFData (GenEntry tarPath linkTarget) where
rnf :: GenEntry tarPath linkTarget -> ()
rnf (Entry tarPath
p GenEntryContent linkTarget
c Permissions
_ Ownership
_ EpochTime
_ Format
_) = forall a. NFData a => a -> ()
rnf tarPath
p seq :: forall a b. a -> b -> b
`seq` forall a. NFData a => a -> ()
rnf GenEntryContent linkTarget
c
instance NFData linkTarget => NFData (GenEntryContent linkTarget) where
rnf :: GenEntryContent linkTarget -> ()
rnf GenEntryContent linkTarget
x = case GenEntryContent linkTarget
x of
NormalFile ByteString
c EpochTime
_ -> forall a. NFData a => a -> ()
rnf ByteString
c
SymbolicLink linkTarget
lnk -> forall a. NFData a => a -> ()
rnf linkTarget
lnk
HardLink linkTarget
lnk -> forall a. NFData a => a -> ()
rnf linkTarget
lnk
OtherEntryType Char
_ ByteString
c EpochTime
_ -> forall a. NFData a => a -> ()
rnf ByteString
c
GenEntryContent linkTarget
_ -> seq :: forall a b. a -> b -> b
seq GenEntryContent linkTarget
x ()
instance NFData Ownership where
rnf :: Ownership -> ()
rnf (Ownership String
o String
g Int
_ Int
_) = forall a. NFData a => a -> ()
rnf String
o seq :: forall a b. a -> b -> b
`seq` forall a. NFData a => a -> ()
rnf String
g
ordinaryFilePermissions :: Permissions
ordinaryFilePermissions :: Permissions
ordinaryFilePermissions = Permissions
0o0644
symbolicLinkPermission :: Permissions
symbolicLinkPermission :: Permissions
symbolicLinkPermission = Permissions
0o0777
executableFilePermissions :: Permissions
executableFilePermissions :: Permissions
executableFilePermissions = Permissions
0o0755
directoryPermissions :: Permissions
directoryPermissions :: Permissions
directoryPermissions = Permissions
0o0755
simpleEntry :: tarPath -> GenEntryContent linkTarget -> GenEntry tarPath linkTarget
simpleEntry :: forall tarPath linkTarget.
tarPath
-> GenEntryContent linkTarget -> GenEntry tarPath linkTarget
simpleEntry tarPath
tarpath GenEntryContent linkTarget
content = Entry {
entryTarPath :: tarPath
entryTarPath = tarPath
tarpath,
entryContent :: GenEntryContent linkTarget
entryContent = GenEntryContent linkTarget
content,
entryPermissions :: Permissions
entryPermissions = case GenEntryContent linkTarget
content of
GenEntryContent linkTarget
Directory -> Permissions
directoryPermissions
SymbolicLink linkTarget
_ -> Permissions
symbolicLinkPermission
GenEntryContent linkTarget
_ -> Permissions
ordinaryFilePermissions,
entryOwnership :: Ownership
entryOwnership = String -> String -> Int -> Int -> Ownership
Ownership String
"" String
"" Int
0 Int
0,
entryTime :: EpochTime
entryTime = EpochTime
0,
entryFormat :: Format
entryFormat = Format
UstarFormat
}
fileEntry :: tarPath -> LBS.ByteString -> GenEntry tarPath linkTarget
fileEntry :: forall tarPath linkTarget.
tarPath -> ByteString -> GenEntry tarPath linkTarget
fileEntry tarPath
name ByteString
fileContent =
forall tarPath linkTarget.
tarPath
-> GenEntryContent linkTarget -> GenEntry tarPath linkTarget
simpleEntry tarPath
name (forall linkTarget.
ByteString -> EpochTime -> GenEntryContent linkTarget
NormalFile ByteString
fileContent (ByteString -> EpochTime
LBS.length ByteString
fileContent))
symlinkEntry :: tarPath -> linkTarget -> GenEntry tarPath linkTarget
symlinkEntry :: forall tarPath linkTarget.
tarPath -> linkTarget -> GenEntry tarPath linkTarget
symlinkEntry tarPath
name linkTarget
targetLink =
forall tarPath linkTarget.
tarPath
-> GenEntryContent linkTarget -> GenEntry tarPath linkTarget
simpleEntry tarPath
name (forall linkTarget. linkTarget -> GenEntryContent linkTarget
SymbolicLink linkTarget
targetLink)
longLinkEntry :: FilePath -> GenEntry TarPath linkTarget
longLinkEntry :: forall linkTarget. String -> GenEntry TarPath linkTarget
longLinkEntry String
tarpath = Entry {
entryTarPath :: TarPath
entryTarPath = ByteString -> ByteString -> TarPath
TarPath (String -> ByteString
BS.Char8.pack String
"././@LongLink") ByteString
BS.empty,
entryContent :: GenEntryContent linkTarget
entryContent = forall linkTarget.
Char -> ByteString -> EpochTime -> GenEntryContent linkTarget
OtherEntryType Char
'L' (ByteString -> ByteString
LBS.fromStrict forall a b. (a -> b) -> a -> b
$ HasCallStack => String -> ByteString
packAscii String
tarpath) (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Int
length String
tarpath),
entryPermissions :: Permissions
entryPermissions = Permissions
ordinaryFilePermissions,
entryOwnership :: Ownership
entryOwnership = String -> String -> Int -> Int -> Ownership
Ownership String
"" String
"" Int
0 Int
0,
entryTime :: EpochTime
entryTime = EpochTime
0,
entryFormat :: Format
entryFormat = Format
GnuFormat
}
longSymLinkEntry :: FilePath -> GenEntry TarPath linkTarget
longSymLinkEntry :: forall linkTarget. String -> GenEntry TarPath linkTarget
longSymLinkEntry String
linkTarget = Entry {
entryTarPath :: TarPath
entryTarPath = ByteString -> ByteString -> TarPath
TarPath (String -> ByteString
BS.Char8.pack String
"././@LongLink") ByteString
BS.empty,
entryContent :: GenEntryContent linkTarget
entryContent = forall linkTarget.
Char -> ByteString -> EpochTime -> GenEntryContent linkTarget
OtherEntryType Char
'K' (ByteString -> ByteString
LBS.fromStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => String -> ByteString
packAscii forall a b. (a -> b) -> a -> b
$ String
linkTarget) (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Int
length String
linkTarget),
entryPermissions :: Permissions
entryPermissions = Permissions
ordinaryFilePermissions,
entryOwnership :: Ownership
entryOwnership = String -> String -> Int -> Int -> Ownership
Ownership String
"" String
"" Int
0 Int
0,
entryTime :: EpochTime
entryTime = EpochTime
0,
entryFormat :: Format
entryFormat = Format
GnuFormat
}
directoryEntry :: tarPath -> GenEntry tarPath linkTarget
directoryEntry :: forall tarPath linkTarget. tarPath -> GenEntry tarPath linkTarget
directoryEntry tarPath
name = forall tarPath linkTarget.
tarPath
-> GenEntryContent linkTarget -> GenEntry tarPath linkTarget
simpleEntry tarPath
name forall linkTarget. GenEntryContent linkTarget
Directory
data TarPath = TarPath {-# UNPACK #-} !BS.ByteString
{-# UNPACK #-} !BS.ByteString
deriving (TarPath -> TarPath -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TarPath -> TarPath -> Bool
$c/= :: TarPath -> TarPath -> Bool
== :: TarPath -> TarPath -> Bool
$c== :: TarPath -> TarPath -> Bool
Eq, Eq TarPath
TarPath -> TarPath -> Bool
TarPath -> TarPath -> Ordering
TarPath -> TarPath -> TarPath
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
min :: TarPath -> TarPath -> TarPath
$cmin :: TarPath -> TarPath -> TarPath
max :: TarPath -> TarPath -> TarPath
$cmax :: TarPath -> TarPath -> TarPath
>= :: TarPath -> TarPath -> Bool
$c>= :: TarPath -> TarPath -> Bool
> :: TarPath -> TarPath -> Bool
$c> :: TarPath -> TarPath -> Bool
<= :: TarPath -> TarPath -> Bool
$c<= :: TarPath -> TarPath -> Bool
< :: TarPath -> TarPath -> Bool
$c< :: TarPath -> TarPath -> Bool
compare :: TarPath -> TarPath -> Ordering
$ccompare :: TarPath -> TarPath -> Ordering
Ord)
instance NFData TarPath where
rnf :: TarPath -> ()
rnf (TarPath ByteString
_ ByteString
_) = ()
instance Show TarPath where
show :: TarPath -> String
show = forall a. Show a => a -> String
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. TarPath -> String
fromTarPath
fromTarPath :: TarPath -> FilePath
fromTarPath :: TarPath -> String
fromTarPath = ByteString -> String
BS.Char8.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> TarPath -> ByteString
fromTarPathInternal Char
FilePath.Native.pathSeparator
fromTarPathToPosixPath :: TarPath -> FilePath
fromTarPathToPosixPath :: TarPath -> String
fromTarPathToPosixPath = ByteString -> String
BS.Char8.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> TarPath -> ByteString
fromTarPathInternal Char
FilePath.Posix.pathSeparator
fromTarPathToWindowsPath :: TarPath -> FilePath
fromTarPathToWindowsPath :: TarPath -> String
fromTarPathToWindowsPath = ByteString -> String
BS.Char8.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> TarPath -> ByteString
fromTarPathInternal Char
FilePath.Windows.pathSeparator
fromTarPathInternal :: Char -> TarPath -> BS.ByteString
fromTarPathInternal :: Char -> TarPath -> ByteString
fromTarPathInternal Char
sep = TarPath -> ByteString
go
where
posixSep :: Char
posixSep = Char
FilePath.Posix.pathSeparator
adjustSeps :: ByteString -> ByteString
adjustSeps = if Char
sep forall a. Eq a => a -> a -> Bool
== Char
posixSep then forall a. a -> a
id else
(Char -> Char) -> ByteString -> ByteString
BS.Char8.map forall a b. (a -> b) -> a -> b
$ \Char
c -> if Char
c forall a. Eq a => a -> a -> Bool
== Char
posixSep then Char
sep else Char
c
go :: TarPath -> ByteString
go (TarPath ByteString
name ByteString
prefix)
| ByteString -> Bool
BS.null ByteString
prefix = ByteString -> ByteString
adjustSeps ByteString
name
| ByteString -> Bool
BS.null ByteString
name = ByteString -> ByteString
adjustSeps ByteString
prefix
| Bool
otherwise = ByteString -> ByteString
adjustSeps ByteString
prefix forall a. Semigroup a => a -> a -> a
<> Char -> ByteString -> ByteString
BS.Char8.cons Char
sep (ByteString -> ByteString
adjustSeps ByteString
name)
{-# INLINE fromTarPathInternal #-}
toTarPath :: Bool
-> FilePath
-> Either String TarPath
toTarPath :: Bool -> String -> Either String TarPath
toTarPath Bool
isDir String
path = case String -> ToTarPathResult
toTarPath' String
path' of
ToTarPathResult
FileNameEmpty -> forall a b. a -> Either a b
Left String
"File name empty"
FileNameOK TarPath
tarPath -> forall a b. b -> Either a b
Right TarPath
tarPath
FileNameTooLong{} -> forall a b. a -> Either a b
Left String
"File name too long"
where
path' :: String
path' = if Bool
isDir Bool -> Bool -> Bool
&& Bool -> Bool
not (String -> Bool
FilePath.Native.hasTrailingPathSeparator String
path)
then String
path forall a. Semigroup a => a -> a -> a
<> [Char
FilePath.Native.pathSeparator]
else String
path
toTarPath'
:: FilePath
-> ToTarPathResult
toTarPath' :: String -> ToTarPathResult
toTarPath'
= String -> ToTarPathResult
splitLongPath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (if Char
nativeSep forall a. Eq a => a -> a -> Bool
== Char
posixSep then forall a. a -> a
id else ShowS
adjustSeps)
where
nativeSep :: Char
nativeSep = Char
FilePath.Native.pathSeparator
posixSep :: Char
posixSep = Char
FilePath.Posix.pathSeparator
adjustSeps :: ShowS
adjustSeps = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a -> b) -> a -> b
$ \Char
c -> if Char
c forall a. Eq a => a -> a -> Bool
== Char
nativeSep then Char
posixSep else Char
c
data ToTarPathResult
= FileNameEmpty
| FileNameOK TarPath
| FileNameTooLong TarPath
splitLongPath :: FilePath -> ToTarPathResult
splitLongPath :: String -> ToTarPathResult
splitLongPath String
path = case forall a. [a] -> [a]
reverse (String -> [String]
FilePath.Posix.splitPath String
path) of
[] -> ToTarPathResult
FileNameEmpty
String
c : [String]
cs -> case Int -> NonEmpty String -> Maybe (String, [String])
packName Int
nameMax (String
c forall a. a -> [a] -> NonEmpty a
:| [String]
cs) of
Maybe (String, [String])
Nothing -> TarPath -> ToTarPathResult
FileNameTooLong forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString -> TarPath
TarPath (HasCallStack => String -> ByteString
packAscii forall a b. (a -> b) -> a -> b
$ forall a. Int -> [a] -> [a]
take Int
100 String
path) ByteString
BS.empty
Just (String
name, []) -> TarPath -> ToTarPathResult
FileNameOK forall a b. (a -> b) -> a -> b
$! ByteString -> ByteString -> TarPath
TarPath (HasCallStack => String -> ByteString
packAscii String
name) ByteString
BS.empty
Just (String
name, String
first:[String]
rest) -> case Int -> NonEmpty String -> Maybe (String, [String])
packName Int
prefixMax NonEmpty String
remainder of
Maybe (String, [String])
Nothing -> TarPath -> ToTarPathResult
FileNameTooLong forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString -> TarPath
TarPath (HasCallStack => String -> ByteString
packAscii forall a b. (a -> b) -> a -> b
$ forall a. Int -> [a] -> [a]
take Int
100 String
path) ByteString
BS.empty
Just (String
_ , String
_:[String]
_) -> TarPath -> ToTarPathResult
FileNameTooLong forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString -> TarPath
TarPath (HasCallStack => String -> ByteString
packAscii forall a b. (a -> b) -> a -> b
$ forall a. Int -> [a] -> [a]
take Int
100 String
path) ByteString
BS.empty
Just (String
prefix, []) -> TarPath -> ToTarPathResult
FileNameOK forall a b. (a -> b) -> a -> b
$! ByteString -> ByteString -> TarPath
TarPath (HasCallStack => String -> ByteString
packAscii String
name) (HasCallStack => String -> ByteString
packAscii String
prefix)
where
remainder :: NonEmpty String
remainder = forall a. [a] -> [a]
init String
first forall a. a -> [a] -> NonEmpty a
:| [String]
rest
where
nameMax, prefixMax :: Int
nameMax :: Int
nameMax = Int
100
prefixMax :: Int
prefixMax = Int
155
packName :: Int -> NonEmpty FilePath -> Maybe (FilePath, [FilePath])
packName :: Int -> NonEmpty String -> Maybe (String, [String])
packName Int
maxLen (String
c :| [String]
cs)
| Int
n forall a. Ord a => a -> a -> Bool
> Int
maxLen = forall a. Maybe a
Nothing
| Bool
otherwise = forall a. a -> Maybe a
Just (Int -> Int -> [String] -> [String] -> (String, [String])
packName' Int
maxLen Int
n [String
c] [String]
cs)
where n :: Int
n = forall (t :: * -> *) a. Foldable t => t a -> Int
length String
c
packName' :: Int -> Int -> [FilePath] -> [FilePath] -> (FilePath, [FilePath])
packName' :: Int -> Int -> [String] -> [String] -> (String, [String])
packName' Int
maxLen Int
n [String]
ok (String
c:[String]
cs)
| Int
n' forall a. Ord a => a -> a -> Bool
<= Int
maxLen = Int -> Int -> [String] -> [String] -> (String, [String])
packName' Int
maxLen Int
n' (String
cforall a. a -> [a] -> [a]
:[String]
ok) [String]
cs
where n' :: Int
n' = Int
n forall a. Num a => a -> a -> a
+ forall (t :: * -> *) a. Foldable t => t a -> Int
length String
c
packName' Int
_ Int
_ [String]
ok [String]
cs = ([String] -> String
FilePath.Posix.joinPath [String]
ok, [String]
cs)
newtype LinkTarget = LinkTarget BS.ByteString
deriving (LinkTarget -> LinkTarget -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LinkTarget -> LinkTarget -> Bool
$c/= :: LinkTarget -> LinkTarget -> Bool
== :: LinkTarget -> LinkTarget -> Bool
$c== :: LinkTarget -> LinkTarget -> Bool
Eq, Eq LinkTarget
LinkTarget -> LinkTarget -> Bool
LinkTarget -> LinkTarget -> Ordering
LinkTarget -> LinkTarget -> LinkTarget
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
min :: LinkTarget -> LinkTarget -> LinkTarget
$cmin :: LinkTarget -> LinkTarget -> LinkTarget
max :: LinkTarget -> LinkTarget -> LinkTarget
$cmax :: LinkTarget -> LinkTarget -> LinkTarget
>= :: LinkTarget -> LinkTarget -> Bool
$c>= :: LinkTarget -> LinkTarget -> Bool
> :: LinkTarget -> LinkTarget -> Bool
$c> :: LinkTarget -> LinkTarget -> Bool
<= :: LinkTarget -> LinkTarget -> Bool
$c<= :: LinkTarget -> LinkTarget -> Bool
< :: LinkTarget -> LinkTarget -> Bool
$c< :: LinkTarget -> LinkTarget -> Bool
compare :: LinkTarget -> LinkTarget -> Ordering
$ccompare :: LinkTarget -> LinkTarget -> Ordering
Ord, Int -> LinkTarget -> ShowS
[LinkTarget] -> ShowS
LinkTarget -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LinkTarget] -> ShowS
$cshowList :: [LinkTarget] -> ShowS
show :: LinkTarget -> String
$cshow :: LinkTarget -> String
showsPrec :: Int -> LinkTarget -> ShowS
$cshowsPrec :: Int -> LinkTarget -> ShowS
Show)
instance NFData LinkTarget where
rnf :: LinkTarget -> ()
rnf (LinkTarget ByteString
bs) = forall a. NFData a => a -> ()
rnf ByteString
bs
toLinkTarget :: FilePath -> Maybe LinkTarget
toLinkTarget :: String -> Maybe LinkTarget
toLinkTarget String
path
| forall (t :: * -> *) a. Foldable t => t a -> Int
length String
path forall a. Ord a => a -> a -> Bool
<= Int
100 = do
String
target <- String -> Maybe String
toLinkTarget' String
path
forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$! ByteString -> LinkTarget
LinkTarget (HasCallStack => String -> ByteString
packAscii String
target)
| Bool
otherwise = forall a. Maybe a
Nothing
data LinkTargetException = IsAbsolute FilePath
| TooLong FilePath
deriving (Int -> LinkTargetException -> ShowS
[LinkTargetException] -> ShowS
LinkTargetException -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LinkTargetException] -> ShowS
$cshowList :: [LinkTargetException] -> ShowS
show :: LinkTargetException -> String
$cshow :: LinkTargetException -> String
showsPrec :: Int -> LinkTargetException -> ShowS
$cshowsPrec :: Int -> LinkTargetException -> ShowS
Show,Typeable)
instance Exception LinkTargetException where
displayException :: LinkTargetException -> String
displayException (IsAbsolute String
fp) = String
"Link target \"" forall a. Semigroup a => a -> a -> a
<> String
fp forall a. Semigroup a => a -> a -> a
<> String
"\" is unexpectedly absolute"
displayException (TooLong String
_) = String
"The link target is too long"
toLinkTarget' :: FilePath -> Maybe FilePath
toLinkTarget' :: String -> Maybe String
toLinkTarget' String
path
| String -> Bool
FilePath.Native.isAbsolute String
path = forall a. Maybe a
Nothing
| Bool
otherwise = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ ShowS
adjustDirectory forall a b. (a -> b) -> a -> b
$ [String] -> String
FilePath.Posix.joinPath forall a b. (a -> b) -> a -> b
$ String -> [String]
FilePath.Native.splitDirectories String
path
where
adjustDirectory :: ShowS
adjustDirectory | String -> Bool
FilePath.Native.hasTrailingPathSeparator String
path
= ShowS
FilePath.Posix.addTrailingPathSeparator
| Bool
otherwise = forall a. a -> a
id
fromLinkTarget :: LinkTarget -> FilePath
fromLinkTarget :: LinkTarget -> String
fromLinkTarget (LinkTarget ByteString
pathbs) = ShowS
fromFilePathToNative forall a b. (a -> b) -> a -> b
$ ByteString -> String
BS.Char8.unpack ByteString
pathbs
fromLinkTargetToPosixPath :: LinkTarget -> FilePath
fromLinkTargetToPosixPath :: LinkTarget -> String
fromLinkTargetToPosixPath (LinkTarget ByteString
pathbs) = ByteString -> String
BS.Char8.unpack ByteString
pathbs
fromLinkTargetToWindowsPath :: LinkTarget -> FilePath
fromLinkTargetToWindowsPath :: LinkTarget -> String
fromLinkTargetToWindowsPath (LinkTarget ByteString
pathbs) =
ShowS
fromFilePathToWindowsPath forall a b. (a -> b) -> a -> b
$ ByteString -> String
BS.Char8.unpack ByteString
pathbs
fromFilePathToNative :: FilePath -> FilePath
fromFilePathToNative :: ShowS
fromFilePathToNative =
Char -> Char -> ShowS
fromFilePathInternal Char
FilePath.Posix.pathSeparator Char
FilePath.Native.pathSeparator
fromFilePathToWindowsPath :: FilePath -> FilePath
fromFilePathToWindowsPath :: ShowS
fromFilePathToWindowsPath =
Char -> Char -> ShowS
fromFilePathInternal Char
FilePath.Posix.pathSeparator Char
FilePath.Windows.pathSeparator
fromFilePathInternal :: Char -> Char -> FilePath -> FilePath
fromFilePathInternal :: Char -> Char -> ShowS
fromFilePathInternal Char
fromSep Char
toSep = ShowS
adjustSeps
where
adjustSeps :: ShowS
adjustSeps = if Char
fromSep forall a. Eq a => a -> a -> Bool
== Char
toSep then forall a. a -> a
id else
forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a -> b) -> a -> b
$ \Char
c -> if Char
c forall a. Eq a => a -> a -> Bool
== Char
fromSep then Char
toSep else Char
c
{-# INLINE fromFilePathInternal #-}
data GenEntries tarPath linkTarget e
= Next (GenEntry tarPath linkTarget) (GenEntries tarPath linkTarget e)
| Done
| Fail e
deriving
( GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall tarPath linkTarget e.
(Eq tarPath, Eq linkTarget, Eq e) =>
GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e -> Bool
/= :: GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e -> Bool
$c/= :: forall tarPath linkTarget e.
(Eq tarPath, Eq linkTarget, Eq e) =>
GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e -> Bool
== :: GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e -> Bool
$c== :: forall tarPath linkTarget e.
(Eq tarPath, Eq linkTarget, Eq e) =>
GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e -> Bool
Eq
, Int -> GenEntries tarPath linkTarget e -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall tarPath linkTarget e.
(Show tarPath, Show linkTarget, Show e) =>
Int -> GenEntries tarPath linkTarget e -> ShowS
forall tarPath linkTarget e.
(Show tarPath, Show linkTarget, Show e) =>
[GenEntries tarPath linkTarget e] -> ShowS
forall tarPath linkTarget e.
(Show tarPath, Show linkTarget, Show e) =>
GenEntries tarPath linkTarget e -> String
showList :: [GenEntries tarPath linkTarget e] -> ShowS
$cshowList :: forall tarPath linkTarget e.
(Show tarPath, Show linkTarget, Show e) =>
[GenEntries tarPath linkTarget e] -> ShowS
show :: GenEntries tarPath linkTarget e -> String
$cshow :: forall tarPath linkTarget e.
(Show tarPath, Show linkTarget, Show e) =>
GenEntries tarPath linkTarget e -> String
showsPrec :: Int -> GenEntries tarPath linkTarget e -> ShowS
$cshowsPrec :: forall tarPath linkTarget e.
(Show tarPath, Show linkTarget, Show e) =>
Int -> GenEntries tarPath linkTarget e -> ShowS
Show
, forall a b.
a
-> GenEntries tarPath linkTarget b
-> GenEntries tarPath linkTarget a
forall a b.
(a -> b)
-> GenEntries tarPath linkTarget a
-> GenEntries tarPath linkTarget b
forall tarPath linkTarget a b.
a
-> GenEntries tarPath linkTarget b
-> GenEntries tarPath linkTarget a
forall tarPath linkTarget a b.
(a -> b)
-> GenEntries tarPath linkTarget a
-> GenEntries tarPath linkTarget b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b.
a
-> GenEntries tarPath linkTarget b
-> GenEntries tarPath linkTarget a
$c<$ :: forall tarPath linkTarget a b.
a
-> GenEntries tarPath linkTarget b
-> GenEntries tarPath linkTarget a
fmap :: forall a b.
(a -> b)
-> GenEntries tarPath linkTarget a
-> GenEntries tarPath linkTarget b
$cfmap :: forall tarPath linkTarget a b.
(a -> b)
-> GenEntries tarPath linkTarget a
-> GenEntries tarPath linkTarget b
Functor
, forall a. GenEntries tarPath linkTarget a -> Bool
forall m a.
Monoid m =>
(a -> m) -> GenEntries tarPath linkTarget a -> m
forall a b.
(a -> b -> b) -> b -> GenEntries tarPath linkTarget a -> b
forall tarPath linkTarget a.
Eq a =>
a -> GenEntries tarPath linkTarget a -> Bool
forall tarPath linkTarget a.
Num a =>
GenEntries tarPath linkTarget a -> a
forall tarPath linkTarget a.
Ord a =>
GenEntries tarPath linkTarget a -> a
forall tarPath linkTarget m.
Monoid m =>
GenEntries tarPath linkTarget m -> m
forall tarPath linkTarget a.
GenEntries tarPath linkTarget a -> Bool
forall tarPath linkTarget a. GenEntries tarPath linkTarget a -> Int
forall tarPath linkTarget a. GenEntries tarPath linkTarget a -> [a]
forall tarPath linkTarget a.
(a -> a -> a) -> GenEntries tarPath linkTarget a -> a
forall tarPath linkTarget m a.
Monoid m =>
(a -> m) -> GenEntries tarPath linkTarget a -> m
forall tarPath linkTarget b a.
(b -> a -> b) -> b -> GenEntries tarPath linkTarget a -> b
forall tarPath linkTarget a b.
(a -> b -> b) -> b -> GenEntries tarPath linkTarget 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 :: forall a. Num a => GenEntries tarPath linkTarget a -> a
$cproduct :: forall tarPath linkTarget a.
Num a =>
GenEntries tarPath linkTarget a -> a
sum :: forall a. Num a => GenEntries tarPath linkTarget a -> a
$csum :: forall tarPath linkTarget a.
Num a =>
GenEntries tarPath linkTarget a -> a
minimum :: forall a. Ord a => GenEntries tarPath linkTarget a -> a
$cminimum :: forall tarPath linkTarget a.
Ord a =>
GenEntries tarPath linkTarget a -> a
maximum :: forall a. Ord a => GenEntries tarPath linkTarget a -> a
$cmaximum :: forall tarPath linkTarget a.
Ord a =>
GenEntries tarPath linkTarget a -> a
elem :: forall a. Eq a => a -> GenEntries tarPath linkTarget a -> Bool
$celem :: forall tarPath linkTarget a.
Eq a =>
a -> GenEntries tarPath linkTarget a -> Bool
length :: forall a. GenEntries tarPath linkTarget a -> Int
$clength :: forall tarPath linkTarget a. GenEntries tarPath linkTarget a -> Int
null :: forall a. GenEntries tarPath linkTarget a -> Bool
$cnull :: forall tarPath linkTarget a.
GenEntries tarPath linkTarget a -> Bool
toList :: forall a. GenEntries tarPath linkTarget a -> [a]
$ctoList :: forall tarPath linkTarget a. GenEntries tarPath linkTarget a -> [a]
foldl1 :: forall a. (a -> a -> a) -> GenEntries tarPath linkTarget a -> a
$cfoldl1 :: forall tarPath linkTarget a.
(a -> a -> a) -> GenEntries tarPath linkTarget a -> a
foldr1 :: forall a. (a -> a -> a) -> GenEntries tarPath linkTarget a -> a
$cfoldr1 :: forall tarPath linkTarget a.
(a -> a -> a) -> GenEntries tarPath linkTarget a -> a
foldl' :: forall b a.
(b -> a -> b) -> b -> GenEntries tarPath linkTarget a -> b
$cfoldl' :: forall tarPath linkTarget b a.
(b -> a -> b) -> b -> GenEntries tarPath linkTarget a -> b
foldl :: forall b a.
(b -> a -> b) -> b -> GenEntries tarPath linkTarget a -> b
$cfoldl :: forall tarPath linkTarget b a.
(b -> a -> b) -> b -> GenEntries tarPath linkTarget a -> b
foldr' :: forall a b.
(a -> b -> b) -> b -> GenEntries tarPath linkTarget a -> b
$cfoldr' :: forall tarPath linkTarget a b.
(a -> b -> b) -> b -> GenEntries tarPath linkTarget a -> b
foldr :: forall a b.
(a -> b -> b) -> b -> GenEntries tarPath linkTarget a -> b
$cfoldr :: forall tarPath linkTarget a b.
(a -> b -> b) -> b -> GenEntries tarPath linkTarget a -> b
foldMap' :: forall m a.
Monoid m =>
(a -> m) -> GenEntries tarPath linkTarget a -> m
$cfoldMap' :: forall tarPath linkTarget m a.
Monoid m =>
(a -> m) -> GenEntries tarPath linkTarget a -> m
foldMap :: forall m a.
Monoid m =>
(a -> m) -> GenEntries tarPath linkTarget a -> m
$cfoldMap :: forall tarPath linkTarget m a.
Monoid m =>
(a -> m) -> GenEntries tarPath linkTarget a -> m
fold :: forall m. Monoid m => GenEntries tarPath linkTarget m -> m
$cfold :: forall tarPath linkTarget m.
Monoid m =>
GenEntries tarPath linkTarget m -> m
Foldable
, forall tarPath linkTarget. Functor (GenEntries tarPath linkTarget)
forall tarPath linkTarget. Foldable (GenEntries tarPath linkTarget)
forall tarPath linkTarget (m :: * -> *) a.
Monad m =>
GenEntries tarPath linkTarget (m a)
-> m (GenEntries tarPath linkTarget a)
forall tarPath linkTarget (f :: * -> *) a.
Applicative f =>
GenEntries tarPath linkTarget (f a)
-> f (GenEntries tarPath linkTarget a)
forall tarPath linkTarget (m :: * -> *) a b.
Monad m =>
(a -> m b)
-> GenEntries tarPath linkTarget a
-> m (GenEntries tarPath linkTarget b)
forall tarPath linkTarget (f :: * -> *) a b.
Applicative f =>
(a -> f b)
-> GenEntries tarPath linkTarget a
-> f (GenEntries tarPath linkTarget 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 (f :: * -> *) a b.
Applicative f =>
(a -> f b)
-> GenEntries tarPath linkTarget a
-> f (GenEntries tarPath linkTarget b)
sequence :: forall (m :: * -> *) a.
Monad m =>
GenEntries tarPath linkTarget (m a)
-> m (GenEntries tarPath linkTarget a)
$csequence :: forall tarPath linkTarget (m :: * -> *) a.
Monad m =>
GenEntries tarPath linkTarget (m a)
-> m (GenEntries tarPath linkTarget a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b)
-> GenEntries tarPath linkTarget a
-> m (GenEntries tarPath linkTarget b)
$cmapM :: forall tarPath linkTarget (m :: * -> *) a b.
Monad m =>
(a -> m b)
-> GenEntries tarPath linkTarget a
-> m (GenEntries tarPath linkTarget b)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
GenEntries tarPath linkTarget (f a)
-> f (GenEntries tarPath linkTarget a)
$csequenceA :: forall tarPath linkTarget (f :: * -> *) a.
Applicative f =>
GenEntries tarPath linkTarget (f a)
-> f (GenEntries tarPath linkTarget a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b)
-> GenEntries tarPath linkTarget a
-> f (GenEntries tarPath linkTarget b)
$ctraverse :: forall tarPath linkTarget (f :: * -> *) a b.
Applicative f =>
(a -> f b)
-> GenEntries tarPath linkTarget a
-> f (GenEntries tarPath linkTarget b)
Traversable
)
infixr 5 `Next`
type Entries e = GenEntries TarPath LinkTarget e
unfoldEntries
:: (a -> Either e (Maybe (GenEntry tarPath linkTarget, a)))
-> a
-> GenEntries tarPath linkTarget e
unfoldEntries :: forall a e tarPath linkTarget.
(a -> Either e (Maybe (GenEntry tarPath linkTarget, a)))
-> a -> GenEntries tarPath linkTarget e
unfoldEntries a -> Either e (Maybe (GenEntry tarPath linkTarget, a))
f = a -> GenEntries tarPath linkTarget e
unfold
where
unfold :: a -> GenEntries tarPath linkTarget e
unfold a
x = case a -> Either e (Maybe (GenEntry tarPath linkTarget, a))
f a
x of
Left e
err -> forall tarPath linkTarget e. e -> GenEntries tarPath linkTarget e
Fail e
err
Right Maybe (GenEntry tarPath linkTarget, a)
Nothing -> forall tarPath linkTarget e. GenEntries tarPath linkTarget e
Done
Right (Just (GenEntry tarPath linkTarget
e, a
x')) -> forall tarPath linkTarget e.
GenEntry tarPath linkTarget
-> GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e
Next GenEntry tarPath linkTarget
e (a -> GenEntries tarPath linkTarget e
unfold a
x')
foldEntries
:: (GenEntry tarPath linkTarget -> a -> a)
-> a
-> (e -> a)
-> GenEntries tarPath linkTarget e -> a
foldEntries :: forall tarPath linkTarget a e.
(GenEntry tarPath linkTarget -> a -> a)
-> a -> (e -> a) -> GenEntries tarPath linkTarget e -> a
foldEntries GenEntry tarPath linkTarget -> a -> a
next a
done e -> a
fail' = GenEntries tarPath linkTarget e -> a
fold
where
fold :: GenEntries tarPath linkTarget e -> a
fold (Next GenEntry tarPath linkTarget
e GenEntries tarPath linkTarget e
es) = GenEntry tarPath linkTarget -> a -> a
next GenEntry tarPath linkTarget
e (GenEntries tarPath linkTarget e -> a
fold GenEntries tarPath linkTarget e
es)
fold GenEntries tarPath linkTarget e
Done = a
done
fold (Fail e
err) = e -> a
fail' e
err
foldlEntries
:: (a -> GenEntry tarPath linkTarget -> a)
-> a
-> GenEntries tarPath linkTarget e
-> Either (e, a) a
foldlEntries :: forall a tarPath linkTarget e.
(a -> GenEntry tarPath linkTarget -> a)
-> a -> GenEntries tarPath linkTarget e -> Either (e, a) a
foldlEntries a -> GenEntry tarPath linkTarget -> a
f = forall {a}. a -> GenEntries tarPath linkTarget a -> Either (a, a) a
go
where
go :: a -> GenEntries tarPath linkTarget a -> Either (a, a) a
go !a
acc (Next GenEntry tarPath linkTarget
e GenEntries tarPath linkTarget a
es) = a -> GenEntries tarPath linkTarget a -> Either (a, a) a
go (a -> GenEntry tarPath linkTarget -> a
f a
acc GenEntry tarPath linkTarget
e) GenEntries tarPath linkTarget a
es
go !a
acc GenEntries tarPath linkTarget a
Done = forall a b. b -> Either a b
Right a
acc
go !a
acc (Fail a
err) = forall a b. a -> Either a b
Left (a
err, a
acc)
mapEntries
:: (GenEntry tarPath linkTarget -> Either e' (GenEntry tarPath linkTarget))
-> GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget (Either e e')
mapEntries :: forall tarPath linkTarget e' e.
(GenEntry tarPath linkTarget
-> Either e' (GenEntry tarPath linkTarget))
-> GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget (Either e e')
mapEntries GenEntry tarPath linkTarget
-> Either e' (GenEntry tarPath linkTarget)
f =
forall tarPath linkTarget a e.
(GenEntry tarPath linkTarget -> a -> a)
-> a -> (e -> a) -> GenEntries tarPath linkTarget e -> a
foldEntries (\GenEntry tarPath linkTarget
entry GenEntries tarPath linkTarget (Either e e')
rest -> forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall tarPath linkTarget e. e -> GenEntries tarPath linkTarget e
Fail forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. b -> Either a b
Right) (forall tarPath linkTarget e.
GenEntry tarPath linkTarget
-> GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e
`Next` GenEntries tarPath linkTarget (Either e e')
rest) (GenEntry tarPath linkTarget
-> Either e' (GenEntry tarPath linkTarget)
f GenEntry tarPath linkTarget
entry)) forall tarPath linkTarget e. GenEntries tarPath linkTarget e
Done (forall tarPath linkTarget e. e -> GenEntries tarPath linkTarget e
Fail forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left)
mapEntriesNoFail
:: (GenEntry tarPath linkTarget -> GenEntry tarPath linkTarget)
-> GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e
mapEntriesNoFail :: forall tarPath linkTarget e.
(GenEntry tarPath linkTarget -> GenEntry tarPath linkTarget)
-> GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e
mapEntriesNoFail GenEntry tarPath linkTarget -> GenEntry tarPath linkTarget
f =
forall tarPath linkTarget a e.
(GenEntry tarPath linkTarget -> a -> a)
-> a -> (e -> a) -> GenEntries tarPath linkTarget e -> a
foldEntries (forall tarPath linkTarget e.
GenEntry tarPath linkTarget
-> GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e
Next forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenEntry tarPath linkTarget -> GenEntry tarPath linkTarget
f) forall tarPath linkTarget e. GenEntries tarPath linkTarget e
Done forall tarPath linkTarget e. e -> GenEntries tarPath linkTarget e
Fail
instance Sem.Semigroup (GenEntries tarPath linkTarget e) where
GenEntries tarPath linkTarget e
a <> :: GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e
<> GenEntries tarPath linkTarget e
b = forall tarPath linkTarget a e.
(GenEntry tarPath linkTarget -> a -> a)
-> a -> (e -> a) -> GenEntries tarPath linkTarget e -> a
foldEntries forall tarPath linkTarget e.
GenEntry tarPath linkTarget
-> GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e
Next GenEntries tarPath linkTarget e
b forall tarPath linkTarget e. e -> GenEntries tarPath linkTarget e
Fail GenEntries tarPath linkTarget e
a
instance Monoid (GenEntries tarPath linkTarget e) where
mempty :: GenEntries tarPath linkTarget e
mempty = forall tarPath linkTarget e. GenEntries tarPath linkTarget e
Done
mappend :: GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e
-> GenEntries tarPath linkTarget e
mappend = forall a. Semigroup a => a -> a -> a
(Sem.<>)
instance (NFData tarPath, NFData linkTarget, NFData e) => NFData (GenEntries tarPath linkTarget e) where
rnf :: GenEntries tarPath linkTarget e -> ()
rnf (Next GenEntry tarPath linkTarget
e GenEntries tarPath linkTarget e
es) = forall a. NFData a => a -> ()
rnf GenEntry tarPath linkTarget
e seq :: forall a b. a -> b -> b
`seq` forall a. NFData a => a -> ()
rnf GenEntries tarPath linkTarget e
es
rnf GenEntries tarPath linkTarget e
Done = ()
rnf (Fail e
e) = forall a. NFData a => a -> ()
rnf e
e