From 94077aa6a65432074d76e7ee122340da92fa5858 Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Sat, 18 Jan 2020 18:44:28 +0100 Subject: [PATCH] Add parseAny friends --- hpath/src/HPath.hs | 54 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/hpath/src/HPath.hs b/hpath/src/HPath.hs index bdbdf5f..844833a 100644 --- a/hpath/src/HPath.hs +++ b/hpath/src/HPath.hs @@ -37,6 +37,7 @@ module HPath ,parseAbs ,parseFn ,parseRel + ,parseAny -- * Path Conversion ,fromAbs ,fromRel @@ -56,6 +57,7 @@ module HPath ,abs ,rel ,fn + ,any ) where @@ -76,7 +78,7 @@ import HPath.Internal import Language.Haskell.TH import Language.Haskell.TH.Syntax (Exp(..), Lift(..), lift) import Language.Haskell.TH.Quote (QuasiQuoter(..)) -import Prelude hiding (abs) +import Prelude hiding (abs, any) import System.Posix.FilePath hiding (()) @@ -227,6 +229,40 @@ parseFn 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 @@ -244,7 +280,6 @@ fromRel :: RelC r => Path r -> ByteString fromRel = toFilePath - -------------------------------------------------------------------------------- -- Path Operations @@ -415,6 +450,9 @@ mkRel = either (error . show) lift . parseRel mkFN :: ByteString -> Q Exp 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. -- -- >>> [abs|/etc/profile|] :: Path Abs @@ -445,3 +483,15 @@ rel = qq mkRel -- "\239\131\144" fn :: QuasiQuoter 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