1{- git-annex deferred parse values
2 -
3 - Copyright 2015-2021 Joey Hess <id@joeyh.name>
4 -
5 - Licensed under the GNU AGPL version 3 or higher.
6 -}
7
8{-# LANGUAGE FlexibleInstances #-}
9
10module Types.DeferredParse where
11
12import Annex
13
14import Options.Applicative
15import qualified Data.Semigroup as Sem
16import Prelude
17
18-- Some values cannot be fully parsed without performing an action.
19-- The action may be expensive, so it's best to call finishParse on such a
20-- value before using getParsed repeatedly.
21data DeferredParse a = DeferredParse (Annex a) | ReadyParse a
22
23class DeferredParseClass a where
24	finishParse :: a -> Annex a
25
26getParsed :: DeferredParse a -> Annex a
27getParsed (DeferredParse a) = a
28getParsed (ReadyParse a) = pure a
29
30instance DeferredParseClass (DeferredParse a) where
31	finishParse (DeferredParse a) = ReadyParse <$> a
32	finishParse (ReadyParse a) = pure (ReadyParse a)
33
34instance DeferredParseClass (Maybe (DeferredParse a)) where
35	finishParse Nothing = pure Nothing
36	finishParse (Just v) = Just <$> finishParse v
37
38instance DeferredParseClass [DeferredParse a] where
39	finishParse v = mapM finishParse v
40
41type GlobalOption = Parser GlobalSetter
42
43-- Used for global options that can modify Annex state by running
44-- an arbitrary action in it, and can also set up AnnexRead.
45data GlobalSetter = GlobalSetter
46	{ annexStateSetter :: Annex ()
47	, annexReadSetter :: AnnexRead -> AnnexRead
48	}
49
50instance Sem.Semigroup GlobalSetter where
51	a <> b = GlobalSetter
52		{ annexStateSetter = annexStateSetter a >> annexStateSetter b
53		, annexReadSetter = annexReadSetter b . annexReadSetter a
54		}
55
56instance Monoid GlobalSetter where
57	mempty = GlobalSetter (return ()) id
58