{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DeriveAnyClass #-}

module Emanote.Route.Ext where

import Data.Aeson (ToJSON)
import Data.Data (Data)
import Relude hiding (show)
import System.FilePath qualified as FP

data SourceExt = SourceExt
  deriving stock (SourceExt -> SourceExt -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SourceExt -> SourceExt -> Bool
$c/= :: SourceExt -> SourceExt -> Bool
== :: SourceExt -> SourceExt -> Bool
$c== :: SourceExt -> SourceExt -> Bool
Eq, Eq SourceExt
SourceExt -> SourceExt -> Bool
SourceExt -> SourceExt -> Ordering
SourceExt -> SourceExt -> SourceExt
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
min :: SourceExt -> SourceExt -> SourceExt
$cmin :: SourceExt -> SourceExt -> SourceExt
max :: SourceExt -> SourceExt -> SourceExt
$cmax :: SourceExt -> SourceExt -> SourceExt
>= :: SourceExt -> SourceExt -> Bool
$c>= :: SourceExt -> SourceExt -> Bool
> :: SourceExt -> SourceExt -> Bool
$c> :: SourceExt -> SourceExt -> Bool
<= :: SourceExt -> SourceExt -> Bool
$c<= :: SourceExt -> SourceExt -> Bool
< :: SourceExt -> SourceExt -> Bool
$c< :: SourceExt -> SourceExt -> Bool
compare :: SourceExt -> SourceExt -> Ordering
$ccompare :: SourceExt -> SourceExt -> Ordering
Ord, Int -> SourceExt -> ShowS
[SourceExt] -> ShowS
SourceExt -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SourceExt] -> ShowS
$cshowList :: [SourceExt] -> ShowS
show :: SourceExt -> String
$cshow :: SourceExt -> String
showsPrec :: Int -> SourceExt -> ShowS
$cshowsPrec :: Int -> SourceExt -> ShowS
Show, ReadPrec [SourceExt]
ReadPrec SourceExt
Int -> ReadS SourceExt
ReadS [SourceExt]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SourceExt]
$creadListPrec :: ReadPrec [SourceExt]
readPrec :: ReadPrec SourceExt
$creadPrec :: ReadPrec SourceExt
readList :: ReadS [SourceExt]
$creadList :: ReadS [SourceExt]
readsPrec :: Int -> ReadS SourceExt
$creadsPrec :: Int -> ReadS SourceExt
Read, Typeable @Type SourceExt
SourceExt -> DataType
SourceExt -> Constr
(forall b. Data b => b -> b) -> SourceExt -> SourceExt
forall a.
Typeable @Type a
-> (forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable @(Type -> Type) t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable @(Type -> Type -> Type) 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 :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> SourceExt -> u
forall u. (forall d. Data d => d -> u) -> SourceExt -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SourceExt -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SourceExt -> r
forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> SourceExt -> m SourceExt
forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SourceExt -> m SourceExt
forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SourceExt
forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SourceExt -> c SourceExt
forall (t :: Type -> Type) (c :: Type -> Type).
Typeable @(Type -> Type) t =>
(forall d. Data d => c (t d)) -> Maybe (c SourceExt)
forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable @(Type -> Type -> Type) t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SourceExt)
gmapMo :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SourceExt -> m SourceExt
$cgmapMo :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SourceExt -> m SourceExt
gmapMp :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SourceExt -> m SourceExt
$cgmapMp :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SourceExt -> m SourceExt
gmapM :: forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> SourceExt -> m SourceExt
$cgmapM :: forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> SourceExt -> m SourceExt
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SourceExt -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SourceExt -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> SourceExt -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> SourceExt -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SourceExt -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SourceExt -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SourceExt -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SourceExt -> r
gmapT :: (forall b. Data b => b -> b) -> SourceExt -> SourceExt
$cgmapT :: (forall b. Data b => b -> b) -> SourceExt -> SourceExt
dataCast2 :: forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable @(Type -> Type -> Type) t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SourceExt)
$cdataCast2 :: forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable @(Type -> Type -> Type) t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SourceExt)
dataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
Typeable @(Type -> Type) t =>
(forall d. Data d => c (t d)) -> Maybe (c SourceExt)
$cdataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
Typeable @(Type -> Type) t =>
(forall d. Data d => c (t d)) -> Maybe (c SourceExt)
dataTypeOf :: SourceExt -> DataType
$cdataTypeOf :: SourceExt -> DataType
toConstr :: SourceExt -> Constr
$ctoConstr :: SourceExt -> Constr
gunfold :: forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SourceExt
$cgunfold :: forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SourceExt
gfoldl :: forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SourceExt -> c SourceExt
$cgfoldl :: forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SourceExt -> c SourceExt
Data, forall x. Rep SourceExt x -> SourceExt
forall x. SourceExt -> Rep SourceExt x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SourceExt x -> SourceExt
$cfrom :: forall x. SourceExt -> Rep SourceExt x
Generic)
  deriving anyclass ([SourceExt] -> Encoding
[SourceExt] -> Value
SourceExt -> Encoding
SourceExt -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [SourceExt] -> Encoding
$ctoEncodingList :: [SourceExt] -> Encoding
toJSONList :: [SourceExt] -> Value
$ctoJSONList :: [SourceExt] -> Value
toEncoding :: SourceExt -> Encoding
$ctoEncoding :: SourceExt -> Encoding
toJSON :: SourceExt -> Value
$ctoJSON :: SourceExt -> Value
ToJSON)

data FileType a where
  LMLType :: LML -> FileType SourceExt
  Yaml :: FileType SourceExt
  HeistTpl :: FileType SourceExt
  -- | `AnyExt` has no *known* (at compile time) extension. It is used as a
  -- "catch all" type to capture files using an arbitrary.
  AnyExt :: FileType SourceExt
  Html :: FileType ()
  Folder :: FileType ()
  deriving stock (Typeable)

deriving stock instance Eq a => Eq (FileType a)

deriving stock instance Ord a => Ord (FileType a)

{- | A lightweight markup language

 https://en.wikipedia.org/wiki/Lightweight_markup_language

 This type exists simply because we may support more formats (eg: org-mode) in
 the future.
-}
data LML = Md | Org
  deriving stock (forall x. Rep LML x -> LML
forall x. LML -> Rep LML x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep LML x -> LML
$cfrom :: forall x. LML -> Rep LML x
Generic, LML -> LML -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LML -> LML -> Bool
$c/= :: LML -> LML -> Bool
== :: LML -> LML -> Bool
$c== :: LML -> LML -> Bool
Eq, Eq LML
LML -> LML -> Bool
LML -> LML -> Ordering
LML -> LML -> LML
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
min :: LML -> LML -> LML
$cmin :: LML -> LML -> LML
max :: LML -> LML -> LML
$cmax :: LML -> LML -> LML
>= :: LML -> LML -> Bool
$c>= :: LML -> LML -> Bool
> :: LML -> LML -> Bool
$c> :: LML -> LML -> Bool
<= :: LML -> LML -> Bool
$c<= :: LML -> LML -> Bool
< :: LML -> LML -> Bool
$c< :: LML -> LML -> Bool
compare :: LML -> LML -> Ordering
$ccompare :: LML -> LML -> Ordering
Ord, Typeable, Typeable @Type LML
LML -> DataType
LML -> Constr
(forall b. Data b => b -> b) -> LML -> LML
forall a.
Typeable @Type a
-> (forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable @(Type -> Type) t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable @(Type -> Type -> Type) 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 :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> LML -> u
forall u. (forall d. Data d => d -> u) -> LML -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> LML -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> LML -> r
forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> LML -> m LML
forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LML -> m LML
forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LML
forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LML -> c LML
forall (t :: Type -> Type) (c :: Type -> Type).
Typeable @(Type -> Type) t =>
(forall d. Data d => c (t d)) -> Maybe (c LML)
forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable @(Type -> Type -> Type) t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LML)
gmapMo :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LML -> m LML
$cgmapMo :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LML -> m LML
gmapMp :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LML -> m LML
$cgmapMp :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LML -> m LML
gmapM :: forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> LML -> m LML
$cgmapM :: forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> LML -> m LML
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> LML -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> LML -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> LML -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> LML -> [u]
gmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> LML -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> LML -> r
gmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> LML -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> LML -> r
gmapT :: (forall b. Data b => b -> b) -> LML -> LML
$cgmapT :: (forall b. Data b => b -> b) -> LML -> LML
dataCast2 :: forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable @(Type -> Type -> Type) t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LML)
$cdataCast2 :: forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable @(Type -> Type -> Type) t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LML)
dataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
Typeable @(Type -> Type) t =>
(forall d. Data d => c (t d)) -> Maybe (c LML)
$cdataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
Typeable @(Type -> Type) t =>
(forall d. Data d => c (t d)) -> Maybe (c LML)
dataTypeOf :: LML -> DataType
$cdataTypeOf :: LML -> DataType
toConstr :: LML -> Constr
$ctoConstr :: LML -> Constr
gunfold :: forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LML
$cgunfold :: forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LML
gfoldl :: forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LML -> c LML
$cgfoldl :: forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LML -> c LML
Data, Int -> LML
LML -> Int
LML -> [LML]
LML -> LML
LML -> LML -> [LML]
LML -> LML -> LML -> [LML]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: LML -> LML -> LML -> [LML]
$cenumFromThenTo :: LML -> LML -> LML -> [LML]
enumFromTo :: LML -> LML -> [LML]
$cenumFromTo :: LML -> LML -> [LML]
enumFromThen :: LML -> LML -> [LML]
$cenumFromThen :: LML -> LML -> [LML]
enumFrom :: LML -> [LML]
$cenumFrom :: LML -> [LML]
fromEnum :: LML -> Int
$cfromEnum :: LML -> Int
toEnum :: Int -> LML
$ctoEnum :: Int -> LML
pred :: LML -> LML
$cpred :: LML -> LML
succ :: LML -> LML
$csucc :: LML -> LML
Enum, LML
forall a. a -> a -> Bounded a
maxBound :: LML
$cmaxBound :: LML
minBound :: LML
$cminBound :: LML
Bounded)
  deriving anyclass ([LML] -> Encoding
[LML] -> Value
LML -> Encoding
LML -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [LML] -> Encoding
$ctoEncodingList :: [LML] -> Encoding
toJSONList :: [LML] -> Value
$ctoJSONList :: [LML] -> Value
toEncoding :: LML -> Encoding
$ctoEncoding :: LML -> Encoding
toJSON :: LML -> Value
$ctoJSON :: LML -> Value
ToJSON)

{- | The `HasExt` class's responsibility is to allow dealing with basepath sans
 extension (and vice-versa).
-}
class HasExt (ext :: FileType a) where
  fileType :: FileType a

  -- | Return the filepath with the known extension.
  withExt :: FilePath -> FilePath

  -- | Return the filepath without the known extension.
  withoutKnownExt :: FilePath -> Maybe FilePath

instance HasExt ('LMLType 'Md) where
  fileType :: FileType SourceExt
fileType = LML -> FileType SourceExt
LMLType LML
Md
  withExt :: ShowS
withExt = forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> ShowS
FP.addExtension String
".md"
  withoutKnownExt :: String -> Maybe String
withoutKnownExt = forall (m :: Type -> Type).
(Monad m, Alternative m) =>
String -> String -> m String
fpWithoutExt String
".md"

instance HasExt ('LMLType 'Org) where
  fileType :: FileType SourceExt
fileType = LML -> FileType SourceExt
LMLType LML
Org
  withExt :: ShowS
withExt = forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> ShowS
FP.addExtension String
".org"
  withoutKnownExt :: String -> Maybe String
withoutKnownExt = forall (m :: Type -> Type).
(Monad m, Alternative m) =>
String -> String -> m String
fpWithoutExt String
".org"

instance HasExt 'Yaml where
  fileType :: FileType SourceExt
fileType = FileType SourceExt
Yaml
  withExt :: ShowS
withExt = forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> ShowS
FP.addExtension String
".yaml"
  withoutKnownExt :: String -> Maybe String
withoutKnownExt = forall (m :: Type -> Type).
(Monad m, Alternative m) =>
String -> String -> m String
fpWithoutExt String
".yaml"

instance HasExt 'Html where
  fileType :: FileType ()
fileType = FileType ()
Html
  withExt :: ShowS
withExt = forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> ShowS
FP.addExtension String
".html"
  withoutKnownExt :: String -> Maybe String
withoutKnownExt = forall (m :: Type -> Type).
(Monad m, Alternative m) =>
String -> String -> m String
fpWithoutExt String
".html"

instance HasExt 'HeistTpl where
  fileType :: FileType SourceExt
fileType = FileType SourceExt
HeistTpl
  withExt :: ShowS
withExt = forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> ShowS
FP.addExtension String
".tpl"
  withoutKnownExt :: String -> Maybe String
withoutKnownExt = forall (m :: Type -> Type).
(Monad m, Alternative m) =>
String -> String -> m String
fpWithoutExt String
".tpl"

instance HasExt 'Folder where
  fileType :: FileType ()
fileType = FileType ()
Folder
  withExt :: ShowS
withExt = forall a. a -> a
id
  withoutKnownExt :: String -> Maybe String
withoutKnownExt = forall (f :: Type -> Type) a. Applicative f => a -> f a
pure

{- | The AnyExt instance ignores explicitly dealing with extensions, expecting
 the user to explicitly encode the extension in their value tpye.
-}
instance HasExt 'AnyExt where
  fileType :: FileType SourceExt
fileType = FileType SourceExt
AnyExt
  withExt :: ShowS
withExt = forall a. a -> a
id
  withoutKnownExt :: String -> Maybe String
withoutKnownExt = forall (f :: Type -> Type) a. Applicative f => a -> f a
pure

fpWithoutExt :: (Monad m, Alternative m) => String -> FilePath -> m FilePath
fpWithoutExt :: forall (m :: Type -> Type).
(Monad m, Alternative m) =>
String -> String -> m String
fpWithoutExt String
e String
fp = do
  let (String
base, String
ext) = String -> (String, String)
FP.splitExtension String
fp
  forall (f :: Type -> Type). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ String
ext forall a. Eq a => a -> a -> Bool
== String
e
  forall (f :: Type -> Type) a. Applicative f => a -> f a
pure String
base