photoname-5.2: src/lib/Photoname/Common.hs
{-# LANGUAGE DuplicateRecordFields #-}
module Photoname.Common
( Artist (..)
, ConfigPath (..)
, CopySwitch (..)
, DestPath (..)
, Extension (..)
, Links(..)
, MoveSwitch (..)
, NoActionSwitch (..)
, NoDirsSwitch (..)
, ParentDir (..)
, Options (..)
, Ph
, Prefix (..)
, SrcPath (..)
, Suffix (..)
, Verbosity (..)
, defaultDateTimeFormat
, readVerbosity
, runRename
-- Re-exporting:
, MonadError
, ask, asks
, liftIO
, throwError
)
where
import Control.Monad.Except (ExceptT, MonadError, runExceptT, throwError)
import Control.Monad.Reader (ReaderT, ask, asks, runReaderT)
import Control.Monad.Trans (liftIO)
import Data.Time.LocalTime (LocalTime)
import System.Log.Logger (Priority (..))
import System.Posix (CNlink)
defaultDateTimeFormat :: String
defaultDateTimeFormat = "%Y%m%d-%H%M%S"
data Verbosity
= Quiet
| Verbose Priority
instance Show Verbosity where
show Quiet = "0"
show (Verbose NOTICE) = "1"
show (Verbose INFO) = "2"
show (Verbose DEBUG) = "3"
show _ = "Should never see this, invalid verbosity level being shown"
readVerbosity :: String -> Either String Verbosity
readVerbosity "0" = Right Quiet
readVerbosity "1" = Right $ Verbose NOTICE
readVerbosity "2" = Right $ Verbose INFO
readVerbosity "3" = Right $ Verbose DEBUG
readVerbosity _ = Left "Invalid verbosity level, expecting 0-3"
newtype Artist = Artist String
newtype ConfigPath = ConfigPath FilePath
newtype CopySwitch = CopySwitch { v :: Bool }
type DateFormatter = LocalTime -> String
newtype NoDirsSwitch = NoDirsSwitch { v :: Bool }
data Extension = Extension FilePath | UseExistingExtension
data Links = Exactly CNlink | NoLimit
newtype MoveSwitch = MoveSwitch { v :: Bool }
newtype NoActionSwitch = NoActionSwitch { v :: Bool }
newtype ParentDir = ParentDir { v :: FilePath }
newtype Prefix = Prefix { v :: String }
newtype Suffix = Suffix { v :: String }
data Options = Options
{ artist :: Maybe Artist
, config :: Maybe ConfigPath
, copy :: CopySwitch
, noDirs :: NoDirsSwitch
, extension :: Extension
, formatter :: DateFormatter
, links :: Links
, move :: MoveSwitch
, noAction :: NoActionSwitch
, parentDir :: ParentDir
, prefix :: Prefix
, suffix :: Suffix
, verbosity :: Verbosity
, paths :: [FilePath]
}
newtype SrcPath = SrcPath { v :: FilePath }
newtype DestPath = DestPath FilePath
type Ph a = ReaderT Options (ExceptT String IO) a
runRename :: Options -> Ph a -> IO (Either String a)
runRename env action = runExceptT $ runReaderT action env