khph-0.1.0: src/Khph/Query/Base.hs
-- This file is part of khph.
--
-- Copyright 2016 Bryan Gardiner <bog@khumba.net>
--
-- 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 <http://www.gnu.org/licenses/>.
-- | 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