packages feed

waiz-0.0.1.0: src/Network/Wai/Optics/FilePart.hs

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# OPTIONS_GHC -Wall #-}

-- | Classy optics and field lenses for 'FilePart'.
module Network.Wai.Optics.FilePart (
  -- * Classy optics
  GetFilePart (..),
  HasFilePart (..),
  ReviewFilePart (..),
  AsFilePart (..),
) where

import Control.Category (id)
import Control.Lens (Getter, Lens', Prism', Review, lens, prism', review, set, to, unto, view)
import Data.Maybe (Maybe (..))
import Network.Wai.Internal (FilePart)
import qualified Network.Wai.Internal as Wai
import Network.Wai.Optics.Internal (
  filePartByteCountL,
  filePartFileSizeL,
  filePartOffsetL,
 )
import Prelude (Integer, const, flip, (.))

{- | Type class for values that can be viewed as a 'FilePart'.

>>> view getFilePart (Wai.FilePart 0 100 200)
FilePart {filePartOffset = 0, filePartByteCount = 100, filePartFileSize = 200}

>>> view getFilePartOffset (Wai.FilePart 10 100 200)
10

>>> view getFilePartByteCount (Wai.FilePart 0 100 200)
100

>>> view getFilePartFileSize (Wai.FilePart 0 100 200)
200
-}
class GetFilePart s where
  -- | A 'Getter' to obtain a 'FilePart'.
  getFilePart :: Getter s FilePart

  -- | A 'Getter' on the byte offset of a 'FilePart'.
  getFilePartOffset :: Getter s Integer
  getFilePartOffset = getFilePart . to Wai.filePartOffset
  {-# INLINE getFilePartOffset #-}

  -- | A 'Getter' on the byte count of a 'FilePart'.
  getFilePartByteCount :: Getter s Integer
  getFilePartByteCount = getFilePart . to Wai.filePartByteCount
  {-# INLINE getFilePartByteCount #-}

  -- | A 'Getter' on the total file size of a 'FilePart'.
  getFilePartFileSize :: Getter s Integer
  getFilePartFileSize = getFilePart . to Wai.filePartFileSize
  {-# INLINE getFilePartFileSize #-}

instance GetFilePart FilePart where
  getFilePart = id
  {-# INLINE getFilePart #-}
  getFilePartOffset = to Wai.filePartOffset
  {-# INLINE getFilePartOffset #-}
  getFilePartByteCount = to Wai.filePartByteCount
  {-# INLINE getFilePartByteCount #-}
  getFilePartFileSize = to Wai.filePartFileSize
  {-# INLINE getFilePartFileSize #-}

{- | Type class for values with a lens into a 'FilePart'.

>>> view filePart (Wai.FilePart 0 100 200)
FilePart {filePartOffset = 0, filePartByteCount = 100, filePartFileSize = 200}

>>> set filePart (Wai.FilePart 10 50 100) (Wai.FilePart 0 100 200)
FilePart {filePartOffset = 10, filePartByteCount = 50, filePartFileSize = 100}

>>> view filePartOffset (Wai.FilePart 10 100 200)
10

>>> set filePartOffset 50 (Wai.FilePart 10 100 200)
FilePart {filePartOffset = 50, filePartByteCount = 100, filePartFileSize = 200}

>>> view filePartByteCount (Wai.FilePart 0 100 200)
100

>>> set filePartByteCount 50 (Wai.FilePart 0 100 200)
FilePart {filePartOffset = 0, filePartByteCount = 50, filePartFileSize = 200}

>>> view filePartFileSize (Wai.FilePart 0 100 200)
200

>>> set filePartFileSize 500 (Wai.FilePart 0 100 200)
FilePart {filePartOffset = 0, filePartByteCount = 100, filePartFileSize = 500}
-}
class (GetFilePart s) => HasFilePart s where
  {-# MINIMAL setFilePart #-}

  -- | Replace the 'FilePart' component.
  setFilePart :: FilePart -> s -> s

  -- | A 'Lens'' into the 'FilePart' component.
  filePart :: Lens' s FilePart
  filePart = lens (view getFilePart) (flip setFilePart)
  {-# INLINE filePart #-}

  -- | Replace the byte offset of a 'FilePart'.
  setFilePartOffset :: Integer -> s -> s
  setFilePartOffset = set filePartOffset
  {-# INLINE setFilePartOffset #-}

  -- | A 'Lens'' on the byte offset of a 'FilePart'.
  filePartOffset :: Lens' s Integer
  filePartOffset = filePart . filePartOffsetL
  {-# INLINE filePartOffset #-}

  -- | Replace the byte count of a 'FilePart'.
  setFilePartByteCount :: Integer -> s -> s
  setFilePartByteCount = set filePartByteCount
  {-# INLINE setFilePartByteCount #-}

  -- | A 'Lens'' on the byte count of a 'FilePart'.
  filePartByteCount :: Lens' s Integer
  filePartByteCount = filePart . filePartByteCountL
  {-# INLINE filePartByteCount #-}

  -- | Replace the total file size of a 'FilePart'.
  setFilePartFileSize :: Integer -> s -> s
  setFilePartFileSize = set filePartFileSize
  {-# INLINE setFilePartFileSize #-}

  -- | A 'Lens'' on the total file size of a 'FilePart'.
  filePartFileSize :: Lens' s Integer
  filePartFileSize = filePart . filePartFileSizeL
  {-# INLINE filePartFileSize #-}

instance HasFilePart FilePart where
  setFilePart = const
  {-# INLINE setFilePart #-}
  filePartOffset = filePartOffsetL
  {-# INLINE filePartOffset #-}
  filePartByteCount = filePartByteCountL
  {-# INLINE filePartByteCount #-}
  filePartFileSize = filePartFileSizeL
  {-# INLINE filePartFileSize #-}

{- | Type class for values that can be constructed from a 'FilePart'.

>>> review reviewFilePart (Wai.FilePart 0 100 200) :: FilePart
FilePart {filePartOffset = 0, filePartByteCount = 100, filePartFileSize = 200}
-}
class ReviewFilePart t where
  -- | A 'Review' to construct a value from a 'FilePart'.
  reviewFilePart :: Review t FilePart

instance ReviewFilePart FilePart where
  reviewFilePart = unto id
  {-# INLINE reviewFilePart #-}

{- | Type class for values with a prism into a 'FilePart'.

>>> import Control.Lens (preview)
>>> preview _FilePart (Wai.FilePart 0 100 200)
Just (FilePart {filePartOffset = 0, filePartByteCount = 100, filePartFileSize = 200})
-}
class (ReviewFilePart t) => AsFilePart t where
  {-# MINIMAL matchFilePart #-}

  -- | Attempt to extract a 'FilePart'.
  matchFilePart :: t -> Maybe FilePart

  -- | A 'Prism'' into a 'FilePart'.
  _FilePart :: Prism' t FilePart
  _FilePart = prism' (review reviewFilePart) matchFilePart
  {-# INLINE _FilePart #-}

instance AsFilePart FilePart where
  matchFilePart = Just
  {-# INLINE matchFilePart #-}