{-# LANGUAGE ConstraintKinds, RecordWildCards, ScopedTypeVariables #-}
module System.FilePattern(
FilePattern, (?==), match, substitute, arity,
step, step_, Step(..), StepNext(..), matchMany
) where
import Control.Exception.Extra
import Data.Maybe
import Data.Tuple.Extra
import Data.List.Extra
import System.FilePattern.Tree
import System.FilePattern.Core(FilePattern, parsePattern, parsePath, renderPath)
import qualified System.FilePattern.Core as Core
import System.FilePattern.Step
import Prelude
(?==) :: FilePattern -> FilePath -> Bool
?== :: FilePattern -> FilePattern -> Bool
(?==) FilePattern
w = forall a. Maybe a -> Bool
isJust forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePattern -> FilePattern -> Maybe [FilePattern]
match FilePattern
w
match :: FilePattern -> FilePath -> Maybe [String]
match :: FilePattern -> FilePattern -> Maybe [FilePattern]
match FilePattern
w = Pattern -> Path -> Maybe [FilePattern]
Core.match (FilePattern -> Pattern
parsePattern FilePattern
w) forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePattern -> Path
parsePath
arity :: FilePattern -> Int
arity :: FilePattern -> Int
arity = Pattern -> Int
Core.arity forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePattern -> Pattern
parsePattern
substitute :: Partial => FilePattern -> [String] -> FilePath
substitute :: Partial => FilePattern -> [FilePattern] -> FilePattern
substitute FilePattern
w [FilePattern]
xs = forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall a. Partial => FilePattern -> a
error FilePattern
msg) Path -> FilePattern
renderPath forall a b. (a -> b) -> a -> b
$ Pattern -> [FilePattern] -> Maybe Path
Core.substitute (FilePattern -> Pattern
parsePattern FilePattern
w) [FilePattern]
xs
where
msg :: FilePattern
msg = FilePattern
"Failed substitute, patterns of different arity. Pattern " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> FilePattern
show FilePattern
w forall a. [a] -> [a] -> [a]
++
FilePattern
" expects " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> FilePattern
show (FilePattern -> Int
arity FilePattern
w) forall a. [a] -> [a] -> [a]
++ FilePattern
" elements, but got " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> FilePattern
show (forall (t :: * -> *) a. Foldable t => t a -> Int
length [FilePattern]
xs) forall a. [a] -> [a] -> [a]
++
FilePattern
" namely " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> FilePattern
show [FilePattern]
xs forall a. [a] -> [a] -> [a]
++ FilePattern
"."
matchMany :: [(a, FilePattern)] -> [(b, FilePath)] -> [(a, b, [String])]
matchMany :: forall a b.
[(a, FilePattern)] -> [(b, FilePattern)] -> [(a, b, [FilePattern])]
matchMany [] = forall a b. a -> b -> a
const []
matchMany [(a, FilePattern)]
pats = \[(b, FilePattern)]
files -> if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(b, FilePattern)]
files then [] else forall {a} {b}.
Step a -> Tree FilePattern b -> [(a, b, [FilePattern])]
f Step a
spats forall a b. (a -> b) -> a -> b
$ forall k v. Ord k => [(v, [k])] -> Tree k v
makeTree forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall b b' a. (b -> b') -> (a, b) -> (a, b')
second forall a b. (a -> b) -> a -> b
$ (\(Core.Path [FilePattern]
x) -> [FilePattern]
x) forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePattern -> Path
parsePath) [(b, FilePattern)]
files
where
spats :: Step a
spats = forall a. [(a, FilePattern)] -> Step a
step [(a, FilePattern)]
pats
f :: Step a -> Tree FilePattern b -> [(a, b, [FilePattern])]
f Step{[(a, [FilePattern])]
StepNext
FilePattern -> Step a
stepApply :: forall a. Step a -> FilePattern -> Step a
stepNext :: forall a. Step a -> StepNext
stepDone :: forall a. Step a -> [(a, [FilePattern])]
stepApply :: FilePattern -> Step a
stepNext :: StepNext
stepDone :: [(a, [FilePattern])]
..} (Tree [b]
bs [(FilePattern, Tree FilePattern b)]
xs) = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall a b. (a -> b) -> a -> b
$
[(a
a, b
b, [FilePattern]
ps) | (a
a, [FilePattern]
ps) <- [(a, [FilePattern])]
stepDone, b
b <- [b]
bs] forall a. a -> [a] -> [a]
:
[Step a -> Tree FilePattern b -> [(a, b, [FilePattern])]
f (FilePattern -> Step a
stepApply FilePattern
x) Tree FilePattern b
t | (FilePattern
x, Tree FilePattern b
t) <- [(FilePattern, Tree FilePattern b)]
xs, case StepNext
stepNext of StepOnly [FilePattern]
xs -> FilePattern
x forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [FilePattern]
xs; StepNext
_ -> Bool
True]