{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} module Data.Foscam.File.Filename( Filename(..) , AsFilename(..) , filename , getFilename ) where import Control.Applicative(Applicative((<*>)), (<*), (<$>)) import Control.Category(id) import Control.Lens(Optic', lens, ( # )) import Control.Monad(Monad) import Data.Digit(Digit, digitC) import Data.Eq(Eq) import Data.Foscam.File.Internal(digitCharacter) import Data.Foscam.File.Alias(AsAlias(_Alias), Alias, alias) import Data.Foscam.File.Date(AsDate(_Date), Date, date) import Data.Foscam.File.DeviceId(AsDeviceId(_DeviceId), DeviceId, deviceId) import Data.Foscam.File.ImageId(AsImageId(_ImageId), ImageId, imageId) import Data.Foscam.File.Time(AsTime(_Time), Time, time) import Data.Functor(Functor) import Data.List((++)) import Data.Ord(Ord) import Data.String(String) import Text.Parser.Char(CharParsing, char, string) import Text.Parser.Combinators(()) import Prelude(Show) -- $setup -- >>> import Text.Parsec data Filename = Filename DeviceId Alias Digit Date Time ImageId deriving (Eq, Ord, Show) class AsFilename p f s where _Filename :: Optic' p f s Filename instance AsFilename p f Filename where _Filename = id instance (p ~ (->), Functor f) => AsDeviceId p f Filename where _DeviceId = lens (\(Filename i _ _ _ _ _) -> i) (\(Filename _ a x d t m) i -> Filename i a x d t m) instance (p ~ (->), Functor f) => AsAlias p f Filename where _Alias = lens (\(Filename _ a _ _ _ _) -> a) (\(Filename i _ x d t m) a -> Filename i a x d t m) instance (p ~ (->), Functor f) => AsDate p f Filename where _Date = lens (\(Filename _ _ _ d _ _) -> d) (\(Filename i a x _ t m) d -> Filename i a x d t m) instance (p ~ (->), Functor f) => AsTime p f Filename where _Time = lens (\(Filename _ _ _ _ t _) -> t) (\(Filename i a x d _ m) t -> Filename i a x d t m) instance (p ~ (->), Functor f) => AsImageId p f Filename where _ImageId = lens (\(Filename _ _ _ _ _ m) -> m) (\(Filename i a x d t _) m -> Filename i a x d t m) -- | -- -- >>> parse filename "test" "00626E44C831(house)_1_20150209134121_2629.jpg" -- Right (Filename (DeviceId (DeviceIdCharacter '0') (DeviceIdCharacter '0') (DeviceIdCharacter '6') (DeviceIdCharacter '2') (DeviceIdCharacter '6') (DeviceIdCharacter 'E') (DeviceIdCharacter '4') (DeviceIdCharacter '4') (DeviceIdCharacter 'C') (DeviceIdCharacter '8') (DeviceIdCharacter '3') (DeviceIdCharacter '1')) (Alias (AliasCharacter 'h') [AliasCharacter 'o',AliasCharacter 'u',AliasCharacter 's',AliasCharacter 'e']) 1 (Date 2 0 1 5 0 2 0 9) (Time 1 3 4 1 2 1) (ImageId 2 [6,2,9])) -- -- >>> parse filename "test" "00626E44C829(garage)_1_20140313234556_2660.jpg" -- Right (Filename (DeviceId (DeviceIdCharacter '0') (DeviceIdCharacter '0') (DeviceIdCharacter '6') (DeviceIdCharacter '2') (DeviceIdCharacter '6') (DeviceIdCharacter 'E') (DeviceIdCharacter '4') (DeviceIdCharacter '4') (DeviceIdCharacter 'C') (DeviceIdCharacter '8') (DeviceIdCharacter '2') (DeviceIdCharacter '9')) (Alias (AliasCharacter 'g') [AliasCharacter 'a',AliasCharacter 'r',AliasCharacter 'a',AliasCharacter 'g',AliasCharacter 'e']) 1 (Date 2 0 1 4 0 3 1 3) (Time 2 3 4 5 5 6) (ImageId 2 [6,6,0])) -- -- >>> parse filename "test" "00626E44C82x(garage)_1_20140313234556_2660.jpg" -- Left "test" (line 1, column 13): -- not a device ID character: x -- -- >>> parse filename "test" "00626E44C829(gara*ge)_1_20140313234556_2660.jpg" -- Left "test" (line 1, column 19): -- not an alias character: * -- -- >>> parse filename "test" "00626E44C829(garage) 1_20140313234556_2660.jpg" -- Left "test" (line 1, column 20): -- unexpected " " -- expecting ")_" -- -- >>> parse filename "test" "00626E44C829(garage)_x_20140313234556_2660.jpg" -- Left "test" (line 1, column 23): -- not a digit: x -- -- >>> parse filename "test" "00626E44C829(garage)_1 20140313234556_2660.jpg" -- Left "test" (line 1, column 23): -- unexpected " " -- expecting "_" -- -- >>> parse filename "test" "00626E44C829(garage)_1_x0140313234556_2660.jpg" -- Left "test" (line 1, column 25): -- not a digit: x filename :: (Monad f, CharParsing f) => f Filename filename = Filename <$> deviceId <* char '(' <*> alias <* string ")_" <*> digitCharacter <* char '_' <*> date <*> time <* char '_' <*> imageId <* string ".jpg" "file" getFilename :: Filename -> String getFilename (Filename i a x d t m) = _DeviceId # i ++ '(' : _Alias # a ++ ")_" ++ [digitC # x, '_'] ++ _Date # d ++ _Time # t ++ '_' : _ImageId # m ++ ".jpg"