{- | "Thin" types which reference the parser input when gotten via 'Get'.

flatparse's @take@ family perform no copying-- instead, a bytestring is
manually constructed with the finalizer from the input bytestring. I'm not sure
I want this -- it sounds like a memory leak waiting to happen -- so I default to
copying to a new bytestring. This type allows recovering the efficient no-copy
behaviour.

TODO doing this the other way around would be simpler, and fit flatparse better.
All we need is such a class:

@
class Copy a where copy :: a -> a
instance Copy B.ByteString where copy = B.copy
@

But this just doesn't fly, because it would invert the behaviour.

-}

{-# LANGUAGE UndecidableInstances #-} -- for strongweak derivingvia

module Binrep.Type.Thin where

import Binrep

import FlatParse.Basic qualified as FP

import GHC.Generics ( Generic )
import Data.Data ( Data )
import GHC.Exts ( IsList )
import Data.String
import Control.DeepSeq
import Data.Functor.Identity
import Strongweak

import Data.ByteString qualified as B

newtype Thin a = Thin { forall a. Thin a -> a
unThin :: a }
    -- derive all instances that 'Data.ByteString.ByteString' has
    deriving stock ((forall x. Thin a -> Rep (Thin a) x)
-> (forall x. Rep (Thin a) x -> Thin a) -> Generic (Thin a)
forall x. Rep (Thin a) x -> Thin a
forall x. Thin a -> Rep (Thin a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Thin a) x -> Thin a
forall a x. Thin a -> Rep (Thin a) x
$cfrom :: forall a x. Thin a -> Rep (Thin a) x
from :: forall x. Thin a -> Rep (Thin a) x
$cto :: forall a x. Rep (Thin a) x -> Thin a
to :: forall x. Rep (Thin a) x -> Thin a
Generic, Typeable (Thin a)
Typeable (Thin a) =>
(forall (c :: Type -> Type).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Thin a -> c (Thin a))
-> (forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Thin a))
-> (Thin a -> Constr)
-> (Thin a -> DataType)
-> (forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Thin a)))
-> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Thin a)))
-> ((forall b. Data b => b -> b) -> Thin a -> Thin a)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Thin a -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Thin a -> r)
-> (forall u. (forall d. Data d => d -> u) -> Thin a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Thin a -> u)
-> (forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> Thin a -> m (Thin a))
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Thin a -> m (Thin a))
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Thin a -> m (Thin a))
-> Data (Thin a)
Thin a -> Constr
Thin a -> DataType
(forall b. Data b => b -> b) -> Thin a -> Thin a
forall a. Data a => Typeable (Thin a)
forall a. Data a => Thin a -> Constr
forall a. Data a => Thin a -> DataType
forall a.
Data a =>
(forall b. Data b => b -> b) -> Thin a -> Thin a
forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> Thin a -> u
forall a u. Data a => (forall d. Data d => d -> u) -> Thin a -> [u]
forall a r r'.
Data a =>
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Thin a -> r
forall a r r'.
Data a =>
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Thin a -> r
forall a (m :: Type -> Type).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Thin a -> m (Thin a)
forall a (m :: Type -> Type).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Thin a -> m (Thin a)
forall a (c :: Type -> Type).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Thin a)
forall a (c :: Type -> Type).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Thin a -> c (Thin a)
forall a (t :: Type -> Type) (c :: Type -> Type).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Thin a))
forall a (t :: Type -> Type -> Type) (c :: Type -> Type).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Thin a))
forall a.
Typeable a =>
(forall (c :: Type -> Type).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Thin a -> u
forall u. (forall d. Data d => d -> u) -> Thin a -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Thin a -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Thin a -> r
forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> Thin a -> m (Thin a)
forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Thin a -> m (Thin a)
forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Thin a)
forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Thin a -> c (Thin a)
forall (t :: Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Thin a))
forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Thin a))
$cgfoldl :: forall a (c :: Type -> Type).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Thin a -> c (Thin a)
gfoldl :: forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Thin a -> c (Thin a)
$cgunfold :: forall a (c :: Type -> Type).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Thin a)
gunfold :: forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Thin a)
$ctoConstr :: forall a. Data a => Thin a -> Constr
toConstr :: Thin a -> Constr
$cdataTypeOf :: forall a. Data a => Thin a -> DataType
dataTypeOf :: Thin a -> DataType
$cdataCast1 :: forall a (t :: Type -> Type) (c :: Type -> Type).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Thin a))
dataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Thin a))
$cdataCast2 :: forall a (t :: Type -> Type -> Type) (c :: Type -> Type).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Thin a))
dataCast2 :: forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Thin a))
$cgmapT :: forall a.
Data a =>
(forall b. Data b => b -> b) -> Thin a -> Thin a
gmapT :: (forall b. Data b => b -> b) -> Thin a -> Thin a
$cgmapQl :: forall a r r'.
Data a =>
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Thin a -> r
gmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Thin a -> r
$cgmapQr :: forall a r r'.
Data a =>
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Thin a -> r
gmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Thin a -> r
$cgmapQ :: forall a u. Data a => (forall d. Data d => d -> u) -> Thin a -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Thin a -> [u]
$cgmapQi :: forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> Thin a -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Thin a -> u
$cgmapM :: forall a (m :: Type -> Type).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Thin a -> m (Thin a)
gmapM :: forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> Thin a -> m (Thin a)
$cgmapMp :: forall a (m :: Type -> Type).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Thin a -> m (Thin a)
gmapMp :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Thin a -> m (Thin a)
$cgmapMo :: forall a (m :: Type -> Type).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Thin a -> m (Thin a)
gmapMo :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Thin a -> m (Thin a)
Data, Int -> Thin a -> ShowS
[Thin a] -> ShowS
Thin a -> String
(Int -> Thin a -> ShowS)
-> (Thin a -> String) -> ([Thin a] -> ShowS) -> Show (Thin a)
forall a. Show a => Int -> Thin a -> ShowS
forall a. Show a => [Thin a] -> ShowS
forall a. Show a => Thin a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Thin a -> ShowS
showsPrec :: Int -> Thin a -> ShowS
$cshow :: forall a. Show a => Thin a -> String
show :: Thin a -> String
$cshowList :: forall a. Show a => [Thin a] -> ShowS
showList :: [Thin a] -> ShowS
Show, ReadPrec [Thin a]
ReadPrec (Thin a)
Int -> ReadS (Thin a)
ReadS [Thin a]
(Int -> ReadS (Thin a))
-> ReadS [Thin a]
-> ReadPrec (Thin a)
-> ReadPrec [Thin a]
-> Read (Thin a)
forall a. Read a => ReadPrec [Thin a]
forall a. Read a => ReadPrec (Thin a)
forall a. Read a => Int -> ReadS (Thin a)
forall a. Read a => ReadS [Thin a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall a. Read a => Int -> ReadS (Thin a)
readsPrec :: Int -> ReadS (Thin a)
$creadList :: forall a. Read a => ReadS [Thin a]
readList :: ReadS [Thin a]
$creadPrec :: forall a. Read a => ReadPrec (Thin a)
readPrec :: ReadPrec (Thin a)
$creadListPrec :: forall a. Read a => ReadPrec [Thin a]
readListPrec :: ReadPrec [Thin a]
Read)
    deriving
      ( Thin a -> Thin a -> Bool
(Thin a -> Thin a -> Bool)
-> (Thin a -> Thin a -> Bool) -> Eq (Thin a)
forall a. Eq a => Thin a -> Thin a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Thin a -> Thin a -> Bool
== :: Thin a -> Thin a -> Bool
$c/= :: forall a. Eq a => Thin a -> Thin a -> Bool
/= :: Thin a -> Thin a -> Bool
Eq, Eq (Thin a)
Eq (Thin a) =>
(Thin a -> Thin a -> Ordering)
-> (Thin a -> Thin a -> Bool)
-> (Thin a -> Thin a -> Bool)
-> (Thin a -> Thin a -> Bool)
-> (Thin a -> Thin a -> Bool)
-> (Thin a -> Thin a -> Thin a)
-> (Thin a -> Thin a -> Thin a)
-> Ord (Thin a)
Thin a -> Thin a -> Bool
Thin a -> Thin a -> Ordering
Thin a -> Thin a -> Thin a
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
forall a. Ord a => Eq (Thin a)
forall a. Ord a => Thin a -> Thin a -> Bool
forall a. Ord a => Thin a -> Thin a -> Ordering
forall a. Ord a => Thin a -> Thin a -> Thin a
$ccompare :: forall a. Ord a => Thin a -> Thin a -> Ordering
compare :: Thin a -> Thin a -> Ordering
$c< :: forall a. Ord a => Thin a -> Thin a -> Bool
< :: Thin a -> Thin a -> Bool
$c<= :: forall a. Ord a => Thin a -> Thin a -> Bool
<= :: Thin a -> Thin a -> Bool
$c> :: forall a. Ord a => Thin a -> Thin a -> Bool
> :: Thin a -> Thin a -> Bool
$c>= :: forall a. Ord a => Thin a -> Thin a -> Bool
>= :: Thin a -> Thin a -> Bool
$cmax :: forall a. Ord a => Thin a -> Thin a -> Thin a
max :: Thin a -> Thin a -> Thin a
$cmin :: forall a. Ord a => Thin a -> Thin a -> Thin a
min :: Thin a -> Thin a -> Thin a
Ord, NonEmpty (Thin a) -> Thin a
Thin a -> Thin a -> Thin a
(Thin a -> Thin a -> Thin a)
-> (NonEmpty (Thin a) -> Thin a)
-> (forall b. Integral b => b -> Thin a -> Thin a)
-> Semigroup (Thin a)
forall b. Integral b => b -> Thin a -> Thin a
forall a. Semigroup a => NonEmpty (Thin a) -> Thin a
forall a. Semigroup a => Thin a -> Thin a -> Thin a
forall a b. (Semigroup a, Integral b) => b -> Thin a -> Thin a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
$c<> :: forall a. Semigroup a => Thin a -> Thin a -> Thin a
<> :: Thin a -> Thin a -> Thin a
$csconcat :: forall a. Semigroup a => NonEmpty (Thin a) -> Thin a
sconcat :: NonEmpty (Thin a) -> Thin a
$cstimes :: forall a b. (Semigroup a, Integral b) => b -> Thin a -> Thin a
stimes :: forall b. Integral b => b -> Thin a -> Thin a
Semigroup, Semigroup (Thin a)
Thin a
Semigroup (Thin a) =>
Thin a
-> (Thin a -> Thin a -> Thin a)
-> ([Thin a] -> Thin a)
-> Monoid (Thin a)
[Thin a] -> Thin a
Thin a -> Thin a -> Thin a
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall a. Monoid a => Semigroup (Thin a)
forall a. Monoid a => Thin a
forall a. Monoid a => [Thin a] -> Thin a
forall a. Monoid a => Thin a -> Thin a -> Thin a
$cmempty :: forall a. Monoid a => Thin a
mempty :: Thin a
$cmappend :: forall a. Monoid a => Thin a -> Thin a -> Thin a
mappend :: Thin a -> Thin a -> Thin a
$cmconcat :: forall a. Monoid a => [Thin a] -> Thin a
mconcat :: [Thin a] -> Thin a
Monoid -- simple
      , Thin a -> ()
(Thin a -> ()) -> NFData (Thin a)
forall a. NFData a => Thin a -> ()
forall a. (a -> ()) -> NFData a
$crnf :: forall a. NFData a => Thin a -> ()
rnf :: Thin a -> ()
NFData, String -> Thin a
(String -> Thin a) -> IsString (Thin a)
forall a. IsString a => String -> Thin a
forall a. (String -> a) -> IsString a
$cfromString :: forall a. IsString a => String -> Thin a
fromString :: String -> Thin a
IsString, Int -> [Item (Thin a)] -> Thin a
[Item (Thin a)] -> Thin a
Thin a -> [Item (Thin a)]
([Item (Thin a)] -> Thin a)
-> (Int -> [Item (Thin a)] -> Thin a)
-> (Thin a -> [Item (Thin a)])
-> IsList (Thin a)
forall a. IsList a => Int -> [Item (Thin a)] -> Thin a
forall a. IsList a => [Item (Thin a)] -> Thin a
forall a. IsList a => Thin a -> [Item (Thin a)]
forall l.
([Item l] -> l)
-> (Int -> [Item l] -> l) -> (l -> [Item l]) -> IsList l
$cfromList :: forall a. IsList a => [Item (Thin a)] -> Thin a
fromList :: [Item (Thin a)] -> Thin a
$cfromListN :: forall a. IsList a => Int -> [Item (Thin a)] -> Thin a
fromListN :: Int -> [Item (Thin a)] -> Thin a
$ctoList :: forall a. IsList a => Thin a -> [Item (Thin a)]
toList :: Thin a -> [Item (Thin a)]
IsList -- weird
      , Thin a -> Int
(Thin a -> Int) -> BLen (Thin a)
forall a. BLen a => Thin a -> Int
forall a. (a -> Int) -> BLen a
$cblen :: forall a. BLen a => Thin a -> Int
blen :: Thin a -> Int
BLen, Thin a -> Putter
(Thin a -> Putter) -> Put (Thin a)
forall a. Put a => Thin a -> Putter
forall a. (a -> Putter) -> Put a
$cput :: forall a. Put a => Thin a -> Putter
put :: Thin a -> Putter
Put -- binrep
      ) via a

    -- at the end of the day, we are the identity functor
    deriving (Thin a -> Weak (Thin a)
(Thin a -> Weak (Thin a)) -> Weaken (Thin a)
forall a. Thin a -> Weak (Thin a)
forall a. (a -> Weak a) -> Weaken a
$cweaken :: forall a. Thin a -> Weak (Thin a)
weaken :: Thin a -> Weak (Thin a)
Weaken, Weaken (Thin a)
Weaken (Thin a) =>
(Weak (Thin a) -> Result (Thin a)) -> Strengthen (Thin a)
Weak (Thin a) -> Result (Thin a)
forall a. Weaken (Thin a)
forall a. Weaken a => (Weak a -> Result a) -> Strengthen a
forall a. Weak (Thin a) -> Result (Thin a)
$cstrengthen :: forall a. Weak (Thin a) -> Result (Thin a)
strengthen :: Weak (Thin a) -> Result (Thin a)
Strengthen) via Identity a

instance Get (Thin B.ByteString) where get :: Getter (Thin ByteString)
get = ByteString -> Thin ByteString
forall a. a -> Thin a
Thin (ByteString -> Thin ByteString)
-> ParserT PureMode E ByteString -> Getter (Thin ByteString)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> ParserT PureMode E ByteString
forall (st :: ZeroBitType) e. ParserT st e ByteString
FP.takeRest