{-# LANGUAGE ViewPatterns, TupleSections, ScopedTypeVariables, DeriveDataTypeable, PatternGuards, GADTs #-}
module Output.Tags(writeTags, completionTags, applyTags) where
import Data.Bifunctor
import Data.Function
import Data.List.Extra
import Data.Tuple.Extra
import Data.Maybe
import Foreign.Storable.Tuple()
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Data.Vector.Storable as V
import qualified Data.ByteString.Char8 as BS
import Input.Item
import Query
import General.Util
import General.Store
import General.Str
data Packages a where Packages :: Packages (BStr0, V.Vector (TargetId, TargetId)) deriving Typeable
data Modules a where Modules :: Modules (BStr0, V.Vector (TargetId, TargetId)) deriving Typeable
data Categories a where Categories :: Categories (BStr0, Jagged (TargetId, TargetId)) deriving Typeable
data Completions a where Completions :: Completions BStr0 deriving Typeable
writeTags :: StoreWrite -> (PkgName -> Bool) -> (PkgName -> [(String,String)]) -> [(Maybe TargetId, Item)] -> IO ()
writeTags :: StoreWrite
-> (PkgName -> Bool)
-> (PkgName -> [(String, String)])
-> [(Maybe TargetId, Item)]
-> IO ()
writeTags StoreWrite
store PkgName -> Bool
keep PkgName -> [(String, String)]
extra [(Maybe TargetId, Item)]
xs = do
let splitPkg :: [(PkgName, [(Maybe TargetId, Item)])]
splitPkg = [(Maybe TargetId, Item)] -> [(PkgName, [(Maybe TargetId, Item)])]
forall a. [(a, Item)] -> [(PkgName, [(a, Item)])]
splitIPackage [(Maybe TargetId, Item)]
xs
let packages :: [(PkgName, (TargetId, TargetId))]
packages = [(PkgName, [(Maybe TargetId, Item)])]
-> [(PkgName, (TargetId, TargetId))]
forall a.
[(PkgName, [(Maybe TargetId, a)])]
-> [(PkgName, (TargetId, TargetId))]
addRange [(PkgName, [(Maybe TargetId, Item)])]
splitPkg
StoreWrite
-> Packages (BStr0, Vector (TargetId, TargetId))
-> (BStr0, Vector (TargetId, TargetId))
-> IO ()
forall (t :: * -> *) a.
(Typeable (t a), Typeable a, Stored a) =>
StoreWrite -> t a -> a -> IO ()
storeWrite StoreWrite
store Packages (BStr0, Vector (TargetId, TargetId))
Packages ([String] -> BStr0
bstr0Join ([String] -> BStr0) -> [String] -> BStr0
forall a b. (a -> b) -> a -> b
$ ((PkgName, (TargetId, TargetId)) -> String)
-> [(PkgName, (TargetId, TargetId))] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (PkgName -> String
strUnpack (PkgName -> String)
-> ((PkgName, (TargetId, TargetId)) -> PkgName)
-> (PkgName, (TargetId, TargetId))
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PkgName, (TargetId, TargetId)) -> PkgName
forall a b. (a, b) -> a
fst) [(PkgName, (TargetId, TargetId))]
packages, [(TargetId, TargetId)] -> Vector (TargetId, TargetId)
forall a. Storable a => [a] -> Vector a
V.fromList ([(TargetId, TargetId)] -> Vector (TargetId, TargetId))
-> [(TargetId, TargetId)] -> Vector (TargetId, TargetId)
forall a b. (a -> b) -> a -> b
$ ((PkgName, (TargetId, TargetId)) -> (TargetId, TargetId))
-> [(PkgName, (TargetId, TargetId))] -> [(TargetId, TargetId)]
forall a b. (a -> b) -> [a] -> [b]
map (PkgName, (TargetId, TargetId)) -> (TargetId, TargetId)
forall a b. (a, b) -> b
snd [(PkgName, (TargetId, TargetId))]
packages)
let categories :: [(String, [(TargetId, TargetId)])]
categories = ((((Double, (String, String)), String), [(TargetId, TargetId)])
-> (String, [(TargetId, TargetId)]))
-> [(((Double, (String, String)), String), [(TargetId, TargetId)])]
-> [(String, [(TargetId, TargetId)])]
forall a b. (a -> b) -> [a] -> [b]
map ((((Double, (String, String)), String) -> String)
-> ([(TargetId, TargetId)] -> [(TargetId, TargetId)])
-> (((Double, (String, String)), String), [(TargetId, TargetId)])
-> (String, [(TargetId, TargetId)])
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap ((Double, (String, String)), String) -> String
forall a b. (a, b) -> b
snd [(TargetId, TargetId)] -> [(TargetId, TargetId)]
forall a. [a] -> [a]
reverse) ([(((Double, (String, String)), String), [(TargetId, TargetId)])]
-> [(String, [(TargetId, TargetId)])])
-> [(((Double, (String, String)), String), [(TargetId, TargetId)])]
-> [(String, [(TargetId, TargetId)])]
forall a b. (a -> b) -> a -> b
$ Map ((Double, (String, String)), String) [(TargetId, TargetId)]
-> [(((Double, (String, String)), String), [(TargetId, TargetId)])]
forall k a. Map k a -> [(k, a)]
Map.toList (Map ((Double, (String, String)), String) [(TargetId, TargetId)]
-> [(((Double, (String, String)), String),
[(TargetId, TargetId)])])
-> Map ((Double, (String, String)), String) [(TargetId, TargetId)]
-> [(((Double, (String, String)), String), [(TargetId, TargetId)])]
forall a b. (a -> b) -> a -> b
$ ([(TargetId, TargetId)]
-> [(TargetId, TargetId)] -> [(TargetId, TargetId)])
-> [(((Double, (String, String)), String), [(TargetId, TargetId)])]
-> Map ((Double, (String, String)), String) [(TargetId, TargetId)]
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
Map.fromListWith [(TargetId, TargetId)]
-> [(TargetId, TargetId)] -> [(TargetId, TargetId)]
forall a. [a] -> [a] -> [a]
(++)
[((((String, String) -> Double
forall p. Fractional p => (String, String) -> p
weightTag (String, String)
ex, (String -> String) -> (String, String) -> (String, String)
forall a b. (a -> b) -> (a, a) -> (b, b)
both String -> String
lower (String, String)
ex), String -> (String, String) -> String
forall a. [a] -> ([a], [a]) -> [a]
joinPair String
":" (String, String)
ex),[(TargetId, TargetId)
rng]) | (PkgName
p,(TargetId, TargetId)
rng) <- [(PkgName, (TargetId, TargetId))]
packages, (String, String)
ex <- PkgName -> [(String, String)]
extra PkgName
p]
StoreWrite
-> Categories (BStr0, Jagged (TargetId, TargetId))
-> (BStr0, Jagged (TargetId, TargetId))
-> IO ()
forall (t :: * -> *) a.
(Typeable (t a), Typeable a, Stored a) =>
StoreWrite -> t a -> a -> IO ()
storeWrite StoreWrite
store Categories (BStr0, Jagged (TargetId, TargetId))
Categories ([String] -> BStr0
bstr0Join ([String] -> BStr0) -> [String] -> BStr0
forall a b. (a -> b) -> a -> b
$ ((String, [(TargetId, TargetId)]) -> String)
-> [(String, [(TargetId, TargetId)])] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, [(TargetId, TargetId)]) -> String
forall a b. (a, b) -> a
fst [(String, [(TargetId, TargetId)])]
categories, [[(TargetId, TargetId)]] -> Jagged (TargetId, TargetId)
forall a. Storable a => [[a]] -> Jagged a
jaggedFromList ([[(TargetId, TargetId)]] -> Jagged (TargetId, TargetId))
-> [[(TargetId, TargetId)]] -> Jagged (TargetId, TargetId)
forall a b. (a -> b) -> a -> b
$ ((String, [(TargetId, TargetId)]) -> [(TargetId, TargetId)])
-> [(String, [(TargetId, TargetId)])] -> [[(TargetId, TargetId)]]
forall a b. (a -> b) -> [a] -> [b]
map (String, [(TargetId, TargetId)]) -> [(TargetId, TargetId)]
forall a b. (a, b) -> b
snd [(String, [(TargetId, TargetId)])]
categories)
let modules :: [(PkgName, (TargetId, TargetId))]
modules = [(PkgName, [(Maybe TargetId, Item)])]
-> [(PkgName, (TargetId, TargetId))]
forall a.
[(PkgName, [(Maybe TargetId, a)])]
-> [(PkgName, (TargetId, TargetId))]
addRange ([(PkgName, [(Maybe TargetId, Item)])]
-> [(PkgName, (TargetId, TargetId))])
-> [(PkgName, [(Maybe TargetId, Item)])]
-> [(PkgName, (TargetId, TargetId))]
forall a b. (a -> b) -> a -> b
$ ((PkgName, [(Maybe TargetId, Item)])
-> [(PkgName, [(Maybe TargetId, Item)])])
-> [(PkgName, [(Maybe TargetId, Item)])]
-> [(PkgName, [(Maybe TargetId, Item)])]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([(Maybe TargetId, Item)] -> [(PkgName, [(Maybe TargetId, Item)])]
forall a. [(a, Item)] -> [(PkgName, [(a, Item)])]
splitIModule ([(Maybe TargetId, Item)] -> [(PkgName, [(Maybe TargetId, Item)])])
-> ((PkgName, [(Maybe TargetId, Item)])
-> [(Maybe TargetId, Item)])
-> (PkgName, [(Maybe TargetId, Item)])
-> [(PkgName, [(Maybe TargetId, Item)])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PkgName, [(Maybe TargetId, Item)]) -> [(Maybe TargetId, Item)]
forall a b. (a, b) -> b
snd) [(PkgName, [(Maybe TargetId, Item)])]
splitPkg
StoreWrite
-> Modules (BStr0, Vector (TargetId, TargetId))
-> (BStr0, Vector (TargetId, TargetId))
-> IO ()
forall (t :: * -> *) a.
(Typeable (t a), Typeable a, Stored a) =>
StoreWrite -> t a -> a -> IO ()
storeWrite StoreWrite
store Modules (BStr0, Vector (TargetId, TargetId))
Modules ([String] -> BStr0
bstr0Join ([String] -> BStr0) -> [String] -> BStr0
forall a b. (a -> b) -> a -> b
$ ((PkgName, (TargetId, TargetId)) -> String)
-> [(PkgName, (TargetId, TargetId))] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String -> String
lower (String -> String)
-> ((PkgName, (TargetId, TargetId)) -> String)
-> (PkgName, (TargetId, TargetId))
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PkgName -> String
strUnpack (PkgName -> String)
-> ((PkgName, (TargetId, TargetId)) -> PkgName)
-> (PkgName, (TargetId, TargetId))
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PkgName, (TargetId, TargetId)) -> PkgName
forall a b. (a, b) -> a
fst) [(PkgName, (TargetId, TargetId))]
modules, [(TargetId, TargetId)] -> Vector (TargetId, TargetId)
forall a. Storable a => [a] -> Vector a
V.fromList ([(TargetId, TargetId)] -> Vector (TargetId, TargetId))
-> [(TargetId, TargetId)] -> Vector (TargetId, TargetId)
forall a b. (a -> b) -> a -> b
$ ((PkgName, (TargetId, TargetId)) -> (TargetId, TargetId))
-> [(PkgName, (TargetId, TargetId))] -> [(TargetId, TargetId)]
forall a b. (a -> b) -> [a] -> [b]
map (PkgName, (TargetId, TargetId)) -> (TargetId, TargetId)
forall a b. (a, b) -> b
snd [(PkgName, (TargetId, TargetId))]
modules)
StoreWrite -> Completions BStr0 -> BStr0 -> IO ()
forall (t :: * -> *) a.
(Typeable (t a), Typeable a, Stored a) =>
StoreWrite -> t a -> a -> IO ()
storeWrite StoreWrite
store Completions BStr0
Completions (BStr0 -> IO ()) -> BStr0 -> IO ()
forall a b. (a -> b) -> a -> b
$ [String] -> BStr0
bstr0Join ([String] -> BStr0) -> [String] -> BStr0
forall a b. (a -> b) -> a -> b
$
(String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (String
"set:" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf`) (((String, [(TargetId, TargetId)]) -> String)
-> [(String, [(TargetId, TargetId)])] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, [(TargetId, TargetId)]) -> String
forall a b. (a, b) -> a
fst [(String, [(TargetId, TargetId)])]
categories) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++
(String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String
"package:"String -> String -> String
forall a. [a] -> [a] -> [a]
++) ((String -> String) -> [String] -> [String]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn String -> String
lower ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ (PkgName -> String) -> [PkgName] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map PkgName -> String
strUnpack ([PkgName] -> [String]) -> [PkgName] -> [String]
forall a b. (a -> b) -> a -> b
$ [PkgName] -> [PkgName]
forall a. Ord a => [a] -> [a]
nubOrd ([PkgName] -> [PkgName]) -> [PkgName] -> [PkgName]
forall a b. (a -> b) -> a -> b
$ (PkgName -> Bool) -> [PkgName] -> [PkgName]
forall a. (a -> Bool) -> [a] -> [a]
filter PkgName -> Bool
keep ([PkgName] -> [PkgName]) -> [PkgName] -> [PkgName]
forall a b. (a -> b) -> a -> b
$ ((PkgName, (TargetId, TargetId)) -> PkgName)
-> [(PkgName, (TargetId, TargetId))] -> [PkgName]
forall a b. (a -> b) -> [a] -> [b]
map (PkgName, (TargetId, TargetId)) -> PkgName
forall a b. (a, b) -> a
fst [(PkgName, (TargetId, TargetId))]
packages) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++
((String, String) -> String) -> [(String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String -> (String, String) -> String
forall a. [a] -> ([a], [a]) -> [a]
joinPair String
":") (((String, String) -> (Double, (String, String)))
-> [(String, String)] -> [(String, String)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn ((String, String) -> Double
forall p. Fractional p => (String, String) -> p
weightTag ((String, String) -> Double)
-> ((String, String) -> (String, String))
-> (String, String)
-> (Double, (String, String))
forall a b c. (a -> b) -> (a -> c) -> a -> (b, c)
&&& (String -> String) -> (String, String) -> (String, String)
forall a b. (a -> b) -> (a, a) -> (b, b)
both String -> String
lower) ([(String, String)] -> [(String, String)])
-> [(String, String)] -> [(String, String)]
forall a b. (a -> b) -> a -> b
$ [(String, String)] -> [(String, String)]
forall a. Ord a => [a] -> [a]
nubOrd [(String, String)
ex | (PkgName
p,(TargetId, TargetId)
_) <- [(PkgName, (TargetId, TargetId))]
packages, PkgName -> Bool
keep PkgName
p, (String, String)
ex <- PkgName -> [(String, String)]
extra PkgName
p, (String, String) -> String
forall a b. (a, b) -> a
fst (String, String)
ex String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
"set"])
where
addRange :: [(Str, [(Maybe TargetId,a)])] -> [(Str, (TargetId, TargetId))]
addRange :: [(PkgName, [(Maybe TargetId, a)])]
-> [(PkgName, (TargetId, TargetId))]
addRange [(PkgName, [(Maybe TargetId, a)])]
xs = [(PkgName
a, ([TargetId] -> TargetId
forall a. Ord a => [a] -> a
minimum' [TargetId]
is, [TargetId] -> TargetId
forall a. Ord a => [a] -> a
maximum' [TargetId]
is)) | (PkgName
a,[(Maybe TargetId, a)]
b) <- [(PkgName, [(Maybe TargetId, a)])]
xs, let is :: [TargetId]
is = ((Maybe TargetId, a) -> Maybe TargetId)
-> [(Maybe TargetId, a)] -> [TargetId]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (Maybe TargetId, a) -> Maybe TargetId
forall a b. (a, b) -> a
fst [(Maybe TargetId, a)]
b, Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ PkgName -> Bool
strNull PkgName
a, [TargetId]
is [TargetId] -> [TargetId] -> Bool
forall a. Eq a => a -> a -> Bool
/= []]
weightTag :: (String, String) -> p
weightTag (String
"set",String
x) = p -> Maybe p -> p
forall a. a -> Maybe a -> a
fromMaybe p
0.9 (Maybe p -> p) -> Maybe p -> p
forall a b. (a -> b) -> a -> b
$ String -> [(String, p)] -> Maybe p
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
x [(String
"stackage",p
0.0),(String
"haskell-platform",p
0.1)]
weightTag (String
"package",String
x) = p
1
weightTag (String
"category",String
x) = p
2
weightTag (String
"license",String
x) = p
3
weightTag (String, String)
_ = p
4
completionTags :: StoreRead -> [String]
completionTags :: StoreRead -> [String]
completionTags StoreRead
store = (BStr0 -> String) -> [BStr0] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map BStr0 -> String
BS.unpack ([BStr0] -> [String]) -> [BStr0] -> [String]
forall a b. (a -> b) -> a -> b
$ BStr0 -> [BStr0]
bstr0Split (BStr0 -> [BStr0]) -> BStr0 -> [BStr0]
forall a b. (a -> b) -> a -> b
$ StoreRead -> Completions BStr0 -> BStr0
forall (t :: * -> *) a.
(Typeable (t a), Typeable a, Stored a) =>
StoreRead -> t a -> a
storeRead StoreRead
store Completions BStr0
Completions
data Tag = IsExact | IsPackage | IsModule | EqPackage String | EqModule String | EqCategory String String deriving Tag -> Tag -> Bool
(Tag -> Tag -> Bool) -> (Tag -> Tag -> Bool) -> Eq Tag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Tag -> Tag -> Bool
$c/= :: Tag -> Tag -> Bool
== :: Tag -> Tag -> Bool
$c== :: Tag -> Tag -> Bool
Eq
parseTag :: String -> String -> Maybe Tag
parseTag :: String -> String -> Maybe Tag
parseTag String
k String
v
| String
k String -> String -> Bool
~~ String
"is" = case () of
()
_ | String
v String -> String -> Bool
~~ String
"exact" -> Tag -> Maybe Tag
forall a. a -> Maybe a
Just Tag
IsExact
| String
v String -> String -> Bool
~~ String
"package" -> Tag -> Maybe Tag
forall a. a -> Maybe a
Just Tag
IsPackage
| String
v String -> String -> Bool
~~ String
"module" -> Tag -> Maybe Tag
forall a. a -> Maybe a
Just Tag
IsModule
| Bool
otherwise -> Maybe Tag
forall a. Maybe a
Nothing
| String
k String -> String -> Bool
~~ String
"package" = if String
v String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"" then Maybe Tag
forall a. Maybe a
Nothing else Tag -> Maybe Tag
forall a. a -> Maybe a
Just (Tag -> Maybe Tag) -> Tag -> Maybe Tag
forall a b. (a -> b) -> a -> b
$ String -> Tag
EqPackage String
v
| String
k String -> String -> Bool
~~ String
"module" = if String
v String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"" then Maybe Tag
forall a. Maybe a
Nothing else Tag -> Maybe Tag
forall a. a -> Maybe a
Just (Tag -> Maybe Tag) -> Tag -> Maybe Tag
forall a b. (a -> b) -> a -> b
$ String -> Tag
EqModule String
v
| String
v String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
"" = Tag -> Maybe Tag
forall a. a -> Maybe a
Just (Tag -> Maybe Tag) -> Tag -> Maybe Tag
forall a b. (a -> b) -> a -> b
$ String -> String -> Tag
EqCategory String
k String
v
| Bool
otherwise = Maybe Tag
forall a. Maybe a
Nothing
where
String
x ~~ :: String -> String -> Bool
~~ String
lit = String
x String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
"" Bool -> Bool -> Bool
&& String -> String
lower String
x String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
lit
showTag :: Tag -> (String, String)
showTag :: Tag -> (String, String)
showTag Tag
IsExact = (String
"is",String
"exact")
showTag Tag
IsPackage = (String
"is",String
"package")
showTag Tag
IsModule = (String
"is",String
"module")
showTag (EqPackage String
x) = (String
"package",String
x)
showTag (EqModule String
x) = (String
"module",String
x)
showTag (EqCategory String
k String
v) = (String
k,String
v)
resolveTag :: StoreRead -> Tag -> (Tag, Maybe [(TargetId,TargetId)])
resolveTag :: StoreRead -> Tag -> (Tag, Maybe [(TargetId, TargetId)])
resolveTag StoreRead
store Tag
x = case Tag
x of
Tag
IsExact -> (Tag
IsExact, Maybe [(TargetId, TargetId)]
forall a. Maybe a
Nothing)
Tag
IsPackage -> (Tag
IsPackage, [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
forall a. a -> Maybe a
Just ([(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)])
-> [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
forall a b. (a -> b) -> a -> b
$ ((TargetId, TargetId) -> (TargetId, TargetId))
-> [(TargetId, TargetId)] -> [(TargetId, TargetId)]
forall a b. (a -> b) -> [a] -> [b]
map (TargetId -> (TargetId, TargetId)
forall a. a -> (a, a)
dupe (TargetId -> (TargetId, TargetId))
-> ((TargetId, TargetId) -> TargetId)
-> (TargetId, TargetId)
-> (TargetId, TargetId)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TargetId, TargetId) -> TargetId
forall a b. (a, b) -> a
fst) ([(TargetId, TargetId)] -> [(TargetId, TargetId)])
-> [(TargetId, TargetId)] -> [(TargetId, TargetId)]
forall a b. (a -> b) -> a -> b
$ Vector (TargetId, TargetId) -> [(TargetId, TargetId)]
forall a. Storable a => Vector a -> [a]
V.toList Vector (TargetId, TargetId)
packageIds)
Tag
IsModule -> (Tag
IsModule, [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
forall a. a -> Maybe a
Just ([(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)])
-> [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
forall a b. (a -> b) -> a -> b
$ ((TargetId, TargetId) -> (TargetId, TargetId))
-> [(TargetId, TargetId)] -> [(TargetId, TargetId)]
forall a b. (a -> b) -> [a] -> [b]
map (TargetId -> (TargetId, TargetId)
forall a. a -> (a, a)
dupe (TargetId -> (TargetId, TargetId))
-> ((TargetId, TargetId) -> TargetId)
-> (TargetId, TargetId)
-> (TargetId, TargetId)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TargetId, TargetId) -> TargetId
forall a b. (a, b) -> a
fst) ([(TargetId, TargetId)] -> [(TargetId, TargetId)])
-> [(TargetId, TargetId)] -> [(TargetId, TargetId)]
forall a b. (a -> b) -> a -> b
$ Vector (TargetId, TargetId) -> [(TargetId, TargetId)]
forall a. Storable a => Vector a -> [a]
V.toList Vector (TargetId, TargetId)
moduleIds)
EqPackage orig :: String
orig@(String -> BStr0
BS.pack -> BStr0
val)
| res :: [(Int, (Int, BStr0))]
res@((Int, (Int, BStr0))
_:[(Int, (Int, BStr0))]
_) <- [(BStr0 -> Int
BS.length BStr0
x, (Int
i,BStr0
x)) | (Int
i,BStr0
x) <- Int -> [BStr0] -> [(Int, BStr0)]
forall a b. Enum a => a -> [b] -> [(a, b)]
zipFrom Int
0 ([BStr0] -> [(Int, BStr0)]) -> [BStr0] -> [(Int, BStr0)]
forall a b. (a -> b) -> a -> b
$ BStr0 -> [BStr0]
bstr0Split BStr0
packageNames, BStr0
val BStr0 -> BStr0 -> Bool
`BS.isPrefixOf` BStr0
x]
-> let (Int
i,BStr0
x) = (Int, (Int, BStr0)) -> (Int, BStr0)
forall a b. (a, b) -> b
snd ((Int, (Int, BStr0)) -> (Int, BStr0))
-> (Int, (Int, BStr0)) -> (Int, BStr0)
forall a b. (a -> b) -> a -> b
$ ((Int, (Int, BStr0)) -> (Int, (Int, BStr0)) -> Ordering)
-> [(Int, (Int, BStr0))] -> (Int, (Int, BStr0))
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
minimumBy (Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Int -> Int -> Ordering)
-> ((Int, (Int, BStr0)) -> Int)
-> (Int, (Int, BStr0))
-> (Int, (Int, BStr0))
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (Int, (Int, BStr0)) -> Int
forall a b. (a, b) -> a
fst) [(Int, (Int, BStr0))]
res in (String -> Tag
EqPackage (String -> Tag) -> String -> Tag
forall a b. (a -> b) -> a -> b
$ BStr0 -> String
BS.unpack BStr0
x, [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
forall a. a -> Maybe a
Just [Vector (TargetId, TargetId)
packageIds Vector (TargetId, TargetId) -> Int -> (TargetId, TargetId)
forall a. Storable a => Vector a -> Int -> a
V.! Int
i])
| Bool
otherwise -> (String -> Tag
EqPackage String
orig , [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
forall a. a -> Maybe a
Just [])
EqModule String
x -> (String -> Tag
EqModule String
x, [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
forall a. a -> Maybe a
Just ([(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)])
-> [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
forall a b. (a -> b) -> a -> b
$ (Int -> (TargetId, TargetId)) -> [Int] -> [(TargetId, TargetId)]
forall a b. (a -> b) -> [a] -> [b]
map (Vector (TargetId, TargetId)
moduleIds Vector (TargetId, TargetId) -> Int -> (TargetId, TargetId)
forall a. Storable a => Vector a -> Int -> a
V.!) ([Int] -> [(TargetId, TargetId)])
-> [Int] -> [(TargetId, TargetId)]
forall a b. (a -> b) -> a -> b
$ (BStr0 -> Bool) -> [BStr0] -> [Int]
forall a. (a -> Bool) -> [a] -> [Int]
findIndices (String -> BStr0 -> Bool
eqModule (String -> BStr0 -> Bool) -> String -> BStr0 -> Bool
forall a b. (a -> b) -> a -> b
$ String -> String
lower String
x) ([BStr0] -> [Int]) -> [BStr0] -> [Int]
forall a b. (a -> b) -> a -> b
$ BStr0 -> [BStr0]
bstr0Split BStr0
moduleNames)
EqCategory String
cat String
val -> (String -> String -> Tag
EqCategory String
cat String
val, [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
forall a. a -> Maybe a
Just ([(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)])
-> [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
forall a b. (a -> b) -> a -> b
$ [[(TargetId, TargetId)]] -> [(TargetId, TargetId)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ Vector (TargetId, TargetId) -> [(TargetId, TargetId)]
forall a. Storable a => Vector a -> [a]
V.toList (Vector (TargetId, TargetId) -> [(TargetId, TargetId)])
-> Vector (TargetId, TargetId) -> [(TargetId, TargetId)]
forall a b. (a -> b) -> a -> b
$ Jagged (TargetId, TargetId) -> Int -> Vector (TargetId, TargetId)
forall a. Storable a => Jagged a -> Int -> Vector a
jaggedAsk Jagged (TargetId, TargetId)
categoryIds Int
i
| Int
i <- BStr0 -> [BStr0] -> [Int]
forall a. Eq a => a -> [a] -> [Int]
elemIndices (String -> BStr0
BS.pack (String
cat String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
val)) ([BStr0] -> [Int]) -> [BStr0] -> [Int]
forall a b. (a -> b) -> a -> b
$ BStr0 -> [BStr0]
bstr0Split BStr0
categoryNames])
where
eqModule :: String -> BStr0 -> Bool
eqModule String
x | Just String
x <- String -> String -> Maybe String
forall a. Eq a => [a] -> [a] -> Maybe [a]
stripPrefix String
"." String
x, Just String
x <- String -> String -> Maybe String
forall a. Eq a => [a] -> [a] -> Maybe [a]
stripSuffix String
"." String
x = BStr0 -> BStr0 -> Bool
forall a. Eq a => a -> a -> Bool
(==) (String -> BStr0
BS.pack String
x)
| Just String
x <- String -> String -> Maybe String
forall a. Eq a => [a] -> [a] -> Maybe [a]
stripPrefix String
"." String
x = BStr0 -> BStr0 -> Bool
BS.isPrefixOf (BStr0 -> BStr0 -> Bool) -> BStr0 -> BStr0 -> Bool
forall a b. (a -> b) -> a -> b
$ String -> BStr0
BS.pack String
x
| Bool
otherwise = let y :: BStr0
y = String -> BStr0
BS.pack String
x; y2 :: BStr0
y2 = String -> BStr0
BS.pack (Char
'.'Char -> String -> String
forall a. a -> [a] -> [a]
:String
x)
in \BStr0
v -> BStr0
y BStr0 -> BStr0 -> Bool
`BS.isPrefixOf` BStr0
v Bool -> Bool -> Bool
|| BStr0
y2 BStr0 -> BStr0 -> Bool
`BS.isInfixOf` BStr0
v
(BStr0
packageNames, Vector (TargetId, TargetId)
packageIds) = StoreRead
-> Packages (BStr0, Vector (TargetId, TargetId))
-> (BStr0, Vector (TargetId, TargetId))
forall (t :: * -> *) a.
(Typeable (t a), Typeable a, Stored a) =>
StoreRead -> t a -> a
storeRead StoreRead
store Packages (BStr0, Vector (TargetId, TargetId))
Packages
(BStr0
categoryNames, Jagged (TargetId, TargetId)
categoryIds) = StoreRead
-> Categories (BStr0, Jagged (TargetId, TargetId))
-> (BStr0, Jagged (TargetId, TargetId))
forall (t :: * -> *) a.
(Typeable (t a), Typeable a, Stored a) =>
StoreRead -> t a -> a
storeRead StoreRead
store Categories (BStr0, Jagged (TargetId, TargetId))
Categories
(BStr0
moduleNames, Vector (TargetId, TargetId)
moduleIds) = StoreRead
-> Modules (BStr0, Vector (TargetId, TargetId))
-> (BStr0, Vector (TargetId, TargetId))
forall (t :: * -> *) a.
(Typeable (t a), Typeable a, Stored a) =>
StoreRead -> t a -> a
storeRead StoreRead
store Modules (BStr0, Vector (TargetId, TargetId))
Modules
applyTags :: StoreRead -> [Query] -> ([Query], Bool, TargetId -> Bool, [TargetId])
applyTags :: StoreRead
-> [Query] -> ([Query], Bool, TargetId -> Bool, [TargetId])
applyTags StoreRead
store [Query]
qs = ([Query]
qs2, Bool
exact, TargetId -> Bool
filt, StoreRead -> [Query] -> [TargetId]
searchTags StoreRead
store [Query]
qs)
where ([Query]
qs2, Bool
exact, TargetId -> Bool
filt) = StoreRead -> [Query] -> ([Query], Bool, TargetId -> Bool)
filterTags StoreRead
store [Query]
qs
filterTags :: StoreRead -> [Query] -> ([Query], Bool, TargetId -> Bool)
filterTags :: StoreRead -> [Query] -> ([Query], Bool, TargetId -> Bool)
filterTags StoreRead
ts [Query]
qs = ((Query -> Query) -> [Query] -> [Query]
forall a b. (a -> b) -> [a] -> [b]
map Query -> Query
redo [Query]
qs, Bool
exact, \TargetId
i -> ((TargetId -> Bool) -> Bool) -> [TargetId -> Bool] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ((TargetId -> Bool) -> TargetId -> Bool
forall a b. (a -> b) -> a -> b
$ TargetId
i) [TargetId -> Bool]
fs)
where fs :: [TargetId -> Bool]
fs = ((String, [Query]) -> TargetId -> Bool)
-> [(String, [Query])] -> [TargetId -> Bool]
forall a b. (a -> b) -> [a] -> [b]
map (StoreRead -> [Query] -> TargetId -> Bool
filterTags2 StoreRead
ts ([Query] -> TargetId -> Bool)
-> ((String, [Query]) -> [Query])
-> (String, [Query])
-> TargetId
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String, [Query]) -> [Query]
forall a b. (a, b) -> b
snd) ([(String, [Query])] -> [TargetId -> Bool])
-> [(String, [Query])] -> [TargetId -> Bool]
forall a b. (a -> b) -> a -> b
$ [(String, Query)] -> [(String, [Query])]
forall k v. Ord k => [(k, v)] -> [(k, [v])]
groupSort ([(String, Query)] -> [(String, [Query])])
-> [(String, Query)] -> [(String, [Query])]
forall a b. (a -> b) -> a -> b
$ (Query -> (String, Query)) -> [Query] -> [(String, Query)]
forall a b. (a -> b) -> [a] -> [b]
map (Query -> String
scopeCategory (Query -> String) -> (Query -> Query) -> Query -> (String, Query)
forall a b c. (a -> b) -> (a -> c) -> a -> (b, c)
&&& Query -> Query
forall a. a -> a
id) ([Query] -> [(String, Query)]) -> [Query] -> [(String, Query)]
forall a b. (a -> b) -> a -> b
$ (Query -> Bool) -> [Query] -> [Query]
forall a. (a -> Bool) -> [a] -> [a]
filter Query -> Bool
isQueryScope [Query]
qs
exact :: Bool
exact = Tag -> Maybe Tag
forall a. a -> Maybe a
Just Tag
IsExact Maybe Tag -> [Maybe Tag] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String -> String -> Maybe Tag
parseTag String
a String
b | QueryScope Bool
True String
a String
b <- [Query]
qs]
redo :: Query -> Query
redo (QueryScope Bool
sense String
cat String
val)
| Just (String
k,String
v) <- (Tag -> (String, String)) -> Maybe Tag -> Maybe (String, String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Tag -> (String, String)
showTag (Tag -> (String, String))
-> (Tag -> Tag) -> Tag -> (String, String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tag, Maybe [(TargetId, TargetId)]) -> Tag
forall a b. (a, b) -> a
fst ((Tag, Maybe [(TargetId, TargetId)]) -> Tag)
-> (Tag -> (Tag, Maybe [(TargetId, TargetId)])) -> Tag -> Tag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StoreRead -> Tag -> (Tag, Maybe [(TargetId, TargetId)])
resolveTag StoreRead
ts) (Maybe Tag -> Maybe (String, String))
-> Maybe Tag -> Maybe (String, String)
forall a b. (a -> b) -> a -> b
$ String -> String -> Maybe Tag
parseTag String
cat String
val = Bool -> String -> String -> Query
QueryScope Bool
sense String
k String
v
| Bool
otherwise = String -> Query
QueryNone (String -> Query) -> String -> Query
forall a b. (a -> b) -> a -> b
$ [Char
'-' | Bool -> Bool
not Bool
sense] String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
cat String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
val
redo Query
q = Query
q
filterTags2 :: StoreRead -> [Query] -> TargetId -> Bool
filterTags2 StoreRead
ts [Query]
qs = \TargetId
i -> Bool -> Bool
not (TargetId -> Bool
negq TargetId
i) Bool -> Bool -> Bool
&& (Bool
noPosRestrict Bool -> Bool -> Bool
|| TargetId -> Bool
posq TargetId
i)
where (TargetId -> Bool
posq,TargetId -> Bool
negq) = ([(TargetId, TargetId)] -> TargetId -> Bool)
-> ([(TargetId, TargetId)], [(TargetId, TargetId)])
-> (TargetId -> Bool, TargetId -> Bool)
forall a b. (a -> b) -> (a, a) -> (b, b)
both [(TargetId, TargetId)] -> TargetId -> Bool
forall a. Ix a => [(a, a)] -> a -> Bool
inRanges ([(TargetId, TargetId)]
pos,[(TargetId, TargetId)]
neg)
([(TargetId, TargetId)]
pos, [(TargetId, TargetId)]
neg) = ([(Bool, [(TargetId, TargetId)])] -> [(TargetId, TargetId)])
-> ([(Bool, [(TargetId, TargetId)])],
[(Bool, [(TargetId, TargetId)])])
-> ([(TargetId, TargetId)], [(TargetId, TargetId)])
forall a b. (a -> b) -> (a, a) -> (b, b)
both (((Bool, [(TargetId, TargetId)]) -> [(TargetId, TargetId)])
-> [(Bool, [(TargetId, TargetId)])] -> [(TargetId, TargetId)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Bool, [(TargetId, TargetId)]) -> [(TargetId, TargetId)]
forall a b. (a, b) -> b
snd) (([(Bool, [(TargetId, TargetId)])],
[(Bool, [(TargetId, TargetId)])])
-> ([(TargetId, TargetId)], [(TargetId, TargetId)]))
-> ([(Bool, [(TargetId, TargetId)])],
[(Bool, [(TargetId, TargetId)])])
-> ([(TargetId, TargetId)], [(TargetId, TargetId)])
forall a b. (a -> b) -> a -> b
$ ((Bool, [(TargetId, TargetId)]) -> Bool)
-> [(Bool, [(TargetId, TargetId)])]
-> ([(Bool, [(TargetId, TargetId)])],
[(Bool, [(TargetId, TargetId)])])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (Bool, [(TargetId, TargetId)]) -> Bool
forall a b. (a, b) -> a
fst [(Bool, [(TargetId, TargetId)])]
xs
xs :: [(Bool, [(TargetId, TargetId)])]
xs = [Maybe (Bool, [(TargetId, TargetId)])]
-> [(Bool, [(TargetId, TargetId)])]
forall a. [Maybe a] -> [a]
catMaybes [Maybe (Bool, [(TargetId, TargetId)])]
restrictions
noPosRestrict :: Bool
noPosRestrict = (Maybe (Bool, [(TargetId, TargetId)]) -> Bool)
-> [Maybe (Bool, [(TargetId, TargetId)])] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Maybe (Bool, [(TargetId, TargetId)]) -> Bool
forall b. Maybe (Bool, b) -> Bool
pred [Maybe (Bool, [(TargetId, TargetId)])]
restrictions
restrictions :: [Maybe (Bool, [(TargetId, TargetId)])]
restrictions = (Query -> Maybe (Bool, [(TargetId, TargetId)]))
-> [Query] -> [Maybe (Bool, [(TargetId, TargetId)])]
forall a b. (a -> b) -> [a] -> [b]
map Query -> Maybe (Bool, [(TargetId, TargetId)])
getRestriction [Query]
qs
pred :: Maybe (Bool, b) -> Bool
pred Maybe (Bool, b)
Nothing = Bool
True
pred (Just (Bool
sense, b
_)) = Bool -> Bool
not Bool
sense
getRestriction :: Query -> Maybe (Bool,[(TargetId, TargetId)])
getRestriction :: Query -> Maybe (Bool, [(TargetId, TargetId)])
getRestriction (QueryScope Bool
sense String
cat String
val) = do
Tag
tag <- String -> String -> Maybe Tag
parseTag String
cat String
val
[(TargetId, TargetId)]
ranges <- (Tag, Maybe [(TargetId, TargetId)]) -> Maybe [(TargetId, TargetId)]
forall a b. (a, b) -> b
snd ((Tag, Maybe [(TargetId, TargetId)])
-> Maybe [(TargetId, TargetId)])
-> (Tag, Maybe [(TargetId, TargetId)])
-> Maybe [(TargetId, TargetId)]
forall a b. (a -> b) -> a -> b
$ StoreRead -> Tag -> (Tag, Maybe [(TargetId, TargetId)])
resolveTag StoreRead
ts Tag
tag
(Bool, [(TargetId, TargetId)])
-> Maybe (Bool, [(TargetId, TargetId)])
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool
sense, [(TargetId, TargetId)]
ranges)
searchTags :: StoreRead -> [Query] -> [TargetId]
searchTags :: StoreRead -> [Query] -> [TargetId]
searchTags StoreRead
ts [Query]
qs
| [TargetId]
x:[[TargetId]]
xs <- [((TargetId, TargetId) -> TargetId)
-> [(TargetId, TargetId)] -> [TargetId]
forall a b. (a -> b) -> [a] -> [b]
map (TargetId, TargetId) -> TargetId
forall a b. (a, b) -> a
fst ([(TargetId, TargetId)] -> [TargetId])
-> [(TargetId, TargetId)] -> [TargetId]
forall a b. (a -> b) -> a -> b
$ [(TargetId, TargetId)]
-> (Tag -> [(TargetId, TargetId)])
-> Maybe Tag
-> [(TargetId, TargetId)]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] ([(TargetId, TargetId)]
-> Maybe [(TargetId, TargetId)] -> [(TargetId, TargetId)]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [(TargetId, TargetId)] -> [(TargetId, TargetId)])
-> (Tag -> Maybe [(TargetId, TargetId)])
-> Tag
-> [(TargetId, TargetId)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tag, Maybe [(TargetId, TargetId)]) -> Maybe [(TargetId, TargetId)]
forall a b. (a, b) -> b
snd ((Tag, Maybe [(TargetId, TargetId)])
-> Maybe [(TargetId, TargetId)])
-> (Tag -> (Tag, Maybe [(TargetId, TargetId)]))
-> Tag
-> Maybe [(TargetId, TargetId)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StoreRead -> Tag -> (Tag, Maybe [(TargetId, TargetId)])
resolveTag StoreRead
ts) (Maybe Tag -> [(TargetId, TargetId)])
-> Maybe Tag -> [(TargetId, TargetId)]
forall a b. (a -> b) -> a -> b
$ String -> String -> Maybe Tag
parseTag String
cat String
val | QueryScope Bool
True String
cat String
val <- [Query]
qs]
= if [[TargetId]] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[TargetId]]
xs then [TargetId]
x else (TargetId -> Bool) -> [TargetId] -> [TargetId]
forall a. (a -> Bool) -> [a] -> [a]
filter (TargetId -> Set TargetId -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` (Set TargetId -> Set TargetId -> Set TargetId)
-> [Set TargetId] -> Set TargetId
forall a. (a -> a -> a) -> [a] -> a
foldl1' Set TargetId -> Set TargetId -> Set TargetId
forall a. Ord a => Set a -> Set a -> Set a
Set.intersection (([TargetId] -> Set TargetId) -> [[TargetId]] -> [Set TargetId]
forall a b. (a -> b) -> [a] -> [b]
map [TargetId] -> Set TargetId
forall a. Ord a => [a] -> Set a
Set.fromList [[TargetId]]
xs)) [TargetId]
x
searchTags StoreRead
ts [Query]
_ = [TargetId]
-> ([(TargetId, TargetId)] -> [TargetId])
-> Maybe [(TargetId, TargetId)]
-> [TargetId]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (((TargetId, TargetId) -> TargetId)
-> [(TargetId, TargetId)] -> [TargetId]
forall a b. (a -> b) -> [a] -> [b]
map (TargetId, TargetId) -> TargetId
forall a b. (a, b) -> a
fst) (Maybe [(TargetId, TargetId)] -> [TargetId])
-> Maybe [(TargetId, TargetId)] -> [TargetId]
forall a b. (a -> b) -> a -> b
$ (Tag, Maybe [(TargetId, TargetId)]) -> Maybe [(TargetId, TargetId)]
forall a b. (a, b) -> b
snd ((Tag, Maybe [(TargetId, TargetId)])
-> Maybe [(TargetId, TargetId)])
-> (Tag, Maybe [(TargetId, TargetId)])
-> Maybe [(TargetId, TargetId)]
forall a b. (a -> b) -> a -> b
$ StoreRead -> Tag -> (Tag, Maybe [(TargetId, TargetId)])
resolveTag StoreRead
ts Tag
IsPackage