Add parseAny friends

This commit is contained in:
Julian Ospald 2020-01-18 18:44:28 +01:00
parent 22ddeeadcc
commit 94077aa6a6
No known key found for this signature in database
GPG Key ID: 511B62C09D50CD28

View File

@ -37,6 +37,7 @@ module HPath
,parseAbs ,parseAbs
,parseFn ,parseFn
,parseRel ,parseRel
,parseAny
-- * Path Conversion -- * Path Conversion
,fromAbs ,fromAbs
,fromRel ,fromRel
@ -56,6 +57,7 @@ module HPath
,abs ,abs
,rel ,rel
,fn ,fn
,any
) )
where where
@ -76,7 +78,7 @@ import HPath.Internal
import Language.Haskell.TH import Language.Haskell.TH
import Language.Haskell.TH.Syntax (Exp(..), Lift(..), lift) import Language.Haskell.TH.Syntax (Exp(..), Lift(..), lift)
import Language.Haskell.TH.Quote (QuasiQuoter(..)) import Language.Haskell.TH.Quote (QuasiQuoter(..))
import Prelude hiding (abs) import Prelude hiding (abs, any)
import System.Posix.FilePath hiding ((</>)) import System.Posix.FilePath hiding ((</>))
@ -227,6 +229,40 @@ parseFn filepath =
else throwM (InvalidFn filepath) else throwM (InvalidFn filepath)
-- | Parses a path, whether it's relative or absolute. Will lose
-- information on whether it's relative or absolute. If you need to know,
-- reparse it.
--
-- Filenames must not contain slashes.
-- Excludes '.' and '..'.
--
-- Throws: 'PathParseException'
--
-- >>> parseAny "/abc" :: Maybe (Path a)
-- Just "/abc"
-- >>> parseAny "..." :: Maybe (Path a)
-- Just "..."
-- >>> parseAny "abc/def" :: Maybe (Path a)
-- Just "abc/def"
-- >>> parseAny "abc/def/." :: Maybe (Path a)
-- Just "abc/def/"
-- >>> parseAny "/abc" :: Maybe (Path a)
-- Just "/abc"
-- >>> parseAny "" :: Maybe (Path a)
-- Nothing
-- >>> parseAny "abc/../foo" :: Maybe (Path a)
-- Nothing
-- >>> parseAny "." :: Maybe (Path a)
-- Nothing
-- >>> parseAny ".." :: Maybe (Path a)
-- Nothing
parseAny :: MonadThrow m => ByteString -> m (Path a)
parseAny filepath = case parseAbs filepath of
Just (MkPath p) -> pure $ (MkPath p)
Nothing -> case parseRel filepath of
Just (MkPath p) -> pure $ (MkPath p)
Nothing -> throwM (InvalidRel filepath)
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Path Conversion -- Path Conversion
@ -244,7 +280,6 @@ fromRel :: RelC r => Path r -> ByteString
fromRel = toFilePath fromRel = toFilePath
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Path Operations -- Path Operations
@ -415,6 +450,9 @@ mkRel = either (error . show) lift . parseRel
mkFN :: ByteString -> Q Exp mkFN :: ByteString -> Q Exp
mkFN = either (error . show) lift . parseFn mkFN = either (error . show) lift . parseFn
mkAny :: ByteString -> Q Exp
mkAny = either (error . show) lift . parseAny
-- | Quasiquote an absolute Path. This accepts Unicode Chars and will encode as UTF-8. -- | Quasiquote an absolute Path. This accepts Unicode Chars and will encode as UTF-8.
-- --
-- >>> [abs|/etc/profile|] :: Path Abs -- >>> [abs|/etc/profile|] :: Path Abs
@ -445,3 +483,15 @@ rel = qq mkRel
-- "\239\131\144" -- "\239\131\144"
fn :: QuasiQuoter fn :: QuasiQuoter
fn = qq mkFN fn = qq mkFN
-- | Quasiquote any path (relative or absolute).
-- This accepts Unicode Chars and will encode as UTF-8.
--
-- >>> [any|/etc/profile|] :: Path a
-- "/etc/profile"
-- >>> [any|etc|] :: Path a
-- "etc"
-- >>> [any||] :: Path a
-- "\239\131\144"
any :: QuasiQuoter
any = qq mkAny