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

    -- |
    -- Module      :  Codec.Archive.Zip.Internal.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.Internal.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.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)

    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)

    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, Int -> EntryDescription -> ShowS
    [EntryDescription] -> ShowS
    EntryDescription -> String
    (Int -> EntryDescription -> ShowS)
    -> (EntryDescription -> String)
    -> ([EntryDescription] -> ShowS)
    -> Show EntryDescription
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> EntryDescription -> ShowS
    showsPrec :: Int -> EntryDescription -> ShowS
    $cshow :: EntryDescription -> String
    show :: EntryDescription -> String
    $cshowList :: [EntryDescription] -> ShowS
    showList :: [EntryDescription] -> ShowS
    Show)

    -- | 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)

    ----------------------------------------------------------------------------
    -- 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 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)

    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