packages feed

document-build-0.2.0.0: src/Document/Build/ImageInfo.hs

{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wall #-}

{- | Information about an image.

A 'ImageInfo' is a product: its fields are named 'imageFormat', 'imageWidth', 'imageHeight', 'imageResolutionX', 'imageResolutionY', 'imageResolutionUnits', 'imageColourspace', 'imageDepth' and 'imageFrames'.
-}
module Document.Build.ImageInfo (
  -- * Type
  ImageInfo (..),

  -- * Optics
  ImageInfoLike (..),
  lawNamesImageInfo,
  InheritImageInfo,
  inheritImageInfo,
) where

import Control.DeepSeq (NFData)
import Control.Lens (Optic, cloneLens, view)
import Data.Aeson (FromJSON (..), ToJSON (..), object, withObject, (.:), (.=))
import Data.Data (Data)
import Data.Functor.Const (Const)
import Document.Build.Name.ImageColourspace (ImageColourspaceLike (..))
import Document.Build.Name.ImageDepth (ImageDepthLike (..))
import Document.Build.Name.ImageFormat (ImageFormatLike (..))
import Document.Build.Name.ImageFrames (ImageFramesLike (..))
import Document.Build.Name.ImageHeight (ImageHeightLike (..))
import Document.Build.Name.ImageResolutionUnits (ImageResolutionUnitsLike (..))
import Document.Build.Name.ImageResolutionX (ImageResolutionXLike (..))
import Document.Build.Name.ImageResolutionY (ImageResolutionYLike (..))
import Document.Build.Name.ImageWidth (ImageWidthLike (..))
import GHC.Generics (Generic)

{- | Information about an image: its format ('imageFormat'), such as @"PNG"@,
width ('imageWidth') and height ('imageHeight') in pixels, horizontal
('imageResolutionX') and vertical ('imageResolutionY') resolution, the units
of the resolution ('imageResolutionUnits'), such as @"PixelsPerInch"@ or
@"Undefined"@, colourspace ('imageColourspace'), such as @"sRGB"@, bit depth
('imageDepth'), and number of frames ('imageFrames').

@since 0.1.0.0
-}
data ImageInfo
  = ImageInfo String Int Int Double Double String String Int Int
  deriving stock (Eq, Ord, Show, Generic, Data)
  deriving anyclass (NFData)

-- | @since 0.1.0.0
instance ToJSON ImageInfo where
  toJSON (ImageInfo m w h x y u c z n) =
    object
      [ "format" .= m
      , "width" .= w
      , "height" .= h
      , "resolutionX" .= x
      , "resolutionY" .= y
      , "resolutionUnits" .= u
      , "colourspace" .= c
      , "depth" .= z
      , "frames" .= n
      ]

-- | @since 0.1.0.0
instance FromJSON ImageInfo where
  parseJSON =
    withObject "ImageInfo" $ \o ->
      ImageInfo
        <$> o .: "format"
        <*> o .: "width"
        <*> o .: "height"
        <*> o .: "resolutionX"
        <*> o .: "resolutionY"
        <*> o .: "resolutionUnits"
        <*> o .: "colourspace"
        <*> o .: "depth"
        <*> o .: "frames"

{- | The class of 'ImageInfo'.

@since 0.2.0.0
-}
class ImageInfoLike p f x x' where
  imageInfo ::
    Optic p f x x' ImageInfo ImageInfo

{- | Identity

@since 0.2.0.0
-}
instance (x' ~ ImageInfo) => ImageInfoLike p f ImageInfo x' where
  imageInfo =
    id
  {-# INLINE imageInfo #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ ImageInfo) => ImageFormatLike p f ImageInfo x' where
  imageFormat f (ImageInfo x1 x2 x3 x4 x5 x6 x7 x8 x9) =
    fmap (\x1' -> ImageInfo x1' x2 x3 x4 x5 x6 x7 x8 x9) (f x1)
  {-# INLINE imageFormat #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ ImageInfo) => ImageWidthLike p f ImageInfo x' where
  imageWidth f (ImageInfo x1 x2 x3 x4 x5 x6 x7 x8 x9) =
    fmap (\x2' -> ImageInfo x1 x2' x3 x4 x5 x6 x7 x8 x9) (f x2)
  {-# INLINE imageWidth #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ ImageInfo) => ImageHeightLike p f ImageInfo x' where
  imageHeight f (ImageInfo x1 x2 x3 x4 x5 x6 x7 x8 x9) =
    fmap (\x3' -> ImageInfo x1 x2 x3' x4 x5 x6 x7 x8 x9) (f x3)
  {-# INLINE imageHeight #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ ImageInfo) => ImageResolutionXLike p f ImageInfo x' where
  imageResolutionX f (ImageInfo x1 x2 x3 x4 x5 x6 x7 x8 x9) =
    fmap (\x4' -> ImageInfo x1 x2 x3 x4' x5 x6 x7 x8 x9) (f x4)
  {-# INLINE imageResolutionX #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ ImageInfo) => ImageResolutionYLike p f ImageInfo x' where
  imageResolutionY f (ImageInfo x1 x2 x3 x4 x5 x6 x7 x8 x9) =
    fmap (\x5' -> ImageInfo x1 x2 x3 x4 x5' x6 x7 x8 x9) (f x5)
  {-# INLINE imageResolutionY #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ ImageInfo) => ImageResolutionUnitsLike p f ImageInfo x' where
  imageResolutionUnits f (ImageInfo x1 x2 x3 x4 x5 x6 x7 x8 x9) =
    fmap (\x6' -> ImageInfo x1 x2 x3 x4 x5 x6' x7 x8 x9) (f x6)
  {-# INLINE imageResolutionUnits #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ ImageInfo) => ImageColourspaceLike p f ImageInfo x' where
  imageColourspace f (ImageInfo x1 x2 x3 x4 x5 x6 x7 x8 x9) =
    fmap (\x7' -> ImageInfo x1 x2 x3 x4 x5 x6 x7' x8 x9) (f x7)
  {-# INLINE imageColourspace #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ ImageInfo) => ImageDepthLike p f ImageInfo x' where
  imageDepth f (ImageInfo x1 x2 x3 x4 x5 x6 x7 x8 x9) =
    fmap (\x8' -> ImageInfo x1 x2 x3 x4 x5 x6 x7 x8' x9) (f x8)
  {-# INLINE imageDepth #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ ImageInfo) => ImageFramesLike p f ImageInfo x' where
  imageFrames f (ImageInfo x1 x2 x3 x4 x5 x6 x7 x8 x9) =
    fmap (ImageInfo x1 x2 x3 x4 x5 x6 x7 x8) (f x9)
  {-# INLINE imageFrames #-}

{- | Rebuild a value using only the name of each field.

Laws:

> lawNamesImageInfo == id

@since 0.2.0.0
-}
lawNamesImageInfo :: ImageInfo -> ImageInfo
lawNamesImageInfo s =
  ImageInfo
    (view (cloneLens imageFormat) s)
    (view (cloneLens imageWidth) s)
    (view (cloneLens imageHeight) s)
    (view (cloneLens imageResolutionX) s)
    (view (cloneLens imageResolutionY) s)
    (view (cloneLens imageResolutionUnits) s)
    (view (cloneLens imageColourspace) s)
    (view (cloneLens imageDepth) s)
    (view (cloneLens imageFrames) s)

{- | The classes that a data type holding 'ImageInfo' inherits.

@since 0.2.0.0
-}
type InheritImageInfo s =
  ( ImageInfoLike (->) (Const ()) s s
  , ImageFormatLike (->) (Const ()) s s
  , ImageWidthLike (->) (Const ()) s s
  , ImageHeightLike (->) (Const ()) s s
  , ImageResolutionXLike (->) (Const ()) s s
  , ImageResolutionYLike (->) (Const ()) s s
  , ImageResolutionUnitsLike (->) (Const ()) s s
  , ImageColourspaceLike (->) (Const ()) s s
  , ImageDepthLike (->) (Const ()) s s
  , ImageFramesLike (->) (Const ()) s s
  )

{- | Check, where it is applied, that @s@ inherits every name of 'ImageInfo'.

@since 0.2.0.0
-}
inheritImageInfo :: (InheritImageInfo s) => proxy s -> ()
inheritImageInfo _ =
  ()