{-# LANGUAGE DataKinds, TypeFamilies, UndecidableInstances #-}

{-|
Convenience interface to enable defining edits at offsets with some optional
safety checks.

Redefines some types to enable us to easily leverage Aeson's generic JSON schema
deriving. That sadly means we can't use some of the interesting offset plumbing.

TODO I should definitely bite the bullet and use the plumbing now that it's so
cool.
-}

module BytePatch.Pretty
  (
  -- * Core types
    CommonMultiEdits(..)
  , MultiEdit(..)
  , EditOffset(..)

  -- * Convenience functions
  , normalizeSimple

  -- * Low-level interface
  , applyBaseOffset
  , listAlgebraConcatEtc
  , normalize
  ) where

import           BytePatch.Core
import           BytePatch.Pretty.PatchRep

import qualified Data.ByteString            as BS
import           Data.Maybe                 ( fromMaybe )
import           GHC.Generics               ( Generic )
import           GHC.Natural

type Bytes = BS.ByteString

-- | A list of 'MultiEdit's with some common configuration.
data CommonMultiEdits a = CommonMultiEdits
  { forall a. CommonMultiEdits a -> Maybe (SeekRep 'CursorSeek)
cmesBaseOffset :: Maybe (SeekRep 'CursorSeek)
  -- ^
  -- The base offset from which all offsets are located. An actual offset is
  -- calculated by adding the base offset to an offset. Actual offsets below 0
  -- are invalid, meaning for an offset @o@ with base offset @bo@, the actual
  -- offset is only valid when @o >= bo@. Negative base offsets are allowed.

  , forall a. CommonMultiEdits a -> [MultiEdit 'CursorSeek a]
cmesEdits :: [MultiEdit 'CursorSeek a]
  } deriving (CommonMultiEdits a -> CommonMultiEdits a -> Bool
(CommonMultiEdits a -> CommonMultiEdits a -> Bool)
-> (CommonMultiEdits a -> CommonMultiEdits a -> Bool)
-> Eq (CommonMultiEdits a)
forall a. Eq a => CommonMultiEdits a -> CommonMultiEdits a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CommonMultiEdits a -> CommonMultiEdits a -> Bool
$c/= :: forall a. Eq a => CommonMultiEdits a -> CommonMultiEdits a -> Bool
== :: CommonMultiEdits a -> CommonMultiEdits a -> Bool
$c== :: forall a. Eq a => CommonMultiEdits a -> CommonMultiEdits a -> Bool
Eq, Int -> CommonMultiEdits a -> ShowS
[CommonMultiEdits a] -> ShowS
CommonMultiEdits a -> String
(Int -> CommonMultiEdits a -> ShowS)
-> (CommonMultiEdits a -> String)
-> ([CommonMultiEdits a] -> ShowS)
-> Show (CommonMultiEdits a)
forall a. Show a => Int -> CommonMultiEdits a -> ShowS
forall a. Show a => [CommonMultiEdits a] -> ShowS
forall a. Show a => CommonMultiEdits a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CommonMultiEdits a] -> ShowS
$cshowList :: forall a. Show a => [CommonMultiEdits a] -> ShowS
show :: CommonMultiEdits a -> String
$cshow :: forall a. Show a => CommonMultiEdits a -> String
showsPrec :: Int -> CommonMultiEdits a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> CommonMultiEdits a -> ShowS
Show, (forall x. CommonMultiEdits a -> Rep (CommonMultiEdits a) x)
-> (forall x. Rep (CommonMultiEdits a) x -> CommonMultiEdits a)
-> Generic (CommonMultiEdits a)
forall x. Rep (CommonMultiEdits a) x -> CommonMultiEdits a
forall x. CommonMultiEdits a -> Rep (CommonMultiEdits a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (CommonMultiEdits a) x -> CommonMultiEdits a
forall a x. CommonMultiEdits a -> Rep (CommonMultiEdits a) x
$cto :: forall a x. Rep (CommonMultiEdits a) x -> CommonMultiEdits a
$cfrom :: forall a x. CommonMultiEdits a -> Rep (CommonMultiEdits a) x
Generic, (forall a b. (a -> b) -> CommonMultiEdits a -> CommonMultiEdits b)
-> (forall a b. a -> CommonMultiEdits b -> CommonMultiEdits a)
-> Functor CommonMultiEdits
forall a b. a -> CommonMultiEdits b -> CommonMultiEdits a
forall a b. (a -> b) -> CommonMultiEdits a -> CommonMultiEdits b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> CommonMultiEdits b -> CommonMultiEdits a
$c<$ :: forall a b. a -> CommonMultiEdits b -> CommonMultiEdits a
fmap :: forall a b. (a -> b) -> CommonMultiEdits a -> CommonMultiEdits b
$cfmap :: forall a b. (a -> b) -> CommonMultiEdits a -> CommonMultiEdits b
Functor, (forall m. Monoid m => CommonMultiEdits m -> m)
-> (forall m a. Monoid m => (a -> m) -> CommonMultiEdits a -> m)
-> (forall m a. Monoid m => (a -> m) -> CommonMultiEdits a -> m)
-> (forall a b. (a -> b -> b) -> b -> CommonMultiEdits a -> b)
-> (forall a b. (a -> b -> b) -> b -> CommonMultiEdits a -> b)
-> (forall b a. (b -> a -> b) -> b -> CommonMultiEdits a -> b)
-> (forall b a. (b -> a -> b) -> b -> CommonMultiEdits a -> b)
-> (forall a. (a -> a -> a) -> CommonMultiEdits a -> a)
-> (forall a. (a -> a -> a) -> CommonMultiEdits a -> a)
-> (forall a. CommonMultiEdits a -> [a])
-> (forall a. CommonMultiEdits a -> Bool)
-> (forall a. CommonMultiEdits a -> Int)
-> (forall a. Eq a => a -> CommonMultiEdits a -> Bool)
-> (forall a. Ord a => CommonMultiEdits a -> a)
-> (forall a. Ord a => CommonMultiEdits a -> a)
-> (forall a. Num a => CommonMultiEdits a -> a)
-> (forall a. Num a => CommonMultiEdits a -> a)
-> Foldable CommonMultiEdits
forall a. Eq a => a -> CommonMultiEdits a -> Bool
forall a. Num a => CommonMultiEdits a -> a
forall a. Ord a => CommonMultiEdits a -> a
forall m. Monoid m => CommonMultiEdits m -> m
forall a. CommonMultiEdits a -> Bool
forall a. CommonMultiEdits a -> Int
forall a. CommonMultiEdits a -> [a]
forall a. (a -> a -> a) -> CommonMultiEdits a -> a
forall m a. Monoid m => (a -> m) -> CommonMultiEdits a -> m
forall b a. (b -> a -> b) -> b -> CommonMultiEdits a -> b
forall a b. (a -> b -> b) -> b -> CommonMultiEdits a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: forall a. Num a => CommonMultiEdits a -> a
$cproduct :: forall a. Num a => CommonMultiEdits a -> a
sum :: forall a. Num a => CommonMultiEdits a -> a
$csum :: forall a. Num a => CommonMultiEdits a -> a
minimum :: forall a. Ord a => CommonMultiEdits a -> a
$cminimum :: forall a. Ord a => CommonMultiEdits a -> a
maximum :: forall a. Ord a => CommonMultiEdits a -> a
$cmaximum :: forall a. Ord a => CommonMultiEdits a -> a
elem :: forall a. Eq a => a -> CommonMultiEdits a -> Bool
$celem :: forall a. Eq a => a -> CommonMultiEdits a -> Bool
length :: forall a. CommonMultiEdits a -> Int
$clength :: forall a. CommonMultiEdits a -> Int
null :: forall a. CommonMultiEdits a -> Bool
$cnull :: forall a. CommonMultiEdits a -> Bool
toList :: forall a. CommonMultiEdits a -> [a]
$ctoList :: forall a. CommonMultiEdits a -> [a]
foldl1 :: forall a. (a -> a -> a) -> CommonMultiEdits a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> CommonMultiEdits a -> a
foldr1 :: forall a. (a -> a -> a) -> CommonMultiEdits a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> CommonMultiEdits a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> CommonMultiEdits a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> CommonMultiEdits a -> b
foldl :: forall b a. (b -> a -> b) -> b -> CommonMultiEdits a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> CommonMultiEdits a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> CommonMultiEdits a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> CommonMultiEdits a -> b
foldr :: forall a b. (a -> b -> b) -> b -> CommonMultiEdits a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> CommonMultiEdits a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> CommonMultiEdits a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> CommonMultiEdits a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> CommonMultiEdits a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> CommonMultiEdits a -> m
fold :: forall m. Monoid m => CommonMultiEdits m -> m
$cfold :: forall m. Monoid m => CommonMultiEdits m -> m
Foldable, Functor CommonMultiEdits
Foldable CommonMultiEdits
Functor CommonMultiEdits
-> Foldable CommonMultiEdits
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> CommonMultiEdits a -> f (CommonMultiEdits b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    CommonMultiEdits (f a) -> f (CommonMultiEdits a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> CommonMultiEdits a -> m (CommonMultiEdits b))
-> (forall (m :: * -> *) a.
    Monad m =>
    CommonMultiEdits (m a) -> m (CommonMultiEdits a))
-> Traversable CommonMultiEdits
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
CommonMultiEdits (m a) -> m (CommonMultiEdits a)
forall (f :: * -> *) a.
Applicative f =>
CommonMultiEdits (f a) -> f (CommonMultiEdits a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> CommonMultiEdits a -> m (CommonMultiEdits b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> CommonMultiEdits a -> f (CommonMultiEdits b)
sequence :: forall (m :: * -> *) a.
Monad m =>
CommonMultiEdits (m a) -> m (CommonMultiEdits a)
$csequence :: forall (m :: * -> *) a.
Monad m =>
CommonMultiEdits (m a) -> m (CommonMultiEdits a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> CommonMultiEdits a -> m (CommonMultiEdits b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> CommonMultiEdits a -> m (CommonMultiEdits b)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
CommonMultiEdits (f a) -> f (CommonMultiEdits a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
CommonMultiEdits (f a) -> f (CommonMultiEdits a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> CommonMultiEdits a -> f (CommonMultiEdits b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> CommonMultiEdits a -> f (CommonMultiEdits b)
Traversable)

-- | A single edit to be applied at a list of offsets.
data MultiEdit (s :: SeekKind) a = MultiEdit
  { forall (s :: SeekKind) a. MultiEdit s a -> a
meData :: a              -- ^ The value (e.g. bytes, text) to add.
  , forall (s :: SeekKind) a. MultiEdit s a -> [EditOffset s a]
meAt   :: [EditOffset s a] -- ^ Offsets to apply edit at.
  } deriving ((forall x. MultiEdit s a -> Rep (MultiEdit s a) x)
-> (forall x. Rep (MultiEdit s a) x -> MultiEdit s a)
-> Generic (MultiEdit s a)
forall x. Rep (MultiEdit s a) x -> MultiEdit s a
forall x. MultiEdit s a -> Rep (MultiEdit s a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (s :: SeekKind) a x. Rep (MultiEdit s a) x -> MultiEdit s a
forall (s :: SeekKind) a x. MultiEdit s a -> Rep (MultiEdit s a) x
$cto :: forall (s :: SeekKind) a x. Rep (MultiEdit s a) x -> MultiEdit s a
$cfrom :: forall (s :: SeekKind) a x. MultiEdit s a -> Rep (MultiEdit s a) x
Generic, (forall a b. (a -> b) -> MultiEdit s a -> MultiEdit s b)
-> (forall a b. a -> MultiEdit s b -> MultiEdit s a)
-> Functor (MultiEdit s)
forall a b. a -> MultiEdit s b -> MultiEdit s a
forall a b. (a -> b) -> MultiEdit s a -> MultiEdit s b
forall (s :: SeekKind) a b. a -> MultiEdit s b -> MultiEdit s a
forall (s :: SeekKind) a b.
(a -> b) -> MultiEdit s a -> MultiEdit s b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> MultiEdit s b -> MultiEdit s a
$c<$ :: forall (s :: SeekKind) a b. a -> MultiEdit s b -> MultiEdit s a
fmap :: forall a b. (a -> b) -> MultiEdit s a -> MultiEdit s b
$cfmap :: forall (s :: SeekKind) a b.
(a -> b) -> MultiEdit s a -> MultiEdit s b
Functor, (forall m. Monoid m => MultiEdit s m -> m)
-> (forall m a. Monoid m => (a -> m) -> MultiEdit s a -> m)
-> (forall m a. Monoid m => (a -> m) -> MultiEdit s a -> m)
-> (forall a b. (a -> b -> b) -> b -> MultiEdit s a -> b)
-> (forall a b. (a -> b -> b) -> b -> MultiEdit s a -> b)
-> (forall b a. (b -> a -> b) -> b -> MultiEdit s a -> b)
-> (forall b a. (b -> a -> b) -> b -> MultiEdit s a -> b)
-> (forall a. (a -> a -> a) -> MultiEdit s a -> a)
-> (forall a. (a -> a -> a) -> MultiEdit s a -> a)
-> (forall a. MultiEdit s a -> [a])
-> (forall a. MultiEdit s a -> Bool)
-> (forall a. MultiEdit s a -> Int)
-> (forall a. Eq a => a -> MultiEdit s a -> Bool)
-> (forall a. Ord a => MultiEdit s a -> a)
-> (forall a. Ord a => MultiEdit s a -> a)
-> (forall a. Num a => MultiEdit s a -> a)
-> (forall a. Num a => MultiEdit s a -> a)
-> Foldable (MultiEdit s)
forall a. Eq a => a -> MultiEdit s a -> Bool
forall a. Num a => MultiEdit s a -> a
forall a. Ord a => MultiEdit s a -> a
forall m. Monoid m => MultiEdit s m -> m
forall a. MultiEdit s a -> Bool
forall a. MultiEdit s a -> Int
forall a. MultiEdit s a -> [a]
forall a. (a -> a -> a) -> MultiEdit s a -> a
forall m a. Monoid m => (a -> m) -> MultiEdit s a -> m
forall b a. (b -> a -> b) -> b -> MultiEdit s a -> b
forall a b. (a -> b -> b) -> b -> MultiEdit s a -> b
forall (s :: SeekKind) a. Eq a => a -> MultiEdit s a -> Bool
forall (s :: SeekKind) a. Num a => MultiEdit s a -> a
forall (s :: SeekKind) a. Ord a => MultiEdit s a -> a
forall (s :: SeekKind) m. Monoid m => MultiEdit s m -> m
forall (s :: SeekKind) a. MultiEdit s a -> Bool
forall (s :: SeekKind) a. MultiEdit s a -> Int
forall (s :: SeekKind) a. MultiEdit s a -> [a]
forall (s :: SeekKind) a. (a -> a -> a) -> MultiEdit s a -> a
forall (s :: SeekKind) m a.
Monoid m =>
(a -> m) -> MultiEdit s a -> m
forall (s :: SeekKind) b a.
(b -> a -> b) -> b -> MultiEdit s a -> b
forall (s :: SeekKind) a b.
(a -> b -> b) -> b -> MultiEdit s a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: forall a. Num a => MultiEdit s a -> a
$cproduct :: forall (s :: SeekKind) a. Num a => MultiEdit s a -> a
sum :: forall a. Num a => MultiEdit s a -> a
$csum :: forall (s :: SeekKind) a. Num a => MultiEdit s a -> a
minimum :: forall a. Ord a => MultiEdit s a -> a
$cminimum :: forall (s :: SeekKind) a. Ord a => MultiEdit s a -> a
maximum :: forall a. Ord a => MultiEdit s a -> a
$cmaximum :: forall (s :: SeekKind) a. Ord a => MultiEdit s a -> a
elem :: forall a. Eq a => a -> MultiEdit s a -> Bool
$celem :: forall (s :: SeekKind) a. Eq a => a -> MultiEdit s a -> Bool
length :: forall a. MultiEdit s a -> Int
$clength :: forall (s :: SeekKind) a. MultiEdit s a -> Int
null :: forall a. MultiEdit s a -> Bool
$cnull :: forall (s :: SeekKind) a. MultiEdit s a -> Bool
toList :: forall a. MultiEdit s a -> [a]
$ctoList :: forall (s :: SeekKind) a. MultiEdit s a -> [a]
foldl1 :: forall a. (a -> a -> a) -> MultiEdit s a -> a
$cfoldl1 :: forall (s :: SeekKind) a. (a -> a -> a) -> MultiEdit s a -> a
foldr1 :: forall a. (a -> a -> a) -> MultiEdit s a -> a
$cfoldr1 :: forall (s :: SeekKind) a. (a -> a -> a) -> MultiEdit s a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> MultiEdit s a -> b
$cfoldl' :: forall (s :: SeekKind) b a.
(b -> a -> b) -> b -> MultiEdit s a -> b
foldl :: forall b a. (b -> a -> b) -> b -> MultiEdit s a -> b
$cfoldl :: forall (s :: SeekKind) b a.
(b -> a -> b) -> b -> MultiEdit s a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> MultiEdit s a -> b
$cfoldr' :: forall (s :: SeekKind) a b.
(a -> b -> b) -> b -> MultiEdit s a -> b
foldr :: forall a b. (a -> b -> b) -> b -> MultiEdit s a -> b
$cfoldr :: forall (s :: SeekKind) a b.
(a -> b -> b) -> b -> MultiEdit s a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> MultiEdit s a -> m
$cfoldMap' :: forall (s :: SeekKind) m a.
Monoid m =>
(a -> m) -> MultiEdit s a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> MultiEdit s a -> m
$cfoldMap :: forall (s :: SeekKind) m a.
Monoid m =>
(a -> m) -> MultiEdit s a -> m
fold :: forall m. Monoid m => MultiEdit s m -> m
$cfold :: forall (s :: SeekKind) m. Monoid m => MultiEdit s m -> m
Foldable, Functor (MultiEdit s)
Foldable (MultiEdit s)
Functor (MultiEdit s)
-> Foldable (MultiEdit s)
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> MultiEdit s a -> f (MultiEdit s b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    MultiEdit s (f a) -> f (MultiEdit s a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> MultiEdit s a -> m (MultiEdit s b))
-> (forall (m :: * -> *) a.
    Monad m =>
    MultiEdit s (m a) -> m (MultiEdit s a))
-> Traversable (MultiEdit s)
forall (s :: SeekKind). Functor (MultiEdit s)
forall (s :: SeekKind). Foldable (MultiEdit s)
forall (s :: SeekKind) (m :: * -> *) a.
Monad m =>
MultiEdit s (m a) -> m (MultiEdit s a)
forall (s :: SeekKind) (f :: * -> *) a.
Applicative f =>
MultiEdit s (f a) -> f (MultiEdit s a)
forall (s :: SeekKind) (m :: * -> *) a b.
Monad m =>
(a -> m b) -> MultiEdit s a -> m (MultiEdit s b)
forall (s :: SeekKind) (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> MultiEdit s a -> f (MultiEdit s b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
MultiEdit s (m a) -> m (MultiEdit s a)
forall (f :: * -> *) a.
Applicative f =>
MultiEdit s (f a) -> f (MultiEdit s a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> MultiEdit s a -> m (MultiEdit s b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> MultiEdit s a -> f (MultiEdit s b)
sequence :: forall (m :: * -> *) a.
Monad m =>
MultiEdit s (m a) -> m (MultiEdit s a)
$csequence :: forall (s :: SeekKind) (m :: * -> *) a.
Monad m =>
MultiEdit s (m a) -> m (MultiEdit s a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> MultiEdit s a -> m (MultiEdit s b)
$cmapM :: forall (s :: SeekKind) (m :: * -> *) a b.
Monad m =>
(a -> m b) -> MultiEdit s a -> m (MultiEdit s b)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
MultiEdit s (f a) -> f (MultiEdit s a)
$csequenceA :: forall (s :: SeekKind) (f :: * -> *) a.
Applicative f =>
MultiEdit s (f a) -> f (MultiEdit s a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> MultiEdit s a -> f (MultiEdit s b)
$ctraverse :: forall (s :: SeekKind) (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> MultiEdit s a -> f (MultiEdit s b)
Traversable)

deriving instance (Eq (SeekRep s), Eq a) => Eq (MultiEdit s a)
deriving instance (Show (SeekRep s), Show a) => Show (MultiEdit s a)

-- | An edit offset, with metadata to use for preparing and applying the edit.
data EditOffset (s :: SeekKind) a = EditOffset
  { forall (s :: SeekKind) a. EditOffset s a -> SeekRep s
eoOffset    :: SeekRep s
  -- ^ Stream offset for edit.

  , forall (s :: SeekKind) a.
EditOffset s a -> Maybe (SeekRep 'AbsSeek)
eoAbsOffset :: Maybe (SeekRep 'AbsSeek)
  -- ^ Absolute stream offset for edit. Used for checking against actual offset.

  , forall (s :: SeekKind) a. EditOffset s a -> Maybe Natural
eoMaxLength :: Maybe Natural
  -- ^ Maximum number of bytes allowed to write at this offset.

  , forall (s :: SeekKind) a. EditOffset s a -> Maybe (EditMeta a)
eoEditMeta  :: Maybe (EditMeta a)
  -- ^ Optional apply time metadata for the edit at this offset.

  } deriving ((forall x. EditOffset s a -> Rep (EditOffset s a) x)
-> (forall x. Rep (EditOffset s a) x -> EditOffset s a)
-> Generic (EditOffset s a)
forall x. Rep (EditOffset s a) x -> EditOffset s a
forall x. EditOffset s a -> Rep (EditOffset s a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (s :: SeekKind) a x.
Rep (EditOffset s a) x -> EditOffset s a
forall (s :: SeekKind) a x.
EditOffset s a -> Rep (EditOffset s a) x
$cto :: forall (s :: SeekKind) a x.
Rep (EditOffset s a) x -> EditOffset s a
$cfrom :: forall (s :: SeekKind) a x.
EditOffset s a -> Rep (EditOffset s a) x
Generic, (forall a b. (a -> b) -> EditOffset s a -> EditOffset s b)
-> (forall a b. a -> EditOffset s b -> EditOffset s a)
-> Functor (EditOffset s)
forall a b. a -> EditOffset s b -> EditOffset s a
forall a b. (a -> b) -> EditOffset s a -> EditOffset s b
forall (s :: SeekKind) a b. a -> EditOffset s b -> EditOffset s a
forall (s :: SeekKind) a b.
(a -> b) -> EditOffset s a -> EditOffset s b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> EditOffset s b -> EditOffset s a
$c<$ :: forall (s :: SeekKind) a b. a -> EditOffset s b -> EditOffset s a
fmap :: forall a b. (a -> b) -> EditOffset s a -> EditOffset s b
$cfmap :: forall (s :: SeekKind) a b.
(a -> b) -> EditOffset s a -> EditOffset s b
Functor, (forall m. Monoid m => EditOffset s m -> m)
-> (forall m a. Monoid m => (a -> m) -> EditOffset s a -> m)
-> (forall m a. Monoid m => (a -> m) -> EditOffset s a -> m)
-> (forall a b. (a -> b -> b) -> b -> EditOffset s a -> b)
-> (forall a b. (a -> b -> b) -> b -> EditOffset s a -> b)
-> (forall b a. (b -> a -> b) -> b -> EditOffset s a -> b)
-> (forall b a. (b -> a -> b) -> b -> EditOffset s a -> b)
-> (forall a. (a -> a -> a) -> EditOffset s a -> a)
-> (forall a. (a -> a -> a) -> EditOffset s a -> a)
-> (forall a. EditOffset s a -> [a])
-> (forall a. EditOffset s a -> Bool)
-> (forall a. EditOffset s a -> Int)
-> (forall a. Eq a => a -> EditOffset s a -> Bool)
-> (forall a. Ord a => EditOffset s a -> a)
-> (forall a. Ord a => EditOffset s a -> a)
-> (forall a. Num a => EditOffset s a -> a)
-> (forall a. Num a => EditOffset s a -> a)
-> Foldable (EditOffset s)
forall a. Eq a => a -> EditOffset s a -> Bool
forall a. Num a => EditOffset s a -> a
forall a. Ord a => EditOffset s a -> a
forall m. Monoid m => EditOffset s m -> m
forall a. EditOffset s a -> Bool
forall a. EditOffset s a -> Int
forall a. EditOffset s a -> [a]
forall a. (a -> a -> a) -> EditOffset s a -> a
forall m a. Monoid m => (a -> m) -> EditOffset s a -> m
forall b a. (b -> a -> b) -> b -> EditOffset s a -> b
forall a b. (a -> b -> b) -> b -> EditOffset s a -> b
forall (s :: SeekKind) a. Eq a => a -> EditOffset s a -> Bool
forall (s :: SeekKind) a. Num a => EditOffset s a -> a
forall (s :: SeekKind) a. Ord a => EditOffset s a -> a
forall (s :: SeekKind) m. Monoid m => EditOffset s m -> m
forall (s :: SeekKind) a. EditOffset s a -> Bool
forall (s :: SeekKind) a. EditOffset s a -> Int
forall (s :: SeekKind) a. EditOffset s a -> [a]
forall (s :: SeekKind) a. (a -> a -> a) -> EditOffset s a -> a
forall (s :: SeekKind) m a.
Monoid m =>
(a -> m) -> EditOffset s a -> m
forall (s :: SeekKind) b a.
(b -> a -> b) -> b -> EditOffset s a -> b
forall (s :: SeekKind) a b.
(a -> b -> b) -> b -> EditOffset s a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: forall a. Num a => EditOffset s a -> a
$cproduct :: forall (s :: SeekKind) a. Num a => EditOffset s a -> a
sum :: forall a. Num a => EditOffset s a -> a
$csum :: forall (s :: SeekKind) a. Num a => EditOffset s a -> a
minimum :: forall a. Ord a => EditOffset s a -> a
$cminimum :: forall (s :: SeekKind) a. Ord a => EditOffset s a -> a
maximum :: forall a. Ord a => EditOffset s a -> a
$cmaximum :: forall (s :: SeekKind) a. Ord a => EditOffset s a -> a
elem :: forall a. Eq a => a -> EditOffset s a -> Bool
$celem :: forall (s :: SeekKind) a. Eq a => a -> EditOffset s a -> Bool
length :: forall a. EditOffset s a -> Int
$clength :: forall (s :: SeekKind) a. EditOffset s a -> Int
null :: forall a. EditOffset s a -> Bool
$cnull :: forall (s :: SeekKind) a. EditOffset s a -> Bool
toList :: forall a. EditOffset s a -> [a]
$ctoList :: forall (s :: SeekKind) a. EditOffset s a -> [a]
foldl1 :: forall a. (a -> a -> a) -> EditOffset s a -> a
$cfoldl1 :: forall (s :: SeekKind) a. (a -> a -> a) -> EditOffset s a -> a
foldr1 :: forall a. (a -> a -> a) -> EditOffset s a -> a
$cfoldr1 :: forall (s :: SeekKind) a. (a -> a -> a) -> EditOffset s a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> EditOffset s a -> b
$cfoldl' :: forall (s :: SeekKind) b a.
(b -> a -> b) -> b -> EditOffset s a -> b
foldl :: forall b a. (b -> a -> b) -> b -> EditOffset s a -> b
$cfoldl :: forall (s :: SeekKind) b a.
(b -> a -> b) -> b -> EditOffset s a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> EditOffset s a -> b
$cfoldr' :: forall (s :: SeekKind) a b.
(a -> b -> b) -> b -> EditOffset s a -> b
foldr :: forall a b. (a -> b -> b) -> b -> EditOffset s a -> b
$cfoldr :: forall (s :: SeekKind) a b.
(a -> b -> b) -> b -> EditOffset s a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> EditOffset s a -> m
$cfoldMap' :: forall (s :: SeekKind) m a.
Monoid m =>
(a -> m) -> EditOffset s a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> EditOffset s a -> m
$cfoldMap :: forall (s :: SeekKind) m a.
Monoid m =>
(a -> m) -> EditOffset s a -> m
fold :: forall m. Monoid m => EditOffset s m -> m
$cfold :: forall (s :: SeekKind) m. Monoid m => EditOffset s m -> m
Foldable, Functor (EditOffset s)
Foldable (EditOffset s)
Functor (EditOffset s)
-> Foldable (EditOffset s)
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> EditOffset s a -> f (EditOffset s b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    EditOffset s (f a) -> f (EditOffset s a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> EditOffset s a -> m (EditOffset s b))
-> (forall (m :: * -> *) a.
    Monad m =>
    EditOffset s (m a) -> m (EditOffset s a))
-> Traversable (EditOffset s)
forall (s :: SeekKind). Functor (EditOffset s)
forall (s :: SeekKind). Foldable (EditOffset s)
forall (s :: SeekKind) (m :: * -> *) a.
Monad m =>
EditOffset s (m a) -> m (EditOffset s a)
forall (s :: SeekKind) (f :: * -> *) a.
Applicative f =>
EditOffset s (f a) -> f (EditOffset s a)
forall (s :: SeekKind) (m :: * -> *) a b.
Monad m =>
(a -> m b) -> EditOffset s a -> m (EditOffset s b)
forall (s :: SeekKind) (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> EditOffset s a -> f (EditOffset s b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
EditOffset s (m a) -> m (EditOffset s a)
forall (f :: * -> *) a.
Applicative f =>
EditOffset s (f a) -> f (EditOffset s a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> EditOffset s a -> m (EditOffset s b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> EditOffset s a -> f (EditOffset s b)
sequence :: forall (m :: * -> *) a.
Monad m =>
EditOffset s (m a) -> m (EditOffset s a)
$csequence :: forall (s :: SeekKind) (m :: * -> *) a.
Monad m =>
EditOffset s (m a) -> m (EditOffset s a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> EditOffset s a -> m (EditOffset s b)
$cmapM :: forall (s :: SeekKind) (m :: * -> *) a b.
Monad m =>
(a -> m b) -> EditOffset s a -> m (EditOffset s b)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
EditOffset s (f a) -> f (EditOffset s a)
$csequenceA :: forall (s :: SeekKind) (f :: * -> *) a.
Applicative f =>
EditOffset s (f a) -> f (EditOffset s a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> EditOffset s a -> f (EditOffset s b)
$ctraverse :: forall (s :: SeekKind) (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> EditOffset s a -> f (EditOffset s b)
Traversable)

deriving instance (Eq (SeekRep s), Eq a) => Eq (EditOffset s a)
deriving instance (Show (SeekRep s), Show a) => Show (EditOffset s a)

-- | Normalize a list of 'CommonMultiEdits's, discarding everything on error.
normalizeSimple :: PatchRep a => [CommonMultiEdits a] -> Maybe [Patch 'AbsSeek Bytes]
normalizeSimple :: forall a.
PatchRep a =>
[CommonMultiEdits a] -> Maybe [Patch 'AbsSeek Bytes]
normalizeSimple [CommonMultiEdits a]
cmess =
    let ([MultiEdit 'AbsSeek a]
p, [(EditOffset 'CursorSeek a, Integer)]
errs) = [(Integer, [(MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])])]
-> ([MultiEdit 'AbsSeek a], [(EditOffset 'CursorSeek a, Integer)])
forall a b c. [(a, [(b, [c])])] -> ([b], [(c, a)])
listAlgebraConcatEtc ([(Integer, [(MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])])]
 -> ([MultiEdit 'AbsSeek a], [(EditOffset 'CursorSeek a, Integer)]))
-> ([CommonMultiEdits a]
    -> [(Integer,
         [(MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])])])
-> [CommonMultiEdits a]
-> ([MultiEdit 'AbsSeek a], [(EditOffset 'CursorSeek a, Integer)])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CommonMultiEdits a
 -> (Integer, [(MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])]))
-> [CommonMultiEdits a]
-> [(Integer,
     [(MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])])]
forall a b. (a -> b) -> [a] -> [b]
map CommonMultiEdits a
-> (Integer, [(MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])])
forall a.
CommonMultiEdits a
-> (Integer, [(MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])])
applyBaseOffset ([CommonMultiEdits a]
 -> ([MultiEdit 'AbsSeek a], [(EditOffset 'CursorSeek a, Integer)]))
-> [CommonMultiEdits a]
-> ([MultiEdit 'AbsSeek a], [(EditOffset 'CursorSeek a, Integer)])
forall a b. (a -> b) -> a -> b
$ [CommonMultiEdits a]
cmess
     in case [(EditOffset 'CursorSeek a, Integer)]
errs of
          (EditOffset 'CursorSeek a, Integer)
_:[(EditOffset 'CursorSeek a, Integer)]
_ -> Maybe [Patch 'AbsSeek Bytes]
forall a. Maybe a
Nothing
          []  -> [MultiEdit 'AbsSeek a] -> Maybe [Patch 'AbsSeek Bytes]
forall a.
PatchRep a =>
[MultiEdit 'AbsSeek a] -> Maybe [Patch 'AbsSeek Bytes]
normalize [MultiEdit 'AbsSeek a]
p

-- Drops no info, not easy to consume.
applyBaseOffset
    :: CommonMultiEdits a
    -> (Integer, [(MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])])
applyBaseOffset :: forall a.
CommonMultiEdits a
-> (Integer, [(MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])])
applyBaseOffset CommonMultiEdits a
cmes =
    (Integer
baseOffset, Integer
-> [MultiEdit 'CursorSeek a]
-> [(MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])]
forall a.
Integer
-> [MultiEdit 'CursorSeek a]
-> [(MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])]
recalculateMultiPatchOffsets Integer
baseOffset (CommonMultiEdits a -> [MultiEdit 'CursorSeek a]
forall a. CommonMultiEdits a -> [MultiEdit 'CursorSeek a]
cmesEdits CommonMultiEdits a
cmes))
      where baseOffset :: Integer
baseOffset = Integer -> Maybe Integer -> Integer
forall a. a -> Maybe a -> a
fromMaybe Integer
0 (CommonMultiEdits a -> Maybe (SeekRep 'CursorSeek)
forall a. CommonMultiEdits a -> Maybe (SeekRep 'CursorSeek)
cmesBaseOffset CommonMultiEdits a
cmes)

-- lmao this sucks. generalisation bad
listAlgebraConcatEtc :: [(a, [(b, [c])])] -> ([b], [(c, a)])
listAlgebraConcatEtc :: forall a b c. [(a, [(b, [c])])] -> ([b], [(c, a)])
listAlgebraConcatEtc = [([b], [(c, a)])] -> ([b], [(c, a)])
forall a. Monoid a => [a] -> a
mconcat ([([b], [(c, a)])] -> ([b], [(c, a)]))
-> ([(a, [(b, [c])])] -> [([b], [(c, a)])])
-> [(a, [(b, [c])])]
-> ([b], [(c, a)])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, [(b, [c])]) -> ([b], [(c, a)]))
-> [(a, [(b, [c])])] -> [([b], [(c, a)])]
forall a b. (a -> b) -> [a] -> [b]
map (a, [(b, [c])]) -> ([b], [(c, a)])
go
  where
    go :: (a, [(b, [c])]) -> ([b], [(c, a)])
go (a
baseOffset, [(b, [c])]
inps) = [(b, [(c, a)])] -> ([b], [(c, a)])
forall {a}. [(a, [(c, a)])] -> ([a], [(c, a)])
tuplemconcat (((b, [c]) -> (b, [(c, a)])) -> [(b, [c])] -> [(b, [(c, a)])]
forall a b. (a -> b) -> [a] -> [b]
map (a -> (b, [c]) -> (b, [(c, a)])
forall {b} {a} {a}. b -> (a, [a]) -> (a, [(a, b)])
go' a
baseOffset) [(b, [c])]
inps)
    go' :: b -> (a, [a]) -> (a, [(a, b)])
go' b
x (a
mp, [a]
offs) = (a
mp, (a -> (a, b)) -> [a] -> [(a, b)]
forall a b. (a -> b) -> [a] -> [b]
map (\a
o -> (a
o, b
x)) [a]
offs)
    tuplemconcat :: [(a, [(c, a)])] -> ([a], [(c, a)])
tuplemconcat = ((a, [(c, a)]) -> ([a], [(c, a)]) -> ([a], [(c, a)]))
-> ([a], [(c, a)]) -> [(a, [(c, a)])] -> ([a], [(c, a)])
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\(a
a, [(c, a)]
bs) ([a]
as, [(c, a)]
bs') -> (a
aa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
as, [(c, a)]
bs [(c, a)] -> [(c, a)] -> [(c, a)]
forall a. Semigroup a => a -> a -> a
<> [(c, a)]
bs')) ([], [(c, a)]
forall a. Monoid a => a
mempty)

recalculateMultiPatchOffsets
    :: Integer
    -> [MultiEdit 'CursorSeek a]
    -> [(MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])]
recalculateMultiPatchOffsets :: forall a.
Integer
-> [MultiEdit 'CursorSeek a]
-> [(MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])]
recalculateMultiPatchOffsets Integer
baseOffset = (MultiEdit 'CursorSeek a
 -> (MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a]))
-> [MultiEdit 'CursorSeek a]
-> [(MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])]
forall a b. (a -> b) -> [a] -> [b]
map MultiEdit 'CursorSeek a
-> (MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])
forall a.
MultiEdit 'CursorSeek a
-> (MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])
go
  where
    go :: MultiEdit 'CursorSeek a -> (MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])
    go :: forall a.
MultiEdit 'CursorSeek a
-> (MultiEdit 'AbsSeek a, [EditOffset 'CursorSeek a])
go MultiEdit 'CursorSeek a
me =
        let ([EditOffset 'AbsSeek a]
osRecalculated, [EditOffset 'CursorSeek a]
osInvalid) = Integer
-> [EditOffset 'CursorSeek a]
-> ([EditOffset 'AbsSeek a], [EditOffset 'CursorSeek a])
forall a.
Integer
-> [EditOffset 'CursorSeek a]
-> ([EditOffset 'AbsSeek a], [EditOffset 'CursorSeek a])
recalculateOffsets Integer
baseOffset (MultiEdit 'CursorSeek a -> [EditOffset 'CursorSeek a]
forall (s :: SeekKind) a. MultiEdit s a -> [EditOffset s a]
meAt MultiEdit 'CursorSeek a
me)
         in (MultiEdit 'CursorSeek a
me { meAt :: [EditOffset 'AbsSeek a]
meAt = [EditOffset 'AbsSeek a]
osRecalculated }, [EditOffset 'CursorSeek a]
osInvalid)

recalculateOffsets
    :: Integer
    -> [EditOffset 'CursorSeek a]
    -> ([EditOffset 'AbsSeek a], [EditOffset 'CursorSeek a])
recalculateOffsets :: forall a.
Integer
-> [EditOffset 'CursorSeek a]
-> ([EditOffset 'AbsSeek a], [EditOffset 'CursorSeek a])
recalculateOffsets Integer
baseOffset = (EditOffset 'CursorSeek a -> Maybe (EditOffset 'AbsSeek a))
-> [EditOffset 'CursorSeek a]
-> ([EditOffset 'AbsSeek a], [EditOffset 'CursorSeek a])
forall a b. (a -> Maybe b) -> [a] -> ([b], [a])
partitionMaybe EditOffset 'CursorSeek a -> Maybe (EditOffset 'AbsSeek a)
go
  where
    go :: EditOffset 'CursorSeek a -> Maybe (EditOffset 'AbsSeek a)
go EditOffset 'CursorSeek a
o = let actualOffset :: Integer
actualOffset = Integer
baseOffset Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ EditOffset 'CursorSeek a -> SeekRep 'CursorSeek
forall (s :: SeekKind) a. EditOffset s a -> SeekRep s
eoOffset EditOffset 'CursorSeek a
o
            in case Integer -> Maybe Natural
tryIntegerToNatural Integer
actualOffset of
                 Maybe Natural
Nothing -> Maybe (EditOffset 'AbsSeek a)
forall a. Maybe a
Nothing
                 Just Natural
actualOffset' -> EditOffset 'AbsSeek a -> Maybe (EditOffset 'AbsSeek a)
forall a. a -> Maybe a
Just (EditOffset 'AbsSeek a -> Maybe (EditOffset 'AbsSeek a))
-> EditOffset 'AbsSeek a -> Maybe (EditOffset 'AbsSeek a)
forall a b. (a -> b) -> a -> b
$ EditOffset 'CursorSeek a
o { eoOffset :: SeekRep 'AbsSeek
eoOffset = Natural
SeekRep 'AbsSeek
actualOffset' }

tryIntegerToNatural :: Integer -> Maybe Natural
tryIntegerToNatural :: Integer -> Maybe Natural
tryIntegerToNatural Integer
n | Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0     = Maybe Natural
forall a. Maybe a
Nothing
                      | Bool
otherwise = Natural -> Maybe Natural
forall a. a -> Maybe a
Just (Natural -> Maybe Natural) -> Natural -> Maybe Natural
forall a b. (a -> b) -> a -> b
$ Integer -> Natural
naturalFromInteger Integer
n

normalize :: PatchRep a => [MultiEdit 'AbsSeek a] -> Maybe [Patch 'AbsSeek Bytes]
normalize :: forall a.
PatchRep a =>
[MultiEdit 'AbsSeek a] -> Maybe [Patch 'AbsSeek Bytes]
normalize [MultiEdit 'AbsSeek a]
xs = [[Patch 'AbsSeek Bytes]] -> [Patch 'AbsSeek Bytes]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Patch 'AbsSeek Bytes]] -> [Patch 'AbsSeek Bytes])
-> Maybe [[Patch 'AbsSeek Bytes]] -> Maybe [Patch 'AbsSeek Bytes]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MultiEdit 'AbsSeek a -> Maybe [Patch 'AbsSeek Bytes])
-> [MultiEdit 'AbsSeek a] -> Maybe [[Patch 'AbsSeek Bytes]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM MultiEdit 'AbsSeek a -> Maybe [Patch 'AbsSeek Bytes]
forall {a}.
PatchRep a =>
MultiEdit 'AbsSeek a -> Maybe [Patch 'AbsSeek Bytes]
go [MultiEdit 'AbsSeek a]
xs
  where go :: MultiEdit 'AbsSeek a -> Maybe [Patch 'AbsSeek Bytes]
go (MultiEdit a
contents [EditOffset 'AbsSeek a]
os) = (EditOffset 'AbsSeek a -> Maybe (Patch 'AbsSeek Bytes))
-> [EditOffset 'AbsSeek a] -> Maybe [Patch 'AbsSeek Bytes]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (a -> EditOffset 'AbsSeek a -> Maybe (Patch 'AbsSeek Bytes)
forall a.
PatchRep a =>
a -> EditOffset 'AbsSeek a -> Maybe (Patch 'AbsSeek Bytes)
tryMakeSingleReplace a
contents) [EditOffset 'AbsSeek a]
os

-- TODO now can error with "[expected] content has no valid patch rep"
tryMakeSingleReplace :: PatchRep a => a -> EditOffset 'AbsSeek a -> Maybe (Patch 'AbsSeek Bytes)
tryMakeSingleReplace :: forall a.
PatchRep a =>
a -> EditOffset 'AbsSeek a -> Maybe (Patch 'AbsSeek Bytes)
tryMakeSingleReplace a
contents (EditOffset SeekRep 'AbsSeek
os Maybe (SeekRep 'AbsSeek)
maos Maybe Natural
mMaxLen Maybe (EditMeta a)
mMeta) =
    case a -> Either String Bytes
forall a. PatchRep a => a -> Either String Bytes
toPatchRep a
contents of
      Left String
errStr -> String -> Maybe (Patch 'AbsSeek Bytes)
forall a. HasCallStack => String -> a
error String
errStr -- TODO
      Right Bytes
bs ->
        if   Bool
offsetIsCorrect
        then case Maybe Natural
mMaxLen of
               Just Natural
maxLen -> if Bytes -> Int
BS.length Bytes
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Natural
maxLen then Maybe (Patch 'AbsSeek Bytes)
forall a. Maybe a
Nothing else Bytes -> Maybe (Patch 'AbsSeek Bytes)
overwrite Bytes
bs
               Maybe Natural
Nothing     -> Bytes -> Maybe (Patch 'AbsSeek Bytes)
overwrite Bytes
bs
        else Maybe (Patch 'AbsSeek Bytes)
forall a. Maybe a
Nothing
  where
    overwrite :: Bytes -> Maybe (Patch 'AbsSeek Bytes)
overwrite Bytes
bs = case (a -> Either String Bytes)
-> EditMeta a -> Either String (EditMeta Bytes)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse a -> Either String Bytes
forall a. PatchRep a => a -> Either String Bytes
toPatchRep EditMeta a
meta of
                     Left String
errStr -> String -> Maybe (Patch 'AbsSeek Bytes)
forall a. HasCallStack => String -> a
error String
errStr -- TODO
                     Right EditMeta Bytes
meta' ->
                         Patch 'AbsSeek Bytes -> Maybe (Patch 'AbsSeek Bytes)
forall a. a -> Maybe a
Just (Patch 'AbsSeek Bytes -> Maybe (Patch 'AbsSeek Bytes))
-> Patch 'AbsSeek Bytes -> Maybe (Patch 'AbsSeek Bytes)
forall a b. (a -> b) -> a -> b
$ SeekRep 'AbsSeek -> Edit Bytes -> Patch 'AbsSeek Bytes
forall (s :: SeekKind) a. SeekRep s -> Edit a -> Patch s a
Patch SeekRep 'AbsSeek
os (Edit Bytes -> Patch 'AbsSeek Bytes)
-> Edit Bytes -> Patch 'AbsSeek Bytes
forall a b. (a -> b) -> a -> b
$ Edit :: forall a. a -> EditMeta a -> Edit a
Edit { editData :: Bytes
editData = Bytes
bs
                                                , editMeta :: EditMeta Bytes
editMeta = EditMeta Bytes
meta' }
    meta :: EditMeta a
meta = EditMeta a -> Maybe (EditMeta a) -> EditMeta a
forall a. a -> Maybe a -> a
fromMaybe (Maybe Int -> Maybe a -> EditMeta a
forall a. Maybe Int -> Maybe a -> EditMeta a
EditMeta Maybe Int
forall a. Maybe a
Nothing Maybe a
forall a. Maybe a
Nothing) Maybe (EditMeta a)
mMeta
    offsetIsCorrect :: Bool
offsetIsCorrect = case Maybe (SeekRep 'AbsSeek)
maos of Maybe (SeekRep 'AbsSeek)
Nothing  -> Bool
True
                                   Just SeekRep 'AbsSeek
aos -> Natural
SeekRep 'AbsSeek
os Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== Natural
SeekRep 'AbsSeek
aos

--------------------------------------------------------------------------------

-- | Map a failable function over a list, retaining "failed" 'Nothing' results.
partitionMaybe :: (a -> Maybe b) -> [a] -> ([b], [a])
partitionMaybe :: forall a b. (a -> Maybe b) -> [a] -> ([b], [a])
partitionMaybe a -> Maybe b
f =
    (a -> ([b], [a]) -> ([b], [a])) -> ([b], [a]) -> [a] -> ([b], [a])
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\a
x -> (([b], [a]) -> ([b], [a]))
-> (b -> ([b], [a]) -> ([b], [a]))
-> Maybe b
-> ([b], [a])
-> ([b], [a])
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (([a] -> [a]) -> ([b], [a]) -> ([b], [a])
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:)) (\b
y -> ([b] -> [b]) -> ([b], [a]) -> ([b], [a])
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (b
yb -> [b] -> [b]
forall a. a -> [a] -> [a]
:)) (a -> Maybe b
f a
x)) ([], [])

mapFst :: (a -> c) -> (a, b) -> (c, b)
mapFst :: forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst a -> c
f (a
a, b
b) = (a -> c
f a
a, b
b)

mapSnd :: (b -> c) -> (a, b) -> (a, c)
mapSnd :: forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd b -> c
f (a
a, b
b) = (a
a, b -> c
f b
b)