{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE AllowAmbiguousTypes #-}

-- TODO rewrite patch/check bits (some overlap)
-- TODO rewrite, rename checks (one for process, one for apply)

module StreamPatch.Patch.Binary where

import StreamPatch.Patch
import StreamPatch.HFunctorList

import Binrep

import GHC.Generics       ( Generic )
import GHC.Natural
import Data.ByteString qualified as BS
import Data.Vinyl
import Data.Functor.Const
import Data.Vinyl.TypeLevel

import StreamPatch.Patch.Compare qualified as Compare
import StreamPatch.Patch.Compare hiding ( Meta )

import Optics

data Meta a = Meta
  { forall {k} (a :: k). Meta a -> Maybe Natural
mNullTerminates :: Maybe Natural
  -- ^ Stream segment should be null bytes (0x00) only from this index onwards.
  } deriving (forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall k (a :: k) x. Rep (Meta a) x -> Meta a
forall k (a :: k) x. Meta a -> Rep (Meta a) x
$cto :: forall k (a :: k) x. Rep (Meta a) x -> Meta a
$cfrom :: forall k (a :: k) x. Meta a -> Rep (Meta a) x
Generic, Meta a -> Meta a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k (a :: k). Meta a -> Meta a -> Bool
/= :: Meta a -> Meta a -> Bool
$c/= :: forall k (a :: k). Meta a -> Meta a -> Bool
== :: Meta a -> Meta a -> Bool
$c== :: forall k (a :: k). Meta a -> Meta a -> Bool
Eq, Int -> Meta a -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k (a :: k). Int -> Meta a -> ShowS
forall k (a :: k). [Meta a] -> ShowS
forall k (a :: k). Meta a -> String
showList :: [Meta a] -> ShowS
$cshowList :: forall k (a :: k). [Meta a] -> ShowS
show :: Meta a -> String
$cshow :: forall k (a :: k). Meta a -> String
showsPrec :: Int -> Meta a -> ShowS
$cshowsPrec :: forall k (a :: k). Int -> Meta a -> ShowS
Show, forall a b. a -> Meta b -> Meta a
forall a b. (a -> b) -> Meta a -> Meta 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 -> Meta b -> Meta a
$c<$ :: forall a b. a -> Meta b -> Meta a
fmap :: forall a b. (a -> b) -> Meta a -> Meta b
$cfmap :: forall a b. (a -> b) -> Meta a -> Meta b
Functor, forall a. Eq a => a -> Meta a -> Bool
forall a. Num a => Meta a -> a
forall a. Ord a => Meta a -> a
forall m. Monoid m => Meta m -> m
forall a. Meta a -> Bool
forall a. Meta a -> Int
forall a. Meta a -> [a]
forall a. (a -> a -> a) -> Meta a -> a
forall m a. Monoid m => (a -> m) -> Meta a -> m
forall b a. (b -> a -> b) -> b -> Meta a -> b
forall a b. (a -> b -> b) -> b -> Meta 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 => Meta a -> a
$cproduct :: forall a. Num a => Meta a -> a
sum :: forall a. Num a => Meta a -> a
$csum :: forall a. Num a => Meta a -> a
minimum :: forall a. Ord a => Meta a -> a
$cminimum :: forall a. Ord a => Meta a -> a
maximum :: forall a. Ord a => Meta a -> a
$cmaximum :: forall a. Ord a => Meta a -> a
elem :: forall a. Eq a => a -> Meta a -> Bool
$celem :: forall a. Eq a => a -> Meta a -> Bool
length :: forall a. Meta a -> Int
$clength :: forall a. Meta a -> Int
null :: forall a. Meta a -> Bool
$cnull :: forall a. Meta a -> Bool
toList :: forall a. Meta a -> [a]
$ctoList :: forall a. Meta a -> [a]
foldl1 :: forall a. (a -> a -> a) -> Meta a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Meta a -> a
foldr1 :: forall a. (a -> a -> a) -> Meta a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Meta a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> Meta a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Meta a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Meta a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Meta a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Meta a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Meta a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Meta a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Meta a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> Meta a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Meta a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Meta a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Meta a -> m
fold :: forall m. Monoid m => Meta m -> m
$cfold :: forall m. Monoid m => Meta m -> m
Foldable, Functor Meta
Foldable Meta
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 => Meta (m a) -> m (Meta a)
forall (f :: * -> *) a. Applicative f => Meta (f a) -> f (Meta a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Meta a -> m (Meta b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Meta a -> f (Meta b)
sequence :: forall (m :: * -> *) a. Monad m => Meta (m a) -> m (Meta a)
$csequence :: forall (m :: * -> *) a. Monad m => Meta (m a) -> m (Meta a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Meta a -> m (Meta b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Meta a -> m (Meta b)
sequenceA :: forall (f :: * -> *) a. Applicative f => Meta (f a) -> f (Meta a)
$csequenceA :: forall (f :: * -> *) a. Applicative f => Meta (f a) -> f (Meta a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Meta a -> f (Meta b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Meta a -> f (Meta b)
Traversable)

data MetaPrep = MetaPrep
  { MetaPrep -> Maybe Natural
mpMaxBytes :: Maybe Natural
  -- ^ Maximum bytelength of binrepped data.
  --
  -- Though binrepping is a safe operation, this is a useful sanity check in
  -- cases where you know the maximum space available.
  --
  -- Note that this is only available for the patch data, not other meta data.
  -- (If you want that, you'll need to shove this field into the patch type.)
  -- itself. Probably not very useful.)
  } deriving (MetaPrep -> MetaPrep -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MetaPrep -> MetaPrep -> Bool
$c/= :: MetaPrep -> MetaPrep -> Bool
== :: MetaPrep -> MetaPrep -> Bool
$c== :: MetaPrep -> MetaPrep -> Bool
Eq, Int -> MetaPrep -> ShowS
[MetaPrep] -> ShowS
MetaPrep -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MetaPrep] -> ShowS
$cshowList :: [MetaPrep] -> ShowS
show :: MetaPrep -> String
$cshow :: MetaPrep -> String
showsPrec :: Int -> MetaPrep -> ShowS
$cshowsPrec :: Int -> MetaPrep -> ShowS
Show, forall x. Rep MetaPrep x -> MetaPrep
forall x. MetaPrep -> Rep MetaPrep x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep MetaPrep x -> MetaPrep
$cfrom :: forall x. MetaPrep -> Rep MetaPrep x
Generic)

data Error a
  = ErrorBinRepOverlong BLenT BLenT a (Maybe BS.ByteString)
  -- ^ If the value was serialized, it's given in the 'Maybe'.
    deriving (Error a -> Error a -> Bool
forall a. Eq a => Error a -> Error a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Error a -> Error a -> Bool
$c/= :: forall a. Eq a => Error a -> Error a -> Bool
== :: Error a -> Error a -> Bool
$c== :: forall a. Eq a => Error a -> Error a -> Bool
Eq, Int -> Error a -> ShowS
forall a. Show a => Int -> Error a -> ShowS
forall a. Show a => [Error a] -> ShowS
forall a. Show a => Error a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Error a] -> ShowS
$cshowList :: forall a. Show a => [Error a] -> ShowS
show :: Error a -> String
$cshow :: forall a. Show a => Error a -> String
showsPrec :: Int -> Error a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Error a -> ShowS
Show, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Error a) x -> Error a
forall a x. Error a -> Rep (Error a) x
$cto :: forall a x. Rep (Error a) x -> Error a
$cfrom :: forall a x. Error a -> Rep (Error a) x
Generic, forall a b. a -> Error b -> Error a
forall a b. (a -> b) -> Error a -> Error 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 -> Error b -> Error a
$c<$ :: forall a b. a -> Error b -> Error a
fmap :: forall a b. (a -> b) -> Error a -> Error b
$cfmap :: forall a b. (a -> b) -> Error a -> Error b
Functor, forall a. Eq a => a -> Error a -> Bool
forall a. Num a => Error a -> a
forall a. Ord a => Error a -> a
forall m. Monoid m => Error m -> m
forall a. Error a -> Bool
forall a. Error a -> Int
forall a. Error a -> [a]
forall a. (a -> a -> a) -> Error a -> a
forall m a. Monoid m => (a -> m) -> Error a -> m
forall b a. (b -> a -> b) -> b -> Error a -> b
forall a b. (a -> b -> b) -> b -> Error 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 => Error a -> a
$cproduct :: forall a. Num a => Error a -> a
sum :: forall a. Num a => Error a -> a
$csum :: forall a. Num a => Error a -> a
minimum :: forall a. Ord a => Error a -> a
$cminimum :: forall a. Ord a => Error a -> a
maximum :: forall a. Ord a => Error a -> a
$cmaximum :: forall a. Ord a => Error a -> a
elem :: forall a. Eq a => a -> Error a -> Bool
$celem :: forall a. Eq a => a -> Error a -> Bool
length :: forall a. Error a -> Int
$clength :: forall a. Error a -> Int
null :: forall a. Error a -> Bool
$cnull :: forall a. Error a -> Bool
toList :: forall a. Error a -> [a]
$ctoList :: forall a. Error a -> [a]
foldl1 :: forall a. (a -> a -> a) -> Error a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Error a -> a
foldr1 :: forall a. (a -> a -> a) -> Error a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Error a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> Error a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Error a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Error a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Error a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Error a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Error a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Error a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Error a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> Error a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Error a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Error a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Error a -> m
fold :: forall m. Monoid m => Error m -> m
$cfold :: forall m. Monoid m => Error m -> m
Foldable, Functor Error
Foldable Error
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 => Error (m a) -> m (Error a)
forall (f :: * -> *) a. Applicative f => Error (f a) -> f (Error a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Error a -> m (Error b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Error a -> f (Error b)
sequence :: forall (m :: * -> *) a. Monad m => Error (m a) -> m (Error a)
$csequence :: forall (m :: * -> *) a. Monad m => Error (m a) -> m (Error a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Error a -> m (Error b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Error a -> m (Error b)
sequenceA :: forall (f :: * -> *) a. Applicative f => Error (f a) -> f (Error a)
$csequenceA :: forall (f :: * -> *) a. Applicative f => Error (f a) -> f (Error a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Error a -> f (Error b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Error a -> f (Error b)
Traversable)

-- Note that via binrep's 'BLen' typeclass, we can check sizing "for free",
-- without serializing. TODO, I could make another function that serializes,
-- then checks. That way, we can return the serialization attempt to the user,
-- and not require 'BLen'. In exchange, it's less efficient on errors. Both have
-- the same main path complexity.
binRepify
    :: forall a s ss is r rs
    .  ( Put a, BLen a
       , Traversable (HFunctorList rs)
       , r ~ Const MetaPrep
       , rs ~ RDelete r ss
       , RElem r ss (RIndex r ss)
       , RSubset rs ss is )
    => Patch s ss a
    -> Either (Error a) (Patch s rs BS.ByteString)
binRepify :: forall a s (ss :: [* -> *]) (is :: [Nat]) (r :: * -> *)
       (rs :: [* -> *]).
(Put a, BLen a, Traversable (HFunctorList rs), r ~ Const MetaPrep,
 rs ~ RDelete r ss, RElem r ss (RIndex r ss), RSubset rs ss is) =>
Patch s ss a -> Either (Error a) (Patch s rs ByteString)
binRepify (Patch a
a s
s HFunctorList ss a
ms) = do
    let (MetaPrep
m, HFunctorList rs a
ms') = forall {k} (f :: k -> *) (fs :: [k -> *]) (a :: k)
       (fs' :: [k -> *]) b (i :: Nat) (is :: [Nat]).
(RElem f fs i, fs' ~ RDelete f fs, RSubset fs' fs is) =>
(f a -> b) -> HFunctorList fs a -> (b, HFunctorList fs' a)
hflStrip forall {k} a (b :: k). Const a b -> a
getConst HFunctorList ss a
ms
    MetaPrep -> Either (Error a) ()
checkMeta MetaPrep
m
    let bs :: ByteString
bs = forall a. Put a => a -> ByteString
runPut a
a
        bsms :: HFunctorList rs ByteString
bsms = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Put a => a -> ByteString
runPut HFunctorList rs a
ms'
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall s (fs :: [* -> *]) a.
a -> s -> HFunctorList fs a -> Patch s fs a
Patch ByteString
bs s
s HFunctorList rs ByteString
bsms
  where
    checkMeta :: MetaPrep -> Either (Error a) ()
checkMeta MetaPrep
m =
        case MetaPrep -> Maybe Natural
mpMaxBytes MetaPrep
m of
          Maybe Natural
Nothing       -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
          Just Natural
maxBytes ->
            let maxBytes' :: Int
maxBytes' = forall a. AsBLen a => Natural -> a
natToBLen Natural
maxBytes
             in if   forall a. BLen a => a -> Int
blen a
a forall a. Ord a => a -> a -> Bool
> Int
maxBytes'
                then forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ forall a. Int -> Int -> a -> Maybe ByteString -> Error a
ErrorBinRepOverlong (forall a. BLen a => a -> Int
blen a
a) Int
maxBytes' a
a forall a. Maybe a
Nothing
                else forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

-- | Treat the nulls field as a "this is how many extra nulls there are", and
--   amend the compare meta for a patch by appending those nulls, and strip that
--   stream-time bin meta.
--
-- Correct thing to do, but needs lots of changes elsewhere too. Dang.
binRepifyNull
    :: forall ec s r1 r2 ss rs is
    .  ( r1 ~ Meta
       , r2 ~ Compare.Meta ('ViaEq ec)
       , rs ~ RDelete r1 ss
       , RElem r1 ss (RIndex r1 ss)
       , RSubset rs ss is
       , RElem r2 rs (RIndex r2 rs)
       , RecElem Rec r2 r2 rs rs (RIndex r2 rs)
       )
    => Patch s ss BS.ByteString
    -> Patch s rs BS.ByteString
binRepifyNull :: forall (ec :: EqualityCheck) s (r1 :: * -> *) (r2 :: * -> *)
       (ss :: [* -> *]) (rs :: [* -> *]) (is :: [Nat]).
(r1 ~ Meta, r2 ~ Meta ('ViaEq ec), rs ~ RDelete r1 ss,
 RElem r1 ss (RIndex r1 ss), RSubset rs ss is,
 RElem r2 rs (RIndex r2 rs), RElem r2 rs (RIndex r2 rs)) =>
Patch s ss ByteString -> Patch s rs ByteString
binRepifyNull (Patch ByteString
a s
s HFunctorList ss ByteString
ms) = do
    let (Maybe Natural
mNT, HFunctorList rs ByteString
ms') = forall {k} (f :: k -> *) (fs :: [k -> *]) (a :: k)
       (fs' :: [k -> *]) b (i :: Nat) (is :: [Nat]).
(RElem f fs i, fs' ~ RDelete f fs, RSubset fs' fs is) =>
(f a -> b) -> HFunctorList fs a -> (b, HFunctorList fs' a)
hflStrip @r1 forall {k} (a :: k). Meta a -> Maybe Natural
mNullTerminates HFunctorList ss ByteString
ms
    case Maybe Natural
mNT of
      Maybe Natural
Nothing -> forall s (fs :: [* -> *]) a.
a -> s -> HFunctorList fs a -> Patch s fs a
Patch ByteString
a s
s HFunctorList rs ByteString
ms'
      Just Natural
nt ->
        let mCmpLens :: Lens
  (HFunctorList rs ByteString)
  (HFunctorList rs ByteString)
  (r2 ByteString)
  (r2 ByteString)
mCmpLens = forall {k} (f :: k -> *) (f' :: k -> *) (fs :: [k -> *])
       (fs' :: [k -> *]) (a :: k) s t.
(RecElem Rec f f' fs fs' (RIndex f fs), RElem f fs (RIndex f fs),
 s ~ HFunctorList fs a, t ~ HFunctorList fs' a) =>
Lens s t (f a) (f' a)
hflLens @r2 @r2 @rs @rs
            ms'' :: HFunctorList rs ByteString
ms'' = forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> (a -> b) -> s -> t
over Lens
  (HFunctorList rs ByteString)
  (HFunctorList rs ByteString)
  (r2 ByteString)
  (r2 ByteString)
mCmpLens (\(Compare.Meta Maybe (CompareRep ('ViaEq ec) ByteString)
x) -> forall {v :: Via} {a} {a}.
(CompareRep v a ~ ByteString, Integral a) =>
a -> Maybe ByteString -> Meta v a
go Natural
nt Maybe (CompareRep ('ViaEq ec) ByteString)
x) HFunctorList rs ByteString
ms'
         in forall s (fs :: [* -> *]) a.
a -> s -> HFunctorList fs a -> Patch s fs a
Patch ByteString
a s
s HFunctorList rs ByteString
ms''
  where
    go :: a -> Maybe ByteString -> Meta v a
go a
nt = \case
      Maybe ByteString
Nothing  -> forall (v :: Via) a. Maybe (CompareRep v a) -> Meta v a
Compare.Meta forall a. Maybe a
Nothing
      Just ByteString
cmp ->
        let cmp' :: ByteString
cmp' = ByteString
cmp forall a. Semigroup a => a -> a -> a
<> Int -> Word8 -> ByteString
BS.replicate (forall a b. (Integral a, Num b) => a -> b
fromIntegral a
nt) Word8
0x00
         in forall (v :: Via) a. Maybe (CompareRep v a) -> Meta v a
Compare.Meta forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just ByteString
cmp'