{-# LANGUAGE Rank2Types, TypeSynonymInstances, DeriveDataTypeable, FlexibleInstances #-}
{- |
   Module      : Data.FileStore.Types
   Copyright   : Copyright (C) 2009 John MacFarlane
   License     : BSD 3

   Maintainer  : John MacFarlane <jgm@berkeley.edu>
   Stability   : alpha
   Portability : GHC 6.10 required

   Type definitions for "Data.FileStore".
-}

module Data.FileStore.Types
           ( RevisionId
           , Resource(..)
           , Author(..)
           , Change(..)
           , Description
           , Revision(..)
           , Contents(..)
           , TimeRange(..)
           , MergeInfo(..)
           , FileStoreError(..)
           , SearchMatch(..)
           , SearchQuery(..)
           , defaultSearchQuery
           , UTCTime
           , FileStore (..) )

where
import Data.ByteString.Lazy (ByteString)
import Data.Typeable
import Data.ByteString.Lazy.UTF8 (toString, fromString)
import Data.Time (UTCTime)
import Control.Exception (Exception)

type RevisionId   = String

data Resource = FSFile FilePath
              | FSDirectory FilePath
              deriving (Int -> Resource -> ShowS
[Resource] -> ShowS
Resource -> String
(Int -> Resource -> ShowS)
-> (Resource -> String) -> ([Resource] -> ShowS) -> Show Resource
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Resource -> ShowS
showsPrec :: Int -> Resource -> ShowS
$cshow :: Resource -> String
show :: Resource -> String
$cshowList :: [Resource] -> ShowS
showList :: [Resource] -> ShowS
Show, ReadPrec [Resource]
ReadPrec Resource
Int -> ReadS Resource
ReadS [Resource]
(Int -> ReadS Resource)
-> ReadS [Resource]
-> ReadPrec Resource
-> ReadPrec [Resource]
-> Read Resource
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Resource
readsPrec :: Int -> ReadS Resource
$creadList :: ReadS [Resource]
readList :: ReadS [Resource]
$creadPrec :: ReadPrec Resource
readPrec :: ReadPrec Resource
$creadListPrec :: ReadPrec [Resource]
readListPrec :: ReadPrec [Resource]
Read, Resource -> Resource -> Bool
(Resource -> Resource -> Bool)
-> (Resource -> Resource -> Bool) -> Eq Resource
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Resource -> Resource -> Bool
== :: Resource -> Resource -> Bool
$c/= :: Resource -> Resource -> Bool
/= :: Resource -> Resource -> Bool
Eq, Typeable, Eq Resource
Eq Resource =>
(Resource -> Resource -> Ordering)
-> (Resource -> Resource -> Bool)
-> (Resource -> Resource -> Bool)
-> (Resource -> Resource -> Bool)
-> (Resource -> Resource -> Bool)
-> (Resource -> Resource -> Resource)
-> (Resource -> Resource -> Resource)
-> Ord Resource
Resource -> Resource -> Bool
Resource -> Resource -> Ordering
Resource -> Resource -> Resource
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Resource -> Resource -> Ordering
compare :: Resource -> Resource -> Ordering
$c< :: Resource -> Resource -> Bool
< :: Resource -> Resource -> Bool
$c<= :: Resource -> Resource -> Bool
<= :: Resource -> Resource -> Bool
$c> :: Resource -> Resource -> Bool
> :: Resource -> Resource -> Bool
$c>= :: Resource -> Resource -> Bool
>= :: Resource -> Resource -> Bool
$cmax :: Resource -> Resource -> Resource
max :: Resource -> Resource -> Resource
$cmin :: Resource -> Resource -> Resource
min :: Resource -> Resource -> Resource
Ord)

data Author =
  Author {
    Author -> String
authorName  :: String
  , Author -> String
authorEmail :: String
  } deriving (Int -> Author -> ShowS
[Author] -> ShowS
Author -> String
(Int -> Author -> ShowS)
-> (Author -> String) -> ([Author] -> ShowS) -> Show Author
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Author -> ShowS
showsPrec :: Int -> Author -> ShowS
$cshow :: Author -> String
show :: Author -> String
$cshowList :: [Author] -> ShowS
showList :: [Author] -> ShowS
Show, ReadPrec [Author]
ReadPrec Author
Int -> ReadS Author
ReadS [Author]
(Int -> ReadS Author)
-> ReadS [Author]
-> ReadPrec Author
-> ReadPrec [Author]
-> Read Author
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Author
readsPrec :: Int -> ReadS Author
$creadList :: ReadS [Author]
readList :: ReadS [Author]
$creadPrec :: ReadPrec Author
readPrec :: ReadPrec Author
$creadListPrec :: ReadPrec [Author]
readListPrec :: ReadPrec [Author]
Read, Author -> Author -> Bool
(Author -> Author -> Bool)
-> (Author -> Author -> Bool) -> Eq Author
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Author -> Author -> Bool
== :: Author -> Author -> Bool
$c/= :: Author -> Author -> Bool
/= :: Author -> Author -> Bool
Eq, Typeable)

data Change =
    Added FilePath
  | Deleted FilePath
  | Modified FilePath
  deriving (Int -> Change -> ShowS
[Change] -> ShowS
Change -> String
(Int -> Change -> ShowS)
-> (Change -> String) -> ([Change] -> ShowS) -> Show Change
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Change -> ShowS
showsPrec :: Int -> Change -> ShowS
$cshow :: Change -> String
show :: Change -> String
$cshowList :: [Change] -> ShowS
showList :: [Change] -> ShowS
Show, ReadPrec [Change]
ReadPrec Change
Int -> ReadS Change
ReadS [Change]
(Int -> ReadS Change)
-> ReadS [Change]
-> ReadPrec Change
-> ReadPrec [Change]
-> Read Change
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Change
readsPrec :: Int -> ReadS Change
$creadList :: ReadS [Change]
readList :: ReadS [Change]
$creadPrec :: ReadPrec Change
readPrec :: ReadPrec Change
$creadListPrec :: ReadPrec [Change]
readListPrec :: ReadPrec [Change]
Read, Change -> Change -> Bool
(Change -> Change -> Bool)
-> (Change -> Change -> Bool) -> Eq Change
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Change -> Change -> Bool
== :: Change -> Change -> Bool
$c/= :: Change -> Change -> Bool
/= :: Change -> Change -> Bool
Eq, Typeable)

type Description = String

data Revision =
  Revision {
    Revision -> String
revId          :: RevisionId
  , Revision -> UTCTime
revDateTime    :: UTCTime
  , Revision -> Author
revAuthor      :: Author
  , Revision -> String
revDescription :: Description
  , Revision -> [Change]
revChanges     :: [Change]
  } deriving (Int -> Revision -> ShowS
[Revision] -> ShowS
Revision -> String
(Int -> Revision -> ShowS)
-> (Revision -> String) -> ([Revision] -> ShowS) -> Show Revision
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Revision -> ShowS
showsPrec :: Int -> Revision -> ShowS
$cshow :: Revision -> String
show :: Revision -> String
$cshowList :: [Revision] -> ShowS
showList :: [Revision] -> ShowS
Show, ReadPrec [Revision]
ReadPrec Revision
Int -> ReadS Revision
ReadS [Revision]
(Int -> ReadS Revision)
-> ReadS [Revision]
-> ReadPrec Revision
-> ReadPrec [Revision]
-> Read Revision
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Revision
readsPrec :: Int -> ReadS Revision
$creadList :: ReadS [Revision]
readList :: ReadS [Revision]
$creadPrec :: ReadPrec Revision
readPrec :: ReadPrec Revision
$creadListPrec :: ReadPrec [Revision]
readListPrec :: ReadPrec [Revision]
Read, Revision -> Revision -> Bool
(Revision -> Revision -> Bool)
-> (Revision -> Revision -> Bool) -> Eq Revision
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Revision -> Revision -> Bool
== :: Revision -> Revision -> Bool
$c/= :: Revision -> Revision -> Bool
/= :: Revision -> Revision -> Bool
Eq, Typeable)

class Contents a where
  fromByteString :: ByteString -> a
  toByteString   :: a -> ByteString

instance Contents ByteString where
  toByteString :: ByteString -> ByteString
toByteString = ByteString -> ByteString
forall a. a -> a
id
  fromByteString :: ByteString -> ByteString
fromByteString = ByteString -> ByteString
forall a. a -> a
id

instance Contents String where
  toByteString :: String -> ByteString
toByteString   = String -> ByteString
fromString
  fromByteString :: ByteString -> String
fromByteString = ByteString -> String
toString

data TimeRange =
  TimeRange {
    TimeRange -> Maybe UTCTime
timeFrom :: Maybe UTCTime  -- ^ @Nothing@ means no lower bound
  , TimeRange -> Maybe UTCTime
timeTo   :: Maybe UTCTime  -- ^ @Nothing@ means no upper bound
  } deriving (Int -> TimeRange -> ShowS
[TimeRange] -> ShowS
TimeRange -> String
(Int -> TimeRange -> ShowS)
-> (TimeRange -> String)
-> ([TimeRange] -> ShowS)
-> Show TimeRange
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TimeRange -> ShowS
showsPrec :: Int -> TimeRange -> ShowS
$cshow :: TimeRange -> String
show :: TimeRange -> String
$cshowList :: [TimeRange] -> ShowS
showList :: [TimeRange] -> ShowS
Show, ReadPrec [TimeRange]
ReadPrec TimeRange
Int -> ReadS TimeRange
ReadS [TimeRange]
(Int -> ReadS TimeRange)
-> ReadS [TimeRange]
-> ReadPrec TimeRange
-> ReadPrec [TimeRange]
-> Read TimeRange
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS TimeRange
readsPrec :: Int -> ReadS TimeRange
$creadList :: ReadS [TimeRange]
readList :: ReadS [TimeRange]
$creadPrec :: ReadPrec TimeRange
readPrec :: ReadPrec TimeRange
$creadListPrec :: ReadPrec [TimeRange]
readListPrec :: ReadPrec [TimeRange]
Read, TimeRange -> TimeRange -> Bool
(TimeRange -> TimeRange -> Bool)
-> (TimeRange -> TimeRange -> Bool) -> Eq TimeRange
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TimeRange -> TimeRange -> Bool
== :: TimeRange -> TimeRange -> Bool
$c/= :: TimeRange -> TimeRange -> Bool
/= :: TimeRange -> TimeRange -> Bool
Eq, Typeable)

data MergeInfo =
  MergeInfo {
    MergeInfo -> Revision
mergeRevision  :: Revision   -- ^ The revision w/ which changes were merged
  , MergeInfo -> Bool
mergeConflicts :: Bool       -- ^ @True@ if there were merge conflicts
  , MergeInfo -> String
mergeText      :: String     -- ^ The merged text, w/ conflict markers
  } deriving (Int -> MergeInfo -> ShowS
[MergeInfo] -> ShowS
MergeInfo -> String
(Int -> MergeInfo -> ShowS)
-> (MergeInfo -> String)
-> ([MergeInfo] -> ShowS)
-> Show MergeInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MergeInfo -> ShowS
showsPrec :: Int -> MergeInfo -> ShowS
$cshow :: MergeInfo -> String
show :: MergeInfo -> String
$cshowList :: [MergeInfo] -> ShowS
showList :: [MergeInfo] -> ShowS
Show, ReadPrec [MergeInfo]
ReadPrec MergeInfo
Int -> ReadS MergeInfo
ReadS [MergeInfo]
(Int -> ReadS MergeInfo)
-> ReadS [MergeInfo]
-> ReadPrec MergeInfo
-> ReadPrec [MergeInfo]
-> Read MergeInfo
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS MergeInfo
readsPrec :: Int -> ReadS MergeInfo
$creadList :: ReadS [MergeInfo]
readList :: ReadS [MergeInfo]
$creadPrec :: ReadPrec MergeInfo
readPrec :: ReadPrec MergeInfo
$creadListPrec :: ReadPrec [MergeInfo]
readListPrec :: ReadPrec [MergeInfo]
Read, MergeInfo -> MergeInfo -> Bool
(MergeInfo -> MergeInfo -> Bool)
-> (MergeInfo -> MergeInfo -> Bool) -> Eq MergeInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MergeInfo -> MergeInfo -> Bool
== :: MergeInfo -> MergeInfo -> Bool
$c/= :: MergeInfo -> MergeInfo -> Bool
/= :: MergeInfo -> MergeInfo -> Bool
Eq, Typeable)

data FileStoreError =
    RepositoryExists             -- ^ Tried to initialize a repo that exists
  | ResourceExists               -- ^ Tried to create a resource that exists
  | NotFound                     -- ^ Requested resource was not found
  | IllegalResourceName          -- ^ The specified resource name is illegal
  | Unchanged                    -- ^ The resource was not modified,
                                 --   because the contents were unchanged
  | UnsupportedOperation
  | NoMaxCount                   -- ^ The darcs version used does not support
                                 --   --max-count
  | UnknownError String
  deriving (ReadPrec [FileStoreError]
ReadPrec FileStoreError
Int -> ReadS FileStoreError
ReadS [FileStoreError]
(Int -> ReadS FileStoreError)
-> ReadS [FileStoreError]
-> ReadPrec FileStoreError
-> ReadPrec [FileStoreError]
-> Read FileStoreError
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS FileStoreError
readsPrec :: Int -> ReadS FileStoreError
$creadList :: ReadS [FileStoreError]
readList :: ReadS [FileStoreError]
$creadPrec :: ReadPrec FileStoreError
readPrec :: ReadPrec FileStoreError
$creadListPrec :: ReadPrec [FileStoreError]
readListPrec :: ReadPrec [FileStoreError]
Read, FileStoreError -> FileStoreError -> Bool
(FileStoreError -> FileStoreError -> Bool)
-> (FileStoreError -> FileStoreError -> Bool) -> Eq FileStoreError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FileStoreError -> FileStoreError -> Bool
== :: FileStoreError -> FileStoreError -> Bool
$c/= :: FileStoreError -> FileStoreError -> Bool
/= :: FileStoreError -> FileStoreError -> Bool
Eq, Typeable)

instance Show FileStoreError where
  show :: FileStoreError -> String
show FileStoreError
RepositoryExists      = String
"RepositoryExists"
  show FileStoreError
ResourceExists        = String
"ResourceExists"
  show FileStoreError
NotFound              = String
"NotFound"
  show FileStoreError
IllegalResourceName   = String
"IllegalResourceName"
  show FileStoreError
Unchanged             = String
"Unchanged"
  show FileStoreError
UnsupportedOperation  = String
"UnsupportedOperation"
  show FileStoreError
NoMaxCount            = String
"NoMaxCount:\n"
    String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"filestore was compiled with the maxcount flag, but your version of\n"
    String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"darcs does not support the --max-count option.  You should either\n"
    String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"upgrade to darcs >= 2.3.0 (recommended) or compile filestore without\n"
    String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"the maxcount flag (cabal install filestore -f-maxcount)."
  show (UnknownError String
s)      = String
"UnknownError: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
s

instance Exception FileStoreError

data SearchQuery =
  SearchQuery {
    SearchQuery -> [String]
queryPatterns    :: [String] -- ^ Patterns to match
  , SearchQuery -> Bool
queryWholeWords  :: Bool     -- ^ Match patterns only with whole words?
  , SearchQuery -> Bool
queryMatchAll    :: Bool     -- ^ Return matches only from files in which
                                 --   all patterns match?
  , SearchQuery -> Bool
queryIgnoreCase  :: Bool     -- ^ Make matches case-insensitive?
  } deriving (Int -> SearchQuery -> ShowS
[SearchQuery] -> ShowS
SearchQuery -> String
(Int -> SearchQuery -> ShowS)
-> (SearchQuery -> String)
-> ([SearchQuery] -> ShowS)
-> Show SearchQuery
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SearchQuery -> ShowS
showsPrec :: Int -> SearchQuery -> ShowS
$cshow :: SearchQuery -> String
show :: SearchQuery -> String
$cshowList :: [SearchQuery] -> ShowS
showList :: [SearchQuery] -> ShowS
Show, ReadPrec [SearchQuery]
ReadPrec SearchQuery
Int -> ReadS SearchQuery
ReadS [SearchQuery]
(Int -> ReadS SearchQuery)
-> ReadS [SearchQuery]
-> ReadPrec SearchQuery
-> ReadPrec [SearchQuery]
-> Read SearchQuery
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS SearchQuery
readsPrec :: Int -> ReadS SearchQuery
$creadList :: ReadS [SearchQuery]
readList :: ReadS [SearchQuery]
$creadPrec :: ReadPrec SearchQuery
readPrec :: ReadPrec SearchQuery
$creadListPrec :: ReadPrec [SearchQuery]
readListPrec :: ReadPrec [SearchQuery]
Read, SearchQuery -> SearchQuery -> Bool
(SearchQuery -> SearchQuery -> Bool)
-> (SearchQuery -> SearchQuery -> Bool) -> Eq SearchQuery
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SearchQuery -> SearchQuery -> Bool
== :: SearchQuery -> SearchQuery -> Bool
$c/= :: SearchQuery -> SearchQuery -> Bool
/= :: SearchQuery -> SearchQuery -> Bool
Eq, Typeable)

defaultSearchQuery :: SearchQuery
defaultSearchQuery :: SearchQuery
defaultSearchQuery = SearchQuery {
     queryPatterns :: [String]
queryPatterns   = []
   , queryWholeWords :: Bool
queryWholeWords = Bool
True
   , queryMatchAll :: Bool
queryMatchAll   = Bool
True
   , queryIgnoreCase :: Bool
queryIgnoreCase = Bool
True
   }

data SearchMatch =
  SearchMatch {
    SearchMatch -> String
matchResourceName :: FilePath
  , SearchMatch -> Integer
matchLineNumber   :: Integer
  , SearchMatch -> String
matchLine         :: String
  } deriving (Int -> SearchMatch -> ShowS
[SearchMatch] -> ShowS
SearchMatch -> String
(Int -> SearchMatch -> ShowS)
-> (SearchMatch -> String)
-> ([SearchMatch] -> ShowS)
-> Show SearchMatch
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SearchMatch -> ShowS
showsPrec :: Int -> SearchMatch -> ShowS
$cshow :: SearchMatch -> String
show :: SearchMatch -> String
$cshowList :: [SearchMatch] -> ShowS
showList :: [SearchMatch] -> ShowS
Show, ReadPrec [SearchMatch]
ReadPrec SearchMatch
Int -> ReadS SearchMatch
ReadS [SearchMatch]
(Int -> ReadS SearchMatch)
-> ReadS [SearchMatch]
-> ReadPrec SearchMatch
-> ReadPrec [SearchMatch]
-> Read SearchMatch
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS SearchMatch
readsPrec :: Int -> ReadS SearchMatch
$creadList :: ReadS [SearchMatch]
readList :: ReadS [SearchMatch]
$creadPrec :: ReadPrec SearchMatch
readPrec :: ReadPrec SearchMatch
$creadListPrec :: ReadPrec [SearchMatch]
readListPrec :: ReadPrec [SearchMatch]
Read, SearchMatch -> SearchMatch -> Bool
(SearchMatch -> SearchMatch -> Bool)
-> (SearchMatch -> SearchMatch -> Bool) -> Eq SearchMatch
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SearchMatch -> SearchMatch -> Bool
== :: SearchMatch -> SearchMatch -> Bool
$c/= :: SearchMatch -> SearchMatch -> Bool
/= :: SearchMatch -> SearchMatch -> Bool
Eq, Typeable)

-- | A versioning filestore, which can be implemented using the
-- file system, a database, or revision-control software.
data FileStore = FileStore {

    -- | Initialize a new filestore.
    FileStore -> IO ()
initialize     :: IO ()

    -- | Save contents in the filestore.
  , FileStore
-> forall a. Contents a => String -> Author -> String -> a -> IO ()
save           :: forall a . Contents a
                   => FilePath          -- Resource to save.
                   -> Author            --  Author of change.
                   -> Description       --  Description of change.
                   -> a                 --  New contents of resource.
                   -> IO ()

    -- | Retrieve the contents of the named resource.
  , FileStore -> forall a. Contents a => String -> Maybe String -> IO a
retrieve       :: forall a . Contents a
                   => FilePath          -- Resource to retrieve.
                   -> Maybe RevisionId  -- @Just@ a particular revision ID,
                                        -- or @Nothing@ for latest
                   -> IO a

    -- | Delete a named resource, providing author and log message.
  , FileStore -> String -> Author -> String -> IO ()
delete         :: FilePath          -- Resource to delete.
                   -> Author            -- Author of change.
                   -> Description       -- Description of change.
                   -> IO ()

    -- | Rename a resource, providing author and log message.
  , FileStore -> String -> String -> Author -> String -> IO ()
rename         :: FilePath          -- Resource original name.
                   -> FilePath          -- Resource new name.
                   -> Author            -- Author of change.
                   -> Description       -- Description of change.
                   -> IO ()

    -- | Get history for a list of named resources in a (possibly openended)
    -- time range. If the list is empty, history for all resources will
    -- be returned. If the TimeRange is 2 Nothings, history for all dates will be returned.
  , FileStore -> [String] -> TimeRange -> Maybe Int -> IO [Revision]
history        :: [FilePath]        -- List of resources to get history for
                                        -- or @[]@ for all.
                   -> TimeRange         -- Time range in which to get history.
                   -> Maybe Int         -- Maybe max number of entries.
                   -> IO [Revision]

    -- | Return the revision ID of the latest change for a resource.
    -- Raises 'NotFound' if the resource is not found.
  , FileStore -> String -> IO String
latest         :: FilePath          -- Resource to get revision ID for.
                   -> IO RevisionId

    -- | Return information about a revision, given the ID.
    -- Raises 'NotFound' if there is no such revision.
  , FileStore -> String -> IO Revision
revision       :: RevisionId        -- Revision ID to get information for.
                   -> IO Revision

    -- | Return a list of resources in the filestore.
  , FileStore -> IO [String]
index          :: IO [FilePath]

  -- | Return a list of resources in a directory of the filestore.
  , FileStore -> String -> IO [Resource]
directory      :: FilePath          -- Directory to list (empty for root)
                   -> IO [Resource]

    -- | @True@ if the revision IDs match, in the sense that the
    -- can be treated as specifying the same revision.
  , FileStore -> String -> String -> Bool
idsMatch       :: RevisionId
                   -> RevisionId
                   -> Bool

  -- | Search the filestore for patterns.
  , FileStore -> SearchQuery -> IO [SearchMatch]
search         :: SearchQuery
                   -> IO [SearchMatch]

  }