-- This file is part of khph. -- -- Copyright 2016 Bryan Gardiner -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU Affero General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU Affero General Public License for more details. -- -- You should have received a copy of the GNU Affero General Public License -- along with this program. If not, see . -- | Data types for constructing predicates. module Khph.Query.Base ( Logic (..), ListPredicate (..), Query, Query' (..), StringQuery, StringQuery' (..), LinkQuery, LinkQuery' (..), ProjectPathComponent (..), TreeQuery, TreeQuery' (..), TagQuery, ) where import Khph.Project.Base import Khph.Util -- | Wraps a query of type @q@ in Boolean logic. data Logic q = LogicQuery q | LogicTrue | LogicFalse | LogicNot (Logic q) | LogicAnd [Logic q] | LogicOr [Logic q] deriving (Eq, Show) -- | Represent a fold of a query @q@ over a list. -- -- TODO Count lt/gt operators? Useful for e.g. "more than one place tag." data ListPredicate q = All q -- ^ All items in the list must match @q@. | All1 q -- ^ All items in the list must match @q@, and the list must be nonempty. | Some q -- ^ Some item in the list must match @q@. | None q -- ^ All items in the list must not match @q@. | Exists -- ^ The list must be nonempty. | DoesNotExist -- ^ The list must be empty. deriving (Eq, Show) -- | A query on an entry. type Query = Logic Query' data Query' = QueryLink (ListPredicate LinkQuery) | QueryTag (ListPredicate TagQuery) deriving (Eq, Show) -- | A query on a string. type StringQuery = Logic StringQuery' data StringQuery' = StringEq String | StringContains String | StringStartsWith String | StringEndsWith String deriving (Eq, Show) -- | A query on one of an entry's links. type LinkQuery = Logic LinkQuery' data LinkQuery' = LinkTypeIs LinkType -- ^ Matches based on whether the link is hard or soft. | LinkMatchesEntrySpec EntrySpec -- ^ Matches based on an 'EntrySpec'. | LinkIsSourcePath -- ^ Matches if the link is at or below one of the project's source -- directories. | LinkStringQuery (Maybe ProjectPathComponent) StringQuery -- ^ Matches if a 'StringQuery' matches the project-relative path's textual -- representation. 'ProjectPathComponent' may be used to select only the -- directory or file name components of the path. | LinkTreeQuery (TreeQuery [String]) -- ^ Matches if a 'TreeQuery' matches the link's position in the directory -- tree. deriving (Eq, Show) data ProjectPathComponent = DirectoryComponent | FileComponent deriving (Eq, Show) -- | A query on a position in a tree. @a@ may be an arbitrary data type, that -- must be convertible into a @Eq b => [b]@ for comparison. type TreeQuery a = Logic (TreeQuery' a) data TreeQuery' a = TreeAt a -- ^ The position must be at the exact location given. | TreeAtAbove a -- ^ The position must either at or be an ancestor of the location given. | TreeAbove a -- ^ The position must be an ancestor (not at) the location given. | TreeAtBelow a -- ^ The position must either at or be a child of the location given. | TreeBelow a -- ^ The position must be a child (not at) the location given. deriving (Eq, Show) -- | A tag query is just a query on the tag's position in the tag hierarchy. type TagQuery = TreeQuery Tag