{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}

-- |
-- Module      :  Codec.Archive.Zip.Type
-- Copyright   :  © 2016–present Mark Karpov
-- License     :  BSD 3 clause
--
-- Maintainer  :  Mark Karpov <markkarpov92@gmail.com>
-- Stability   :  experimental
-- Portability :  portable
--
-- Types used by the package.
module Codec.Archive.Zip.Type
  ( -- * Entry selector
    EntrySelector,
    mkEntrySelector,
    unEntrySelector,
    getEntryName,
    EntrySelectorException (..),

    -- * Entry description
    EntryDescription (..),
    CompressionMethod (..),

    -- * Archive description
    ArchiveDescription (..),

    -- * Exceptions
    ZipException (..),
  )
where

import Control.Exception (Exception)
import Control.Monad.Catch (MonadThrow (..))
import Data.ByteString (ByteString)
import Data.ByteString qualified as B
import Data.CaseInsensitive (CI)
import Data.CaseInsensitive qualified as CI
import Data.Data (Data)
import Data.List.NonEmpty (NonEmpty)
import Data.List.NonEmpty qualified as NE
import Data.Map (Map)
import Data.Maybe (mapMaybe)
import Data.Text (Text)
import Data.Text qualified as T
import Data.Text.Encoding qualified as T
import Data.Time.Clock (UTCTime)
import Data.Typeable (Typeable)
import Data.Version (Version)
import Data.Word (Word16, Word32)
import Numeric.Natural
import System.FilePath qualified as FP
import System.FilePath.Posix qualified as Posix
import System.FilePath.Windows qualified as Windows

----------------------------------------------------------------------------
-- Entry selector

-- | This data type serves for naming and selection of archive entries. It
-- can be created only with the help of the smart constructor
-- 'mkEntrySelector', and it's the only “key” that can be used to refer to
-- files in the archive or to name new archive entries.
--
-- The abstraction is crucial for ensuring that created archives are
-- portable across operating systems, file systems, and platforms. Since on
-- some operating systems, file paths are case-insensitive, this selector is
-- also case-insensitive. It makes sure that only relative paths are used to
-- name files inside archive, as it's recommended in the specification. It
-- also guarantees that forward slashes are used when the path is stored
-- inside the archive for compatibility with Unix-like operating systems (as
-- recommended in the specification). On the other hand, in can be rendered
-- as an ordinary relative file path in OS-specific format when needed.
newtype EntrySelector = EntrySelector
  { -- | Path pieces of relative path inside archive
    EntrySelector -> NonEmpty (CI String)
unES :: NonEmpty (CI String)
  }
  deriving (EntrySelector -> EntrySelector -> Bool
(EntrySelector -> EntrySelector -> Bool)
-> (EntrySelector -> EntrySelector -> Bool) -> Eq EntrySelector
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EntrySelector -> EntrySelector -> Bool
== :: EntrySelector -> EntrySelector -> Bool
$c/= :: EntrySelector -> EntrySelector -> Bool
/= :: EntrySelector -> EntrySelector -> Bool
Eq, Eq EntrySelector
Eq EntrySelector =>
(EntrySelector -> EntrySelector -> Ordering)
-> (EntrySelector -> EntrySelector -> Bool)
-> (EntrySelector -> EntrySelector -> Bool)
-> (EntrySelector -> EntrySelector -> Bool)
-> (EntrySelector -> EntrySelector -> Bool)
-> (EntrySelector -> EntrySelector -> EntrySelector)
-> (EntrySelector -> EntrySelector -> EntrySelector)
-> Ord EntrySelector
EntrySelector -> EntrySelector -> Bool
EntrySelector -> EntrySelector -> Ordering
EntrySelector -> EntrySelector -> EntrySelector
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
$ccompare :: EntrySelector -> EntrySelector -> Ordering
compare :: EntrySelector -> EntrySelector -> Ordering
$c< :: EntrySelector -> EntrySelector -> Bool
< :: EntrySelector -> EntrySelector -> Bool
$c<= :: EntrySelector -> EntrySelector -> Bool
<= :: EntrySelector -> EntrySelector -> Bool
$c> :: EntrySelector -> EntrySelector -> Bool
> :: EntrySelector -> EntrySelector -> Bool
$c>= :: EntrySelector -> EntrySelector -> Bool
>= :: EntrySelector -> EntrySelector -> Bool
$cmax :: EntrySelector -> EntrySelector -> EntrySelector
max :: EntrySelector -> EntrySelector -> EntrySelector
$cmin :: EntrySelector -> EntrySelector -> EntrySelector
min :: EntrySelector -> EntrySelector -> EntrySelector
Ord, Typeable)

instance Show EntrySelector where
  show :: EntrySelector -> String
show = ShowS
forall a. Show a => a -> String
show ShowS -> (EntrySelector -> String) -> EntrySelector -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EntrySelector -> String
unEntrySelector

-- | Create an 'EntrySelector' from a 'FilePath'. To avoid problems with
-- distribution of the archive, characters that some operating systems do
-- not expect in paths are not allowed.
--
-- Argument to 'mkEntrySelector' should pass these checks:
--
--     * 'System.FilePath.Posix.isValid'
--     * 'System.FilePath.Windows.isValid'
--     * it is a relative path without slash at the end
--     * binary representations of normalized path should be not longer than
--       65535 bytes
--
-- This function can throw an 'EntrySelectorException'.
mkEntrySelector :: (MonadThrow m) => FilePath -> m EntrySelector
mkEntrySelector :: forall (m :: * -> *). MonadThrow m => String -> m EntrySelector
mkEntrySelector String
path =
  let f :: String -> Maybe (CI String)
f String
x =
        case (Char -> Bool) -> ShowS
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
FP.isPathSeparator) String
x of
          [] -> Maybe (CI String)
forall a. Maybe a
Nothing
          String
xs -> CI String -> Maybe (CI String)
forall a. a -> Maybe a
Just (String -> CI String
forall s. FoldCase s => s -> CI s
CI.mk String
xs)
      giveup :: m a
giveup = EntrySelectorException -> m a
forall e a. (HasCallStack, Exception e) => e -> m a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
throwM (String -> EntrySelectorException
InvalidEntrySelector String
path)
   in case [CI String] -> Maybe (NonEmpty (CI String))
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty ((String -> Maybe (CI String)) -> [String] -> [CI String]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe String -> Maybe (CI String)
f (String -> [String]
FP.splitPath String
path)) of
        Maybe (NonEmpty (CI String))
Nothing -> m EntrySelector
forall {a}. m a
giveup
        Just NonEmpty (CI String)
pieces ->
          let selector :: EntrySelector
selector = NonEmpty (CI String) -> EntrySelector
EntrySelector NonEmpty (CI String)
pieces
              binLength :: EntrySelector -> Int
binLength = ByteString -> Int
B.length (ByteString -> Int)
-> (EntrySelector -> ByteString) -> EntrySelector -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
T.encodeUtf8 (Text -> ByteString)
-> (EntrySelector -> Text) -> EntrySelector -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EntrySelector -> Text
getEntryName
           in if String -> Bool
Posix.isValid String
path
                Bool -> Bool -> Bool
&& String -> Bool
Windows.isValid String
path
                Bool -> Bool -> Bool
&& Bool -> Bool
not (String -> Bool
FP.isAbsolute String
path Bool -> Bool -> Bool
|| String -> Bool
FP.hasTrailingPathSeparator String
path)
                Bool -> Bool -> Bool
&& (String -> CI String
forall s. FoldCase s => s -> CI s
CI.mk String
"." CI String -> NonEmpty (CI String) -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` NonEmpty (CI String)
pieces)
                Bool -> Bool -> Bool
&& (String -> CI String
forall s. FoldCase s => s -> CI s
CI.mk String
".." CI String -> NonEmpty (CI String) -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` NonEmpty (CI String)
pieces)
                Bool -> Bool -> Bool
&& EntrySelector -> Int
binLength EntrySelector
selector Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0xffff
                then EntrySelector -> m EntrySelector
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return EntrySelector
selector
                else m EntrySelector
forall {a}. m a
giveup

-- | Restore a relative path from 'EntrySelector'. Every 'EntrySelector'
-- corresponds to a 'FilePath'.
unEntrySelector :: EntrySelector -> FilePath
unEntrySelector :: EntrySelector -> String
unEntrySelector =
  [String] -> String
FP.joinPath ([String] -> String)
-> (EntrySelector -> [String]) -> EntrySelector -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CI String -> String) -> [CI String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CI String -> String
forall s. CI s -> s
CI.original ([CI String] -> [String])
-> (EntrySelector -> [CI String]) -> EntrySelector -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (CI String) -> [CI String]
forall a. NonEmpty a -> [a]
NE.toList (NonEmpty (CI String) -> [CI String])
-> (EntrySelector -> NonEmpty (CI String))
-> EntrySelector
-> [CI String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EntrySelector -> NonEmpty (CI String)
unES

-- | Get an entry name in the from that is suitable for writing to file
-- header, given an 'EntrySelector'.
getEntryName :: EntrySelector -> Text
getEntryName :: EntrySelector -> Text
getEntryName =
  String -> Text
T.pack (String -> Text)
-> (EntrySelector -> String) -> EntrySelector -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([String] -> String)
-> (EntrySelector -> [String]) -> EntrySelector -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty String -> [String]
forall a. NonEmpty a -> [a]
NE.toList (NonEmpty String -> [String])
-> (EntrySelector -> NonEmpty String) -> EntrySelector -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> NonEmpty String -> NonEmpty String
forall a. a -> NonEmpty a -> NonEmpty a
NE.intersperse String
"/" (NonEmpty String -> NonEmpty String)
-> (EntrySelector -> NonEmpty String)
-> EntrySelector
-> NonEmpty String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CI String -> String) -> NonEmpty (CI String) -> NonEmpty String
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CI String -> String
forall s. CI s -> s
CI.original (NonEmpty (CI String) -> NonEmpty String)
-> (EntrySelector -> NonEmpty (CI String))
-> EntrySelector
-> NonEmpty String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EntrySelector -> NonEmpty (CI String)
unES

-- | The problems you can have with an 'EntrySelector'.
newtype EntrySelectorException
  = -- | 'EntrySelector' cannot be created from this path
    InvalidEntrySelector FilePath
  deriving (EntrySelectorException -> EntrySelectorException -> Bool
(EntrySelectorException -> EntrySelectorException -> Bool)
-> (EntrySelectorException -> EntrySelectorException -> Bool)
-> Eq EntrySelectorException
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EntrySelectorException -> EntrySelectorException -> Bool
== :: EntrySelectorException -> EntrySelectorException -> Bool
$c/= :: EntrySelectorException -> EntrySelectorException -> Bool
/= :: EntrySelectorException -> EntrySelectorException -> Bool
Eq, Eq EntrySelectorException
Eq EntrySelectorException =>
(EntrySelectorException -> EntrySelectorException -> Ordering)
-> (EntrySelectorException -> EntrySelectorException -> Bool)
-> (EntrySelectorException -> EntrySelectorException -> Bool)
-> (EntrySelectorException -> EntrySelectorException -> Bool)
-> (EntrySelectorException -> EntrySelectorException -> Bool)
-> (EntrySelectorException
    -> EntrySelectorException -> EntrySelectorException)
-> (EntrySelectorException
    -> EntrySelectorException -> EntrySelectorException)
-> Ord EntrySelectorException
EntrySelectorException -> EntrySelectorException -> Bool
EntrySelectorException -> EntrySelectorException -> Ordering
EntrySelectorException
-> EntrySelectorException -> EntrySelectorException
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
$ccompare :: EntrySelectorException -> EntrySelectorException -> Ordering
compare :: EntrySelectorException -> EntrySelectorException -> Ordering
$c< :: EntrySelectorException -> EntrySelectorException -> Bool
< :: EntrySelectorException -> EntrySelectorException -> Bool
$c<= :: EntrySelectorException -> EntrySelectorException -> Bool
<= :: EntrySelectorException -> EntrySelectorException -> Bool
$c> :: EntrySelectorException -> EntrySelectorException -> Bool
> :: EntrySelectorException -> EntrySelectorException -> Bool
$c>= :: EntrySelectorException -> EntrySelectorException -> Bool
>= :: EntrySelectorException -> EntrySelectorException -> Bool
$cmax :: EntrySelectorException
-> EntrySelectorException -> EntrySelectorException
max :: EntrySelectorException
-> EntrySelectorException -> EntrySelectorException
$cmin :: EntrySelectorException
-> EntrySelectorException -> EntrySelectorException
min :: EntrySelectorException
-> EntrySelectorException -> EntrySelectorException
Ord, Typeable)

instance Show EntrySelectorException where
  show :: EntrySelectorException -> String
show (InvalidEntrySelector String
path) = String
"Cannot build selector from " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show String
path

instance Exception EntrySelectorException

----------------------------------------------------------------------------
-- Entry description

-- | The information about archive entry that can be stored in a zip
-- archive. It does not mirror local file header or central directory file
-- header, but their binary representations can be built given this data
-- structure and the archive contents.
data EntryDescription = EntryDescription
  { -- | Version made by
    EntryDescription -> Version
edVersionMadeBy :: Version,
    -- | Version needed to extract
    EntryDescription -> Version
edVersionNeeded :: Version,
    -- | Compression method
    EntryDescription -> CompressionMethod
edCompression :: CompressionMethod,
    -- | Last modification date and time
    EntryDescription -> UTCTime
edModTime :: UTCTime,
    -- | CRC32 check sum
    EntryDescription -> Word32
edCRC32 :: Word32,
    -- | Size of compressed entry
    EntryDescription -> Natural
edCompressedSize :: Natural,
    -- | Size of uncompressed entry
    EntryDescription -> Natural
edUncompressedSize :: Natural,
    -- | Absolute offset of local file header
    EntryDescription -> Natural
edOffset :: Natural,
    -- | Entry comment
    EntryDescription -> Maybe Text
edComment :: Maybe Text,
    -- | All extra fields found
    EntryDescription -> Map Word16 ByteString
edExtraField :: Map Word16 ByteString,
    -- | External file attributes
    --
    -- @since 1.2.0
    EntryDescription -> Word32
edExternalFileAttrs :: Word32
  }
  deriving (EntryDescription -> EntryDescription -> Bool
(EntryDescription -> EntryDescription -> Bool)
-> (EntryDescription -> EntryDescription -> Bool)
-> Eq EntryDescription
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EntryDescription -> EntryDescription -> Bool
== :: EntryDescription -> EntryDescription -> Bool
$c/= :: EntryDescription -> EntryDescription -> Bool
/= :: EntryDescription -> EntryDescription -> Bool
Eq, Typeable)

-- | The supported compression methods.
data CompressionMethod
  = -- | Store file uncompressed
    Store
  | -- | Deflate
    Deflate
  | -- | Compressed using BZip2 algorithm
    BZip2
  | -- | Compressed using Zstandard algorithm
    --
    -- @since 1.6.0
    Zstd
  deriving (Int -> CompressionMethod -> ShowS
[CompressionMethod] -> ShowS
CompressionMethod -> String
(Int -> CompressionMethod -> ShowS)
-> (CompressionMethod -> String)
-> ([CompressionMethod] -> ShowS)
-> Show CompressionMethod
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CompressionMethod -> ShowS
showsPrec :: Int -> CompressionMethod -> ShowS
$cshow :: CompressionMethod -> String
show :: CompressionMethod -> String
$cshowList :: [CompressionMethod] -> ShowS
showList :: [CompressionMethod] -> ShowS
Show, ReadPrec [CompressionMethod]
ReadPrec CompressionMethod
Int -> ReadS CompressionMethod
ReadS [CompressionMethod]
(Int -> ReadS CompressionMethod)
-> ReadS [CompressionMethod]
-> ReadPrec CompressionMethod
-> ReadPrec [CompressionMethod]
-> Read CompressionMethod
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS CompressionMethod
readsPrec :: Int -> ReadS CompressionMethod
$creadList :: ReadS [CompressionMethod]
readList :: ReadS [CompressionMethod]
$creadPrec :: ReadPrec CompressionMethod
readPrec :: ReadPrec CompressionMethod
$creadListPrec :: ReadPrec [CompressionMethod]
readListPrec :: ReadPrec [CompressionMethod]
Read, CompressionMethod -> CompressionMethod -> Bool
(CompressionMethod -> CompressionMethod -> Bool)
-> (CompressionMethod -> CompressionMethod -> Bool)
-> Eq CompressionMethod
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CompressionMethod -> CompressionMethod -> Bool
== :: CompressionMethod -> CompressionMethod -> Bool
$c/= :: CompressionMethod -> CompressionMethod -> Bool
/= :: CompressionMethod -> CompressionMethod -> Bool
Eq, Eq CompressionMethod
Eq CompressionMethod =>
(CompressionMethod -> CompressionMethod -> Ordering)
-> (CompressionMethod -> CompressionMethod -> Bool)
-> (CompressionMethod -> CompressionMethod -> Bool)
-> (CompressionMethod -> CompressionMethod -> Bool)
-> (CompressionMethod -> CompressionMethod -> Bool)
-> (CompressionMethod -> CompressionMethod -> CompressionMethod)
-> (CompressionMethod -> CompressionMethod -> CompressionMethod)
-> Ord CompressionMethod
CompressionMethod -> CompressionMethod -> Bool
CompressionMethod -> CompressionMethod -> Ordering
CompressionMethod -> CompressionMethod -> CompressionMethod
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
$ccompare :: CompressionMethod -> CompressionMethod -> Ordering
compare :: CompressionMethod -> CompressionMethod -> Ordering
$c< :: CompressionMethod -> CompressionMethod -> Bool
< :: CompressionMethod -> CompressionMethod -> Bool
$c<= :: CompressionMethod -> CompressionMethod -> Bool
<= :: CompressionMethod -> CompressionMethod -> Bool
$c> :: CompressionMethod -> CompressionMethod -> Bool
> :: CompressionMethod -> CompressionMethod -> Bool
$c>= :: CompressionMethod -> CompressionMethod -> Bool
>= :: CompressionMethod -> CompressionMethod -> Bool
$cmax :: CompressionMethod -> CompressionMethod -> CompressionMethod
max :: CompressionMethod -> CompressionMethod -> CompressionMethod
$cmin :: CompressionMethod -> CompressionMethod -> CompressionMethod
min :: CompressionMethod -> CompressionMethod -> CompressionMethod
Ord, Int -> CompressionMethod
CompressionMethod -> Int
CompressionMethod -> [CompressionMethod]
CompressionMethod -> CompressionMethod
CompressionMethod -> CompressionMethod -> [CompressionMethod]
CompressionMethod
-> CompressionMethod -> CompressionMethod -> [CompressionMethod]
(CompressionMethod -> CompressionMethod)
-> (CompressionMethod -> CompressionMethod)
-> (Int -> CompressionMethod)
-> (CompressionMethod -> Int)
-> (CompressionMethod -> [CompressionMethod])
-> (CompressionMethod -> CompressionMethod -> [CompressionMethod])
-> (CompressionMethod -> CompressionMethod -> [CompressionMethod])
-> (CompressionMethod
    -> CompressionMethod -> CompressionMethod -> [CompressionMethod])
-> Enum CompressionMethod
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: CompressionMethod -> CompressionMethod
succ :: CompressionMethod -> CompressionMethod
$cpred :: CompressionMethod -> CompressionMethod
pred :: CompressionMethod -> CompressionMethod
$ctoEnum :: Int -> CompressionMethod
toEnum :: Int -> CompressionMethod
$cfromEnum :: CompressionMethod -> Int
fromEnum :: CompressionMethod -> Int
$cenumFrom :: CompressionMethod -> [CompressionMethod]
enumFrom :: CompressionMethod -> [CompressionMethod]
$cenumFromThen :: CompressionMethod -> CompressionMethod -> [CompressionMethod]
enumFromThen :: CompressionMethod -> CompressionMethod -> [CompressionMethod]
$cenumFromTo :: CompressionMethod -> CompressionMethod -> [CompressionMethod]
enumFromTo :: CompressionMethod -> CompressionMethod -> [CompressionMethod]
$cenumFromThenTo :: CompressionMethod
-> CompressionMethod -> CompressionMethod -> [CompressionMethod]
enumFromThenTo :: CompressionMethod
-> CompressionMethod -> CompressionMethod -> [CompressionMethod]
Enum, CompressionMethod
CompressionMethod -> CompressionMethod -> Bounded CompressionMethod
forall a. a -> a -> Bounded a
$cminBound :: CompressionMethod
minBound :: CompressionMethod
$cmaxBound :: CompressionMethod
maxBound :: CompressionMethod
Bounded, Typeable CompressionMethod
Typeable CompressionMethod =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g)
 -> CompressionMethod
 -> c CompressionMethod)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c CompressionMethod)
-> (CompressionMethod -> Constr)
-> (CompressionMethod -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c CompressionMethod))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c CompressionMethod))
-> ((forall b. Data b => b -> b)
    -> CompressionMethod -> CompressionMethod)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> CompressionMethod -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> CompressionMethod -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> CompressionMethod -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> CompressionMethod -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> CompressionMethod -> m CompressionMethod)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> CompressionMethod -> m CompressionMethod)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> CompressionMethod -> m CompressionMethod)
-> Data CompressionMethod
CompressionMethod -> Constr
CompressionMethod -> DataType
(forall b. Data b => b -> b)
-> CompressionMethod -> CompressionMethod
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) -> CompressionMethod -> u
forall u. (forall d. Data d => d -> u) -> CompressionMethod -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CompressionMethod -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CompressionMethod -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> CompressionMethod -> m CompressionMethod
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> CompressionMethod -> m CompressionMethod
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CompressionMethod
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CompressionMethod -> c CompressionMethod
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CompressionMethod)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c CompressionMethod)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CompressionMethod -> c CompressionMethod
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CompressionMethod -> c CompressionMethod
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CompressionMethod
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CompressionMethod
$ctoConstr :: CompressionMethod -> Constr
toConstr :: CompressionMethod -> Constr
$cdataTypeOf :: CompressionMethod -> DataType
dataTypeOf :: CompressionMethod -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CompressionMethod)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CompressionMethod)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c CompressionMethod)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c CompressionMethod)
$cgmapT :: (forall b. Data b => b -> b)
-> CompressionMethod -> CompressionMethod
gmapT :: (forall b. Data b => b -> b)
-> CompressionMethod -> CompressionMethod
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CompressionMethod -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CompressionMethod -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CompressionMethod -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CompressionMethod -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> CompressionMethod -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> CompressionMethod -> [u]
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> CompressionMethod -> u
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> CompressionMethod -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> CompressionMethod -> m CompressionMethod
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> CompressionMethod -> m CompressionMethod
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> CompressionMethod -> m CompressionMethod
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> CompressionMethod -> m CompressionMethod
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> CompressionMethod -> m CompressionMethod
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> CompressionMethod -> m CompressionMethod
Data, Typeable)

----------------------------------------------------------------------------
-- Archive description

-- | The information about the archive as a whole.
data ArchiveDescription = ArchiveDescription
  { -- | The comment of the entire archive
    ArchiveDescription -> Maybe Text
adComment :: Maybe Text,
    -- | Absolute offset of the start of central directory
    ArchiveDescription -> Natural
adCDOffset :: Natural,
    -- | The size of central directory record
    ArchiveDescription -> Natural
adCDSize :: Natural
  }
  deriving (Int -> ArchiveDescription -> ShowS
[ArchiveDescription] -> ShowS
ArchiveDescription -> String
(Int -> ArchiveDescription -> ShowS)
-> (ArchiveDescription -> String)
-> ([ArchiveDescription] -> ShowS)
-> Show ArchiveDescription
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ArchiveDescription -> ShowS
showsPrec :: Int -> ArchiveDescription -> ShowS
$cshow :: ArchiveDescription -> String
show :: ArchiveDescription -> String
$cshowList :: [ArchiveDescription] -> ShowS
showList :: [ArchiveDescription] -> ShowS
Show, ReadPrec [ArchiveDescription]
ReadPrec ArchiveDescription
Int -> ReadS ArchiveDescription
ReadS [ArchiveDescription]
(Int -> ReadS ArchiveDescription)
-> ReadS [ArchiveDescription]
-> ReadPrec ArchiveDescription
-> ReadPrec [ArchiveDescription]
-> Read ArchiveDescription
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS ArchiveDescription
readsPrec :: Int -> ReadS ArchiveDescription
$creadList :: ReadS [ArchiveDescription]
readList :: ReadS [ArchiveDescription]
$creadPrec :: ReadPrec ArchiveDescription
readPrec :: ReadPrec ArchiveDescription
$creadListPrec :: ReadPrec [ArchiveDescription]
readListPrec :: ReadPrec [ArchiveDescription]
Read, ArchiveDescription -> ArchiveDescription -> Bool
(ArchiveDescription -> ArchiveDescription -> Bool)
-> (ArchiveDescription -> ArchiveDescription -> Bool)
-> Eq ArchiveDescription
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ArchiveDescription -> ArchiveDescription -> Bool
== :: ArchiveDescription -> ArchiveDescription -> Bool
$c/= :: ArchiveDescription -> ArchiveDescription -> Bool
/= :: ArchiveDescription -> ArchiveDescription -> Bool
Eq, Eq ArchiveDescription
Eq ArchiveDescription =>
(ArchiveDescription -> ArchiveDescription -> Ordering)
-> (ArchiveDescription -> ArchiveDescription -> Bool)
-> (ArchiveDescription -> ArchiveDescription -> Bool)
-> (ArchiveDescription -> ArchiveDescription -> Bool)
-> (ArchiveDescription -> ArchiveDescription -> Bool)
-> (ArchiveDescription -> ArchiveDescription -> ArchiveDescription)
-> (ArchiveDescription -> ArchiveDescription -> ArchiveDescription)
-> Ord ArchiveDescription
ArchiveDescription -> ArchiveDescription -> Bool
ArchiveDescription -> ArchiveDescription -> Ordering
ArchiveDescription -> ArchiveDescription -> ArchiveDescription
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
$ccompare :: ArchiveDescription -> ArchiveDescription -> Ordering
compare :: ArchiveDescription -> ArchiveDescription -> Ordering
$c< :: ArchiveDescription -> ArchiveDescription -> Bool
< :: ArchiveDescription -> ArchiveDescription -> Bool
$c<= :: ArchiveDescription -> ArchiveDescription -> Bool
<= :: ArchiveDescription -> ArchiveDescription -> Bool
$c> :: ArchiveDescription -> ArchiveDescription -> Bool
> :: ArchiveDescription -> ArchiveDescription -> Bool
$c>= :: ArchiveDescription -> ArchiveDescription -> Bool
>= :: ArchiveDescription -> ArchiveDescription -> Bool
$cmax :: ArchiveDescription -> ArchiveDescription -> ArchiveDescription
max :: ArchiveDescription -> ArchiveDescription -> ArchiveDescription
$cmin :: ArchiveDescription -> ArchiveDescription -> ArchiveDescription
min :: ArchiveDescription -> ArchiveDescription -> ArchiveDescription
Ord, Typeable, Typeable ArchiveDescription
Typeable ArchiveDescription =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g)
 -> ArchiveDescription
 -> c ArchiveDescription)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ArchiveDescription)
-> (ArchiveDescription -> Constr)
-> (ArchiveDescription -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ArchiveDescription))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c ArchiveDescription))
-> ((forall b. Data b => b -> b)
    -> ArchiveDescription -> ArchiveDescription)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ArchiveDescription -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ArchiveDescription -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> ArchiveDescription -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> ArchiveDescription -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> ArchiveDescription -> m ArchiveDescription)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ArchiveDescription -> m ArchiveDescription)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ArchiveDescription -> m ArchiveDescription)
-> Data ArchiveDescription
ArchiveDescription -> Constr
ArchiveDescription -> DataType
(forall b. Data b => b -> b)
-> ArchiveDescription -> ArchiveDescription
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) -> ArchiveDescription -> u
forall u. (forall d. Data d => d -> u) -> ArchiveDescription -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ArchiveDescription -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ArchiveDescription -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> ArchiveDescription -> m ArchiveDescription
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> ArchiveDescription -> m ArchiveDescription
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ArchiveDescription
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> ArchiveDescription
-> c ArchiveDescription
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ArchiveDescription)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ArchiveDescription)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> ArchiveDescription
-> c ArchiveDescription
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> ArchiveDescription
-> c ArchiveDescription
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ArchiveDescription
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ArchiveDescription
$ctoConstr :: ArchiveDescription -> Constr
toConstr :: ArchiveDescription -> Constr
$cdataTypeOf :: ArchiveDescription -> DataType
dataTypeOf :: ArchiveDescription -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ArchiveDescription)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ArchiveDescription)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ArchiveDescription)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ArchiveDescription)
$cgmapT :: (forall b. Data b => b -> b)
-> ArchiveDescription -> ArchiveDescription
gmapT :: (forall b. Data b => b -> b)
-> ArchiveDescription -> ArchiveDescription
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ArchiveDescription -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ArchiveDescription -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ArchiveDescription -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ArchiveDescription -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ArchiveDescription -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> ArchiveDescription -> [u]
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> ArchiveDescription -> u
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> ArchiveDescription -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> ArchiveDescription -> m ArchiveDescription
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> ArchiveDescription -> m ArchiveDescription
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> ArchiveDescription -> m ArchiveDescription
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> ArchiveDescription -> m ArchiveDescription
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> ArchiveDescription -> m ArchiveDescription
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> ArchiveDescription -> m ArchiveDescription
Data)

----------------------------------------------------------------------------
-- Exceptions

-- | The bad things that can happen when you use the library.
data ZipException
  = -- | Thrown when you try to get contents of non-existing entry
    EntryDoesNotExist FilePath EntrySelector
  | -- | Thrown when attempting to decompress an entry compressed with an
    -- unsupported compression method or the library is compiled without
    -- support for it.
    --
    -- @since 2.0.0
    UnsupportedCompressionMethod CompressionMethod
  | -- | Thrown when archive structure cannot be parsed.
    ParsingFailed FilePath String
  deriving (ZipException -> ZipException -> Bool
(ZipException -> ZipException -> Bool)
-> (ZipException -> ZipException -> Bool) -> Eq ZipException
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ZipException -> ZipException -> Bool
== :: ZipException -> ZipException -> Bool
$c/= :: ZipException -> ZipException -> Bool
/= :: ZipException -> ZipException -> Bool
Eq, Eq ZipException
Eq ZipException =>
(ZipException -> ZipException -> Ordering)
-> (ZipException -> ZipException -> Bool)
-> (ZipException -> ZipException -> Bool)
-> (ZipException -> ZipException -> Bool)
-> (ZipException -> ZipException -> Bool)
-> (ZipException -> ZipException -> ZipException)
-> (ZipException -> ZipException -> ZipException)
-> Ord ZipException
ZipException -> ZipException -> Bool
ZipException -> ZipException -> Ordering
ZipException -> ZipException -> ZipException
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
$ccompare :: ZipException -> ZipException -> Ordering
compare :: ZipException -> ZipException -> Ordering
$c< :: ZipException -> ZipException -> Bool
< :: ZipException -> ZipException -> Bool
$c<= :: ZipException -> ZipException -> Bool
<= :: ZipException -> ZipException -> Bool
$c> :: ZipException -> ZipException -> Bool
> :: ZipException -> ZipException -> Bool
$c>= :: ZipException -> ZipException -> Bool
>= :: ZipException -> ZipException -> Bool
$cmax :: ZipException -> ZipException -> ZipException
max :: ZipException -> ZipException -> ZipException
$cmin :: ZipException -> ZipException -> ZipException
min :: ZipException -> ZipException -> ZipException
Ord, Typeable)

instance Show ZipException where
  show :: ZipException -> String
show (EntryDoesNotExist String
file EntrySelector
s) =
    String
"No such entry found: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ EntrySelector -> String
forall a. Show a => a -> String
show EntrySelector
s String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" in " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show String
file
  show (ParsingFailed String
file String
msg) =
    String
"Parsing of archive structure failed: \n" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
msg String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\nin " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show String
file
  show (UnsupportedCompressionMethod CompressionMethod
method) =
    String
"Encountered a zipfile entry with "
      String -> ShowS
forall a. [a] -> [a] -> [a]
++ CompressionMethod -> String
forall a. Show a => a -> String
show CompressionMethod
method
      String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" compression, but "
      String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"zip library does not support it or has been built without support for it."

instance Exception ZipException