File: FileMatcher.hs

package info (click to toggle)
git-annex 8.20210223-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 68,764 kB
  • sloc: haskell: 70,359; javascript: 9,103; sh: 1,304; makefile: 212; perl: 136; ansic: 44
file content (95 lines) | stat: -rw-r--r-- 3,026 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
{- git-annex file matcher types
 -
 - Copyright 2013-2020 Joey Hess <id@joeyh.name>
 -
 - Licensed under the GNU AGPL version 3 or higher.
 -}

module Types.FileMatcher where

import Types.UUID (UUID)
import Types.Key (Key, AssociatedFile)
import Types.Mime
import Utility.Matcher (Matcher, Token)
import Utility.FileSize
import Utility.FileSystemEncoding

import Control.Monad.IO.Class
import qualified Data.Map as M
import qualified Data.Set as S

-- Information about a file and/or a key that can be matched on.
data MatchInfo
	= MatchingFile FileInfo
	| MatchingKey Key AssociatedFile
	-- ^ This is used when matching a file that may be in another
	-- branch. The AssociatedFile is the filename, but it should not be
	-- accessed from disk when matching.
	| MatchingInfo ProvidedInfo
	| MatchingUserInfo UserProvidedInfo

data FileInfo = FileInfo
	{ contentFile :: Maybe RawFilePath
	-- ^ path to a file containing the content, for operations
	-- that examine it
	, matchFile :: RawFilePath
	-- ^ filepath to match on; may be relative to top of repo or cwd,
	-- depending on how globs in preferred content expressions
	-- are intended to be matched
	, matchKey :: Maybe Key
	-- ^ provided if a key is already known
	}

data ProvidedInfo = ProvidedInfo
	{ providedFilePath :: RawFilePath
	, providedKey :: Maybe Key
	, providedFileSize :: FileSize
	, providedMimeType :: Maybe MimeType
	, providedMimeEncoding :: Maybe MimeEncoding
	}

-- This is used when testing a matcher, with values to match against
-- provided by the user.
data UserProvidedInfo = UserProvidedInfo
	{ userProvidedFilePath :: UserInfo FilePath
	, userProvidedKey :: UserInfo Key
	, userProvidedFileSize :: UserInfo FileSize
	, userProvidedMimeType :: UserInfo MimeType
	, userProvidedMimeEncoding :: UserInfo MimeEncoding
	}

-- This may fail if the user did not provide the information.
type UserInfo a = Either (IO a) a

-- If the UserInfo is not available, accessing it may result in eg an
-- exception being thrown.
getUserInfo :: MonadIO m => UserInfo a -> m a
getUserInfo (Right i) = return i
getUserInfo (Left e) = liftIO e

type FileMatcherMap a = M.Map UUID (FileMatcher a)

type MkLimit a = String -> Either String (MatchFiles a)

type AssumeNotPresent = S.Set UUID

data MatchFiles a = MatchFiles 
	{ matchAction :: AssumeNotPresent -> MatchInfo -> a Bool
	, matchNeedsFileName :: Bool
	-- ^ does the matchAction need a filename in order to match?
	, matchNeedsFileContent :: Bool
	-- ^ does the matchAction need the file content to be present in
	-- order to succeed?
	, matchNeedsKey :: Bool
	-- ^ does the matchAction look at information about the key?
	, matchNeedsLocationLog :: Bool
	-- ^ does the matchAction look at the location log?
	}

type FileMatcher a = Matcher (MatchFiles a)

-- This is a matcher that can have tokens added to it while it's being
-- built, and once complete is compiled to an unchangable matcher.
data ExpandableMatcher a
	= BuildingMatcher [Token (MatchFiles a)]
	| CompleteMatcher (Matcher (MatchFiles a))