-- Copyright (C) 2009-2010 Benedikt Schmidt
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2, 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; see the file COPYING.  If not, write to
-- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-- Boston, MA 02110-1301, USA.

module Darcs.Patch.Index.Types where

import Darcs.Prelude

import Darcs.Util.Hash( SHA1, sha1short, sha1zero )
import Darcs.Util.Path ( anchorPath, AnchoredPath )
import Data.Binary ( Binary(..) )
import Data.Word ( Word32 )

-- | The FileId for a file consists of the FilePath (creation name)
--   and an index. The index denotes how many files
--   with the same name have been added before (and subsequently
--   deleted or moved)
data FileId = FileId {FileId -> AnchoredPath
cname::AnchoredPath,FileId -> Int
count::Int}
  deriving (FileId -> FileId -> Bool
(FileId -> FileId -> Bool)
-> (FileId -> FileId -> Bool) -> Eq FileId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FileId -> FileId -> Bool
$c/= :: FileId -> FileId -> Bool
== :: FileId -> FileId -> Bool
$c== :: FileId -> FileId -> Bool
Eq,Int -> FileId -> ShowS
[FileId] -> ShowS
FileId -> String
(Int -> FileId -> ShowS)
-> (FileId -> String) -> ([FileId] -> ShowS) -> Show FileId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FileId] -> ShowS
$cshowList :: [FileId] -> ShowS
show :: FileId -> String
$cshow :: FileId -> String
showsPrec :: Int -> FileId -> ShowS
$cshowsPrec :: Int -> FileId -> ShowS
Show,Eq FileId
Eq FileId
-> (FileId -> FileId -> Ordering)
-> (FileId -> FileId -> Bool)
-> (FileId -> FileId -> Bool)
-> (FileId -> FileId -> Bool)
-> (FileId -> FileId -> Bool)
-> (FileId -> FileId -> FileId)
-> (FileId -> FileId -> FileId)
-> Ord FileId
FileId -> FileId -> Bool
FileId -> FileId -> Ordering
FileId -> FileId -> FileId
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
min :: FileId -> FileId -> FileId
$cmin :: FileId -> FileId -> FileId
max :: FileId -> FileId -> FileId
$cmax :: FileId -> FileId -> FileId
>= :: FileId -> FileId -> Bool
$c>= :: FileId -> FileId -> Bool
> :: FileId -> FileId -> Bool
$c> :: FileId -> FileId -> Bool
<= :: FileId -> FileId -> Bool
$c<= :: FileId -> FileId -> Bool
< :: FileId -> FileId -> Bool
$c< :: FileId -> FileId -> Bool
compare :: FileId -> FileId -> Ordering
$ccompare :: FileId -> FileId -> Ordering
$cp1Ord :: Eq FileId
Ord)

instance Binary FileId where
  put :: FileId -> Put
put (FileId AnchoredPath
rfp Int
i) = (AnchoredPath, Int) -> Put
forall t. Binary t => t -> Put
put (AnchoredPath
rfp,Int
i)
  get :: Get FileId
get = do
   (AnchoredPath
rfp,Int
cnt) <- Get (AnchoredPath, Int)
forall t. Binary t => Get t
get
   FileId -> Get FileId
forall (m :: * -> *) a. Monad m => a -> m a
return (FileId -> Get FileId) -> FileId -> Get FileId
forall a b. (a -> b) -> a -> b
$ AnchoredPath -> Int -> FileId
FileId AnchoredPath
rfp Int
cnt

-- | Convert FileId to string
showFileId :: FileId -> String
showFileId :: FileId -> String
showFileId (FileId AnchoredPath
fn Int
i) = Int -> String
forall a. Show a => a -> String
show Int
iString -> ShowS
forall a. [a] -> [a] -> [a]
++String
"#"String -> ShowS
forall a. [a] -> [a] -> [a]
++String -> AnchoredPath -> String
anchorPath String
"." AnchoredPath
fn

-- | The PatchId identifies a patch and can be created from a PatchInfo with makePatchname
newtype PatchId = PID {PatchId -> SHA1
patchId :: SHA1}
  deriving (Get PatchId
[PatchId] -> Put
PatchId -> Put
(PatchId -> Put)
-> Get PatchId -> ([PatchId] -> Put) -> Binary PatchId
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [PatchId] -> Put
$cputList :: [PatchId] -> Put
get :: Get PatchId
$cget :: Get PatchId
put :: PatchId -> Put
$cput :: PatchId -> Put
Binary,Int -> PatchId -> ShowS
[PatchId] -> ShowS
PatchId -> String
(Int -> PatchId -> ShowS)
-> (PatchId -> String) -> ([PatchId] -> ShowS) -> Show PatchId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PatchId] -> ShowS
$cshowList :: [PatchId] -> ShowS
show :: PatchId -> String
$cshow :: PatchId -> String
showsPrec :: Int -> PatchId -> ShowS
$cshowsPrec :: Int -> PatchId -> ShowS
Show,Eq PatchId
Eq PatchId
-> (PatchId -> PatchId -> Ordering)
-> (PatchId -> PatchId -> Bool)
-> (PatchId -> PatchId -> Bool)
-> (PatchId -> PatchId -> Bool)
-> (PatchId -> PatchId -> Bool)
-> (PatchId -> PatchId -> PatchId)
-> (PatchId -> PatchId -> PatchId)
-> Ord PatchId
PatchId -> PatchId -> Bool
PatchId -> PatchId -> Ordering
PatchId -> PatchId -> PatchId
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
min :: PatchId -> PatchId -> PatchId
$cmin :: PatchId -> PatchId -> PatchId
max :: PatchId -> PatchId -> PatchId
$cmax :: PatchId -> PatchId -> PatchId
>= :: PatchId -> PatchId -> Bool
$c>= :: PatchId -> PatchId -> Bool
> :: PatchId -> PatchId -> Bool
$c> :: PatchId -> PatchId -> Bool
<= :: PatchId -> PatchId -> Bool
$c<= :: PatchId -> PatchId -> Bool
< :: PatchId -> PatchId -> Bool
$c< :: PatchId -> PatchId -> Bool
compare :: PatchId -> PatchId -> Ordering
$ccompare :: PatchId -> PatchId -> Ordering
$cp1Ord :: Eq PatchId
Ord,PatchId -> PatchId -> Bool
(PatchId -> PatchId -> Bool)
-> (PatchId -> PatchId -> Bool) -> Eq PatchId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PatchId -> PatchId -> Bool
$c/= :: PatchId -> PatchId -> Bool
== :: PatchId -> PatchId -> Bool
$c== :: PatchId -> PatchId -> Bool
Eq)

pid2string :: PatchId -> String
pid2string :: PatchId -> String
pid2string = SHA1 -> String
forall a. Show a => a -> String
show (SHA1 -> String) -> (PatchId -> SHA1) -> PatchId -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchId -> SHA1
patchId

-- | This is used to track changes to files
data PatchMod a
  = PTouch a
  | PCreateFile a
  | PCreateDir a
  | PRename a
            a
  | PRemove a
  | PDuplicateTouch a
    -- ^ this is used for duplicate patches that don't
    --   have any effect, but we still want to keep
    --   track of them
  deriving (Int -> PatchMod a -> ShowS
[PatchMod a] -> ShowS
PatchMod a -> String
(Int -> PatchMod a -> ShowS)
-> (PatchMod a -> String)
-> ([PatchMod a] -> ShowS)
-> Show (PatchMod a)
forall a. Show a => Int -> PatchMod a -> ShowS
forall a. Show a => [PatchMod a] -> ShowS
forall a. Show a => PatchMod a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PatchMod a] -> ShowS
$cshowList :: forall a. Show a => [PatchMod a] -> ShowS
show :: PatchMod a -> String
$cshow :: forall a. Show a => PatchMod a -> String
showsPrec :: Int -> PatchMod a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> PatchMod a -> ShowS
Show, PatchMod a -> PatchMod a -> Bool
(PatchMod a -> PatchMod a -> Bool)
-> (PatchMod a -> PatchMod a -> Bool) -> Eq (PatchMod a)
forall a. Eq a => PatchMod a -> PatchMod a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PatchMod a -> PatchMod a -> Bool
$c/= :: forall a. Eq a => PatchMod a -> PatchMod a -> Bool
== :: PatchMod a -> PatchMod a -> Bool
$c== :: forall a. Eq a => PatchMod a -> PatchMod a -> Bool
Eq, a -> PatchMod b -> PatchMod a
(a -> b) -> PatchMod a -> PatchMod b
(forall a b. (a -> b) -> PatchMod a -> PatchMod b)
-> (forall a b. a -> PatchMod b -> PatchMod a) -> Functor PatchMod
forall a b. a -> PatchMod b -> PatchMod a
forall a b. (a -> b) -> PatchMod a -> PatchMod b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> PatchMod b -> PatchMod a
$c<$ :: forall a b. a -> PatchMod b -> PatchMod a
fmap :: (a -> b) -> PatchMod a -> PatchMod b
$cfmap :: forall a b. (a -> b) -> PatchMod a -> PatchMod b
Functor)

short :: PatchId -> Word32
short :: PatchId -> Word32
short (PID SHA1
sha1) = SHA1 -> Word32
sha1short SHA1
sha1

zero :: PatchId
zero :: PatchId
zero = SHA1 -> PatchId
PID SHA1
sha1zero