{-# LANGUAGE CPP, OverloadedStrings #-} -- Copyright (C) 2011 Petr Rockai -- -- Permission is hereby granted, free of charge, to any person -- obtaining a copy of this software and associated documentation -- files (the "Software"), to deal in the Software without -- restriction, including without limitation the rights to use, copy, -- modify, merge, publish, distribute, sublicense, and/or sell copies -- of the Software, and to permit persons to whom the Software is -- furnished to do so, subject to the following conditions: -- -- The above copyright notice and this permission notice shall be -- included in all copies or substantial portions of the Software. -- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -- BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -- SOFTWARE. #include "gadts.h" module Darcs.Patch.Prim.V3.Core ( Prim(..), Hunk(..), UUID(..), Location, Object(..), touches, hunkEdit ) where import qualified Data.ByteString as BS import Darcs.Witnesses.Eq ( MyEq(..) ) import Darcs.Patch.FileHunk( IsHunk(..) ) import Darcs.Patch.Invert ( Invert(..) ) import Darcs.Patch.Inspect ( PatchInspect(..) ) import Darcs.Patch.Prim.Class ( PrimConstruct(..), PrimClassify(..) ) import Darcs.Patch.Prim.V3.ObjectMap -- TODO: elaborate data Hunk C(x y) where Hunk :: !Int -> BS.ByteString -> BS.ByteString -> Hunk C(x y) invertHunk :: Hunk C(x y) -> Hunk C(y x) invertHunk (Hunk off old new) = Hunk off new old hunkEdit :: Hunk C(x y) -> BS.ByteString -> BS.ByteString hunkEdit (Hunk off old new) bs = case splice bs (off) (off + BS.length old) of x | x == old -> BS.concat [ BS.take off bs, new, BS.drop (off + BS.length old) bs ] | otherwise -> error $ "error applying hunk: " ++ show off ++ " " ++ show old ++ " " ++ show new ++ " to " ++ show bs where splice bs' x y = BS.drop x $ BS.take y bs' instance MyEq Hunk where unsafeCompare (Hunk i x y) (Hunk i' x' y') = i == i' && x == x' && y == y' data Prim C(x y) where BinaryHunk :: !UUID -> Hunk C(x y) -> Prim C(x y) TextHunk :: !UUID -> Hunk C(x y) -> Prim C(x y) -- TODO: String is not the right type here. However, what it represents is -- a single file *name* (not a path). No slashes allowed, no "." and ".." -- allowed either. Manifest :: !UUID -> Location -> Prim C(x y) Demanifest :: !UUID -> Location -> Prim C(x y) Move :: !UUID -> Location -> Location -> Prim C(x y) Identity :: Prim C(x x) touches :: Prim C(x y) -> [UUID] touches (BinaryHunk x _) = [x] touches (TextHunk x _) = [x] touches (Manifest _ (x, _)) = [x] touches (Demanifest _ (x, _)) = [x] touches (Move _ (x, _) (y, _)) = [x, y] touches Identity = [] -- TODO: PrimClassify doesn't make sense for V3 prims instance PrimClassify Prim where primIsAddfile _ = False primIsRmfile _ = False primIsAdddir _ = False primIsRmdir _ = False primIsHunk _ = False primIsMove _ = False primIsBinary _ = False primIsTokReplace _ = False primIsSetpref _ = False is_filepatch _ = Nothing -- TODO: PrimConstruct makes no sense for V3 prims instance PrimConstruct Prim where addfile _ = error "PrimConstruct addfile" rmfile _ = error "PrimConstruct rmfile" adddir _ = error "PrimConstruct adddir" rmdir _ = error "PrimConstruct rmdir" move _ _ = error "PrimConstruct move" changepref _ _ _ = error "PrimConstruct changepref" hunk _ _ _ _ = error "PrimConstruct hunk" tokreplace _ _ _ _ = error "PrimConstruct tokreplace" binary _ _ _ = error "PrimConstruct binary" primFromHunk _ = error "PrimConstruct primFromHunk" anIdentity = Identity instance IsHunk Prim where isHunk _ = Nothing instance Invert Prim where invert (BinaryHunk x h) = BinaryHunk x $ invertHunk h invert (TextHunk x h) = TextHunk x $ invertHunk h invert (Manifest x y) = Demanifest x y invert (Demanifest x y) = Manifest x y invert (Move x y z) = Move x z y invert Identity = Identity instance PatchInspect Prim where -- We don't need this for V3. Slashes are not allowed in Manifest and -- Demanifest patches and nothing else uses working-copy paths. listTouchedFiles _ = [] -- TODO (used for --match 'hunk ...', presumably) hunkMatches _ _ = False instance MyEq Prim where unsafeCompare (BinaryHunk a b) (BinaryHunk c d) = a == c && b `unsafeCompare` d unsafeCompare (TextHunk a b) (TextHunk c d) = a == c && b `unsafeCompare` d unsafeCompare (Manifest a b) (Manifest c d) = a == c && b == d unsafeCompare (Demanifest a b) (Demanifest c d) = a == c && b == d unsafeCompare Identity Identity = True unsafeCompare _ _ = False instance Eq (Prim C(x y)) where (==) = unsafeCompare