module Data.SafeCopy.Instances where import Data.SafeCopy.Types import Data.Word import Data.Int import Data.Maybe import Data.Binary import Data.Binary.Put import Data.Binary.Get import qualified Data.Map as Map import qualified Data.IntMap as IntMap import qualified Data.Set as Set import qualified Data.ByteString.Lazy.Char8 as L import qualified Data.ByteString.Char8 as B import Control.Monad instance SafeCopy a => SafeCopy [a] where mode = Primitive getCopy = contain $ do n <- get getSafeGet >>= replicateM n putCopy lst = contain $ do put (length lst) getSafePut >>= forM_ lst instance SafeCopy a => SafeCopy (Maybe a) where mode = Primitive getCopy = contain $ do n <- get if n then liftM Just safeGet else return Nothing putCopy (Just a) = contain $ put True >> safePut a putCopy Nothing = contain $ put False instance (SafeCopy a, Ord a) => SafeCopy (Set.Set a) where getCopy = contain $ fmap Set.fromList safeGet putCopy = contain . safePut . Set.toList instance (SafeCopy a,SafeCopy b, Ord a) => SafeCopy (Map.Map a b) where getCopy = contain $ fmap Map.fromList safeGet putCopy = contain . safePut . Map.toList instance (SafeCopy a) => SafeCopy (IntMap.IntMap a) where getCopy = contain $ fmap IntMap.fromList safeGet putCopy = contain . safePut . IntMap.toList instance (SafeCopy a, SafeCopy b) => SafeCopy (a,b) where mode = Primitive getCopy = contain $ liftM2 (,) safeGet safeGet putCopy (a,b) = contain $ safePut a >> safePut b instance (SafeCopy a, SafeCopy b, SafeCopy c) => SafeCopy (a,b,c) where mode = Primitive getCopy = contain $ liftM3 (,,) safeGet safeGet safeGet putCopy (a,b,c) = contain $ safePut a >> safePut b >> safePut c instance (SafeCopy a, SafeCopy b, SafeCopy c, SafeCopy d) => SafeCopy (a,b,c,d) where mode = Primitive getCopy = contain $ liftM4 (,,,) safeGet safeGet safeGet safeGet putCopy (a,b,c,d) = contain $ safePut a >> safePut b >> safePut c >> safePut d instance SafeCopy Int where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy Integer where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy Float where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy Double where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy L.ByteString where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy B.ByteString where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy Char where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy Word8 where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy Word16 where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy Word32 where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy Word64 where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy Ordering where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy Int8 where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy Int16 where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy Int32 where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy Int64 where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy () where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance SafeCopy Bool where mode = Primitive; getCopy = contain $ get; putCopy = contain . put instance (SafeCopy a, SafeCopy b) => SafeCopy (Either a b) where mode = Primitive getCopy = contain $ do n <- get if n then liftM Right safeGet else liftM Left safeGet putCopy (Right a) = contain $ put True >> safePut a putCopy (Left a) = contain $ put False >> safePut a data Test1 = Test1 deriving (Read,Show) data Test2 = Test2 [Int] deriving (Read,Show) data Test3 = Test3 [Integer] deriving (Read,Show) data Test4 = Test4 [Sub2] deriving (Read,Show) data Sub1 = Sub1 Integer deriving (Read,Show) data Sub2 = Sub2 Int deriving (Read,Show) instance SafeCopy Test1 where getCopy = contain $ return Test1; putCopy _ = contain $ return () instance SafeCopy Test2 where version = 2 mode = Extension (mkPrevious (Proxy :: Proxy Test1)) getCopy = contain $ fmap Test2 get putCopy (Test2 lst) = contain $ put lst instance Migrate Test1 Test2 where migrate Test1 = Test2 [] instance SafeCopy Test3 where version = 3 mode = Extension (mkPrevious (Proxy :: Proxy Test2)) getCopy = contain $ fmap Test3 get putCopy (Test3 lst) = contain $ put lst instance Migrate Test2 Test3 where migrate (Test2 lst) = Test3 (map fromIntegral lst) instance SafeCopy Test4 where version = 4 mode = Extension (mkPrevious (Proxy :: Proxy Test3)) getCopy = contain $ fmap Test4 safeGet putCopy (Test4 lst) = contain $ safePut lst instance Migrate Test3 Test4 where migrate (Test3 lst) = Test4 (map Sub2 $ map fromIntegral lst) instance SafeCopy Sub1 where getCopy = contain $ fmap Sub1 get putCopy (Sub1 n) = contain $ put n instance Migrate Sub1 Sub2 where migrate (Sub1 n) = Sub2 (fromIntegral n) instance SafeCopy Sub2 where version = 2 mode = Extension (mkPrevious (Proxy :: Proxy Sub1)) getCopy = contain $ fmap Sub2 get putCopy (Sub2 n) = contain $ put n