data-filepath 2.1.0.1 → 2.1.1.0
raw patch · 2 files changed
+81/−18 lines, 2 filesdep +semigroupsPVP ok
version bump matches the API change (PVP)
Dependencies added: semigroups
API changes (from Hackage documentation)
+ Data.FilePath: basenameSeg :: FilePath a File -> PathSegment
+ Data.FilePath: data PathSegment
+ Data.FilePath: instance Data PathSegment
+ Data.FilePath: instance Eq PathSegment
+ Data.FilePath: instance Semigroup PathSegment
+ Data.FilePath: instance Show PathSegment
+ Data.FilePath: instance Typeable PathSegment
+ Data.FilePath: mkDirPathSeg :: PathSegment -> FilePath Relative Directory
+ Data.FilePath: mkFilePathSeg :: PathSegment -> FilePath Relative File
+ Data.FilePath: mkPathSegment :: String -> Maybe PathSegment
+ Data.FilePath: segQ :: QuasiQuoter
+ Data.FilePath: segString :: PathSegment -> String
Files
- Data/FilePath.hs +72/−14
- data-filepath.cabal +9/−4
Data/FilePath.hs view
@@ -2,17 +2,24 @@ module Data.FilePath ( Path(..) , From(..)+ , PathSegment+ , segString+ , mkPathSegment , FilePath , (</>) , rootPath , relativePath , mkDirPath+ , mkDirPathSeg , mkFilePath+ , mkFilePathSeg , mkRootFilePathBase , mkFullFilePath , dirname , basename+ , basenameSeg , showp+ , segQ , dirpathQ , filepathQ ) where@@ -22,17 +29,49 @@ import Data.Char import Data.List.Split import Data.Maybe (fromJust)+import Data.Semigroup ( Semigroup(..) ) import Language.Haskell.TH import Language.Haskell.TH.Quote import GHC.Types +-- | A PathSegment is any single element of a path...i.e. the stuff between+-- two \'\/\' characters. Valid path segments cannot contain \'\/\' or control+-- characters. PathSegments are also monoids to allow mappending with+-- prefixes/suffixes.+newtype PathSegment = PathSegment { _segString :: String }+ deriving (Eq,Show,Typeable,Data)++instance Semigroup PathSegment where+ (PathSegment a) <> (PathSegment b) = PathSegment $ a <> b++-- For the motivation behind taking the time and characters to write `segString` instead of just exporting `_segString` pls see <https://github.com/maxpow4h/data-filepath/pull/6>++-- |+-- Every `PathSegment` is a valid string+--+segString :: PathSegment -> String+segString = _segString++-- | Smart constructor for valid PathSegments. Valid path segments cannot+-- contain front slashes or control characters.+-- This function performs __all__ the checks up front.+--+-- * Is the string non-empty?+-- * Does the string contain forward slashes or control characters?+--+mkPathSegment :: String -> Maybe PathSegment+mkPathSegment s+ | any (\x -> x == '/' || isControl x) s = Nothing+ | null s = Nothing+ | otherwise = Just $ PathSegment s+ data Path = File | Directory data From = Root | Relative data FilePath (a :: From) (b :: Path) where RootPath :: FilePath Root Directory RelativePath :: FilePath Relative Directory- FilePath :: FilePath a Directory -> String -> FilePath a File- DirectoryPath :: FilePath a Directory -> String -> FilePath a Directory+ FilePath :: FilePath a Directory -> PathSegment -> FilePath a File+ DirectoryPath :: FilePath a Directory -> PathSegment -> FilePath a Directory -- Path API@@ -48,12 +87,26 @@ p </> (DirectoryPath u s) = DirectoryPath (p </> u) s p </> (FilePath u s) = FilePath (p </> u) s +-- | Smart constructor for directories. Valid directories must be valid+-- PathSegments and also cannot be empty strings. mkDirPath :: String -> Maybe (FilePath Relative Directory)-mkDirPath s = DirectoryPath RelativePath `fmap` mkf s+mkDirPath = fmap mkDirPathSeg . mkPathSegment +-- | This function basically defines what the `PathSegment` type is semantically.+-- It is string like thing which you can safely create a path from.+-- See `mkPathSegment`, `mkFilePathSeg`+--+mkDirPathSeg :: PathSegment -> FilePath Relative Directory+mkDirPathSeg = DirectoryPath relativePath++-- | Smart constructor for files. Valid files must be valid PathSegments and+-- also cannot be empty strings. mkFilePath :: String -> Maybe (FilePath Relative File)-mkFilePath s = FilePath RelativePath `fmap` mkf s+mkFilePath = fmap mkFilePathSeg . mkPathSegment +mkFilePathSeg :: PathSegment -> FilePath Relative File+mkFilePathSeg = FilePath relativePath+ mkRootFilePathBase :: String -> Maybe (FilePath Root Directory) mkRootFilePathBase ('/':s) = do ys <- xs@@ -79,33 +132,38 @@ dirname (FilePath dir _) = dir basename :: FilePath a File -> String-basename (FilePath _ bname) = bname+basename (FilePath _ (PathSegment bname)) = bname +basenameSeg :: FilePath a File -> PathSegment+basenameSeg (FilePath _ bname) = bname+ showp :: FilePath a b -> String showp RootPath = "" showp RelativePath = "."-showp (DirectoryPath u s) = showp u ++ "/" ++ s-showp (FilePath u s) = showp u ++ "/" ++ s+showp (DirectoryPath u (PathSegment s)) = showp u ++ "/" ++ s+showp (FilePath u (PathSegment s)) = showp u ++ "/" ++ s -mkf :: String -> Maybe String-mkf "" = Nothing -- an empty string is an invalid file/dir name-mkf s = if any (\x -> x == '/' || isControl x) s- then Nothing- else Just s+-- TODO: could it split the delimiters?+segQ :: QuasiQuoter+segQ = QuasiQuoter qExp qPat (error "path segments are not types") (error "path segments are not decs")+ where+ qExp :: String -> ExpQ+ qExp s = dataToExpQ (const Nothing) (fromJust (mkPathSegment s) :: PathSegment)+ qPat = undefined -- TODO: could it split the delimiters? dirpathQ :: QuasiQuoter dirpathQ = QuasiQuoter qExp qPat (error "dir paths are not types") (error "dir paths are not decs") where qExp :: String -> ExpQ- qExp s = dataToExpQ (const Nothing) (DirectoryPath RelativePath (fromJust (mkf s)) :: FilePath Relative Directory)+ qExp s = dataToExpQ (const Nothing) (fromJust (mkDirPath s) :: FilePath Relative Directory) qPat = undefined filepathQ :: QuasiQuoter filepathQ = QuasiQuoter qExp qPat (error "file paths are not types") (error "file paths are not decs") where qExp :: String -> ExpQ- qExp s = dataToExpQ (const Nothing) (FilePath RelativePath (fromJust (mkf s)) :: FilePath Relative File)+ qExp s = dataToExpQ (const Nothing) (fromJust (mkFilePath s) :: FilePath Relative File) qPat = undefined -- data / typeable
data-filepath.cabal view
@@ -1,5 +1,5 @@ name: data-filepath-version: 2.1.0.1+version: 2.1.1.0 synopsis: A type safe file path data structure description: A type safe file path data structure license: BSD3@@ -19,7 +19,12 @@ location: https://github.com/maxpow4h/data-filepath.git library- exposed-modules: Data.FilePath- other-extensions: CPP, GADTs, DataKinds, KindSignatures, StandaloneDeriving, RankNTypes, DeriveDataTypeable, FlexibleInstances, MagicHash- build-depends: base >=4.6 && <4.9, split >=0.2 && <0.3, template-haskell, ghc-prim+ exposed-modules: Data.FilePath+ other-extensions: CPP, GADTs, DataKinds, KindSignatures, StandaloneDeriving, RankNTypes, DeriveDataTypeable, FlexibleInstances, MagicHash+ build-depends: base >= 4.6 && < 4.9+ , semigroups == 0.16.*+ , split >= 0.2 && < 0.3+ , template-haskell+ , ghc-prim+ default-language: Haskell2010