{-# LANGUAGE CPP #-}
{-# LANGUAGE UndecidableInstances #-}

-- | Internal module for "Data.Bytes". The primary difference is
-- this module exposes some underlying details i.e. singleton witnesses.
-- These are hidden by default as they complicate the API.
--
-- @since 0.1
module Data.Bytes.Internal
  ( -- * Bytes
    Bytes (..),
    _MkBytes,
    bytesToSSize,

    -- * Unknown Size
    SomeSize (..),
    _MkSomeSize,
  )
where

#if !MIN_VERSION_base(4, 18, 0)
import Control.Applicative (liftA2)
#endif
import Control.DeepSeq (NFData (rnf), deepseq)
import Data.Bounds
  ( AnyLowerBounded,
    AnyUpperBounded,
    LowerBounded,
    LowerBoundless,
    UpperBounded,
    UpperBoundless,
  )
import Data.Bytes.Class.Conversion (Conversion (convert))
import Data.Bytes.Class.Conversion qualified as Conv
import Data.Bytes.Class.Normalize (Normalize (Norm, normalize))
import Data.Bytes.Class.Parser (Parser (parser))
import Data.Bytes.Class.Parser qualified as Parser
import Data.Bytes.Class.RawNumeric (RawNumeric (Raw, toRaw))
import Data.Bytes.Size
  ( NextSize,
    PrevSize,
    SSize (SB, SE, SG, SK, SM, SP, ST, SY, SZ),
    SingSize (singSize),
    Size (B, E, G, K, M, P, T, Y, Z),
    Sized (hideSize),
  )
import Data.Bytes.Size qualified as Size
import Data.Hashable as X (Hashable (hashWithSalt))
import Data.Kind (Type)
import Data.Proxy (Proxy (Proxy))
import GHC.Generics (Generic)
#if MIN_VERSION_base(4, 16, 0)
import GHC.Records (HasField (getField))
#endif
import Numeric.Algebra
  ( AGroup ((.-.)),
    AMonoid (zero),
    ASemigroup ((.+.)),
    Field,
    MGroup ((.%.)),
    MSemiSpace ((.*)),
    MSemigroup ((.*.)),
    MSpace ((.%)),
    Module,
    Normed (norm),
    Ring,
    Semifield,
    Semimodule,
    Semiring,
    SemivectorSpace,
    VectorSpace,
  )
import Numeric.Literal.Integer (FromInteger (afromInteger))
import Numeric.Literal.Rational (FromRational (afromRational))
import Optics.Core (A_Getter, An_Iso, Iso', LabelOptic (labelOptic), iso, to)
import Text.Megaparsec qualified as MP
import Text.Megaparsec.Char qualified as MPC

-- $setup
-- >>> import Data.Bytes.Size (Size (..), Sized (..))
-- >>> getRawFileSize _ = pure (40, "K")

-- | This is the core type for handling type-safe byte operations. It is
-- intended to be used as a simple wrapper over some numeric type,
-- equipped with a 'Size' tag.
--
-- To take full advantage of the API (e.g. `normalize`), the underlying
-- numeric type should implement 'Semifield' or, ideally, 'Field'.
--
-- ==== __Examples__
-- >>> MkBytes @M 1000
-- MkBytes 1000
--
-- @since 0.1
type Bytes :: Size -> Type -> Type
newtype Bytes (s :: Size) (n :: Type) = MkBytes n
  deriving stock
    ( -- | @since 0.1
      Bytes s n
Bytes s n -> Bytes s n -> Bounded (Bytes s n)
forall a. a -> a -> Bounded a
forall (s :: Size) n. Bounded n => Bytes s n
$cminBound :: forall (s :: Size) n. Bounded n => Bytes s n
minBound :: Bytes s n
$cmaxBound :: forall (s :: Size) n. Bounded n => Bytes s n
maxBound :: Bytes s n
Bounded,
      -- | @since 0.1
      Bytes s n -> Bytes s n -> Bool
(Bytes s n -> Bytes s n -> Bool)
-> (Bytes s n -> Bytes s n -> Bool) -> Eq (Bytes s n)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (s :: Size) n. Eq n => Bytes s n -> Bytes s n -> Bool
$c== :: forall (s :: Size) n. Eq n => Bytes s n -> Bytes s n -> Bool
== :: Bytes s n -> Bytes s n -> Bool
$c/= :: forall (s :: Size) n. Eq n => Bytes s n -> Bytes s n -> Bool
/= :: Bytes s n -> Bytes s n -> Bool
Eq,
      -- | @since 0.1
      (forall a b. (a -> b) -> Bytes s a -> Bytes s b)
-> (forall a b. a -> Bytes s b -> Bytes s a) -> Functor (Bytes s)
forall a b. a -> Bytes s b -> Bytes s a
forall a b. (a -> b) -> Bytes s a -> Bytes s b
forall (s :: Size) a b. a -> Bytes s b -> Bytes s a
forall (s :: Size) a b. (a -> b) -> Bytes s a -> Bytes s b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (s :: Size) a b. (a -> b) -> Bytes s a -> Bytes s b
fmap :: forall a b. (a -> b) -> Bytes s a -> Bytes s b
$c<$ :: forall (s :: Size) a b. a -> Bytes s b -> Bytes s a
<$ :: forall a b. a -> Bytes s b -> Bytes s a
Functor,
      -- | @since 0.1
      (forall x. Bytes s n -> Rep (Bytes s n) x)
-> (forall x. Rep (Bytes s n) x -> Bytes s n)
-> Generic (Bytes s n)
forall x. Rep (Bytes s n) x -> Bytes s n
forall x. Bytes s n -> Rep (Bytes s n) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (s :: Size) n x. Rep (Bytes s n) x -> Bytes s n
forall (s :: Size) n x. Bytes s n -> Rep (Bytes s n) x
$cfrom :: forall (s :: Size) n x. Bytes s n -> Rep (Bytes s n) x
from :: forall x. Bytes s n -> Rep (Bytes s n) x
$cto :: forall (s :: Size) n x. Rep (Bytes s n) x -> Bytes s n
to :: forall x. Rep (Bytes s n) x -> Bytes s n
Generic,
      -- | @since 0.1
      Eq (Bytes s n)
Eq (Bytes s n) =>
(Bytes s n -> Bytes s n -> Ordering)
-> (Bytes s n -> Bytes s n -> Bool)
-> (Bytes s n -> Bytes s n -> Bool)
-> (Bytes s n -> Bytes s n -> Bool)
-> (Bytes s n -> Bytes s n -> Bool)
-> (Bytes s n -> Bytes s n -> Bytes s n)
-> (Bytes s n -> Bytes s n -> Bytes s n)
-> Ord (Bytes s n)
Bytes s n -> Bytes s n -> Bool
Bytes s n -> Bytes s n -> Ordering
Bytes s n -> Bytes s n -> Bytes s n
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 (s :: Size) n. Ord n => Eq (Bytes s n)
forall (s :: Size) n. Ord n => Bytes s n -> Bytes s n -> Bool
forall (s :: Size) n. Ord n => Bytes s n -> Bytes s n -> Ordering
forall (s :: Size) n. Ord n => Bytes s n -> Bytes s n -> Bytes s n
$ccompare :: forall (s :: Size) n. Ord n => Bytes s n -> Bytes s n -> Ordering
compare :: Bytes s n -> Bytes s n -> Ordering
$c< :: forall (s :: Size) n. Ord n => Bytes s n -> Bytes s n -> Bool
< :: Bytes s n -> Bytes s n -> Bool
$c<= :: forall (s :: Size) n. Ord n => Bytes s n -> Bytes s n -> Bool
<= :: Bytes s n -> Bytes s n -> Bool
$c> :: forall (s :: Size) n. Ord n => Bytes s n -> Bytes s n -> Bool
> :: Bytes s n -> Bytes s n -> Bool
$c>= :: forall (s :: Size) n. Ord n => Bytes s n -> Bytes s n -> Bool
>= :: Bytes s n -> Bytes s n -> Bool
$cmax :: forall (s :: Size) n. Ord n => Bytes s n -> Bytes s n -> Bytes s n
max :: Bytes s n -> Bytes s n -> Bytes s n
$cmin :: forall (s :: Size) n. Ord n => Bytes s n -> Bytes s n -> Bytes s n
min :: Bytes s n -> Bytes s n -> Bytes s n
Ord,
      -- | @since 0.1
      Int -> Bytes s n -> ShowS
[Bytes s n] -> ShowS
Bytes s n -> String
(Int -> Bytes s n -> ShowS)
-> (Bytes s n -> String)
-> ([Bytes s n] -> ShowS)
-> Show (Bytes s n)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (s :: Size) n. Show n => Int -> Bytes s n -> ShowS
forall (s :: Size) n. Show n => [Bytes s n] -> ShowS
forall (s :: Size) n. Show n => Bytes s n -> String
$cshowsPrec :: forall (s :: Size) n. Show n => Int -> Bytes s n -> ShowS
showsPrec :: Int -> Bytes s n -> ShowS
$cshow :: forall (s :: Size) n. Show n => Bytes s n -> String
show :: Bytes s n -> String
$cshowList :: forall (s :: Size) n. Show n => [Bytes s n] -> ShowS
showList :: [Bytes s n] -> ShowS
Show
    )
  deriving anyclass
    ( -- | @since 0.1
      Bytes s n -> ()
(Bytes s n -> ()) -> NFData (Bytes s n)
forall a. (a -> ()) -> NFData a
forall (s :: Size) n. NFData n => Bytes s n -> ()
$crnf :: forall (s :: Size) n. NFData n => Bytes s n -> ()
rnf :: Bytes s n -> ()
NFData
    )
  deriving
    ( -- | @since 0.1
      Maybe (Bytes s n)
Maybe (Bytes s n) -> AnyLowerBounded (Bytes s n)
forall a. Maybe a -> AnyLowerBounded a
forall (s :: Size) n. AnyLowerBounded n => Maybe (Bytes s n)
$csomeLowerBound :: forall (s :: Size) n. AnyLowerBounded n => Maybe (Bytes s n)
someLowerBound :: Maybe (Bytes s n)
AnyLowerBounded,
      -- | @since 0.1
      Maybe (Bytes s n)
Maybe (Bytes s n) -> AnyUpperBounded (Bytes s n)
forall a. Maybe a -> AnyUpperBounded a
forall (s :: Size) n. AnyUpperBounded n => Maybe (Bytes s n)
$csomeUpperBound :: forall (s :: Size) n. AnyUpperBounded n => Maybe (Bytes s n)
someUpperBound :: Maybe (Bytes s n)
AnyUpperBounded,
      -- | @since 0.1
      Eq (Bytes s n)
Eq (Bytes s n) =>
(Int -> Bytes s n -> Int)
-> (Bytes s n -> Int) -> Hashable (Bytes s n)
Int -> Bytes s n -> Int
Bytes s n -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
forall (s :: Size) n. Hashable n => Eq (Bytes s n)
forall (s :: Size) n. Hashable n => Int -> Bytes s n -> Int
forall (s :: Size) n. Hashable n => Bytes s n -> Int
$chashWithSalt :: forall (s :: Size) n. Hashable n => Int -> Bytes s n -> Int
hashWithSalt :: Int -> Bytes s n -> Int
$chash :: forall (s :: Size) n. Hashable n => Bytes s n -> Int
hash :: Bytes s n -> Int
Hashable,
      -- | @since 0.1
      Bytes s n
Bytes s n -> LowerBounded (Bytes s n)
forall a. a -> LowerBounded a
forall (s :: Size) n. LowerBounded n => Bytes s n
$clowerBound :: forall (s :: Size) n. LowerBounded n => Bytes s n
lowerBound :: Bytes s n
LowerBounded,
      -- | @since 0.1
      LowerBoundless (Bytes s n)
forall a. LowerBoundless a
LowerBoundless,
      -- | @since 0.1
      Bytes s n
Bytes s n -> UpperBounded (Bytes s n)
forall a. a -> UpperBounded a
forall (s :: Size) n. UpperBounded n => Bytes s n
$cupperBound :: forall (s :: Size) n. UpperBounded n => Bytes s n
upperBound :: Bytes s n
UpperBounded,
      -- | @since 0.1
      UpperBoundless (Bytes s n)
forall a. UpperBoundless a
UpperBoundless
    )
    via n

-- | Changes the 'Size' tag.
--
-- @since 0.1
resizeBytes :: Bytes s n -> Bytes t n
resizeBytes :: forall (s :: Size) n (t :: Size). Bytes s n -> Bytes t n
resizeBytes (MkBytes n
x) = n -> Bytes t n
forall (s :: Size) n. n -> Bytes s n
MkBytes n
x
{-# INLINE resizeBytes #-}

-- | Retrieves the 'SSize' witness. Can be used to recover the 'Size'.
--
-- >>> bytesToSSize (MkBytes @K @Int 7)
-- SK
--
-- @since 0.1
bytesToSSize :: (SingSize s) => Bytes s n -> SSize s
bytesToSSize :: forall (s :: Size) n. SingSize s => Bytes s n -> SSize s
bytesToSSize Bytes s n
_ = SSize s
forall (s :: Size). SingSize s => SSize s
singSize
{-# INLINE bytesToSSize #-}

-- | 'Iso'' between 'Bytes' and underlying value.
--
-- ==== __Examples__
--
-- >>> import Optics.Core (review, view)
-- >>> (review _MkBytes 70) :: Bytes K Int
-- MkBytes 70
--
-- >>> view _MkBytes (MkBytes @K @Int 70)
-- 70
--
-- @since 0.1
_MkBytes :: forall s n. Iso' (Bytes s n) n
_MkBytes :: forall (s :: Size) n. Iso' (Bytes s n) n
_MkBytes = (Bytes s n -> n)
-> (n -> Bytes s n) -> Iso (Bytes s n) (Bytes s n) n n
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso Bytes s n -> n
Bytes s n -> Raw (Bytes s n)
forall a. RawNumeric a => a -> Raw a
toRaw n -> Bytes s n
forall (s :: Size) n. n -> Bytes s n
MkBytes
{-# INLINE _MkBytes #-}

#if MIN_VERSION_base(4, 16, 0)

-- | @since 0.1
instance HasField "unBytes" (Bytes s n) n where
  getField :: Bytes s n -> n
getField (MkBytes n
x) = n
x

#endif

-- | @since 0.1
instance
  ( k ~ An_Iso,
    a ~ n,
    b ~ n
  ) =>
  LabelOptic "unBytes" k (Bytes s n) (Bytes s n) a b
  where
  labelOptic :: Optic k NoIx (Bytes s n) (Bytes s n) a b
labelOptic = (Bytes s n -> a)
-> (b -> Bytes s n) -> Iso (Bytes s n) (Bytes s n) a b
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso (\(MkBytes n
x) -> a
n
x) b -> Bytes s n
b -> Bytes s b
forall (s :: Size) n. n -> Bytes s n
MkBytes
  {-# INLINE labelOptic #-}

-- | @since 0.1
instance Applicative (Bytes s) where
  pure :: forall a. a -> Bytes s a
pure = a -> Bytes s a
forall (s :: Size) n. n -> Bytes s n
MkBytes
  {-# INLINE pure #-}
  MkBytes a -> b
f <*> :: forall a b. Bytes s (a -> b) -> Bytes s a -> Bytes s b
<*> MkBytes a
x = b -> Bytes s b
forall (s :: Size) n. n -> Bytes s n
MkBytes (b -> Bytes s b) -> b -> Bytes s b
forall a b. (a -> b) -> a -> b
$ a -> b
f a
x
  {-# INLINE (<*>) #-}

-- | @since 0.1
instance Monad (Bytes s) where
  MkBytes a
x >>= :: forall a b. Bytes s a -> (a -> Bytes s b) -> Bytes s b
>>= a -> Bytes s b
f = a -> Bytes s b
f a
x
  {-# INLINE (>>=) #-}

-- | @since 0.1
instance Foldable (Bytes s) where
  foldr :: forall a b. (a -> b -> b) -> b -> Bytes s a -> b
foldr a -> b -> b
f b
e (MkBytes a
x) = a -> b -> b
f a
x b
e
  {-# INLINE foldr #-}

-- | @since 0.1
instance Traversable (Bytes s) where
  traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Bytes s a -> f (Bytes s b)
traverse a -> f b
f (MkBytes a
x) = b -> Bytes s b
forall (s :: Size) n. n -> Bytes s n
MkBytes (b -> Bytes s b) -> f b -> f (Bytes s b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f b
f a
x
  {-# INLINE traverse #-}

  sequenceA :: forall (f :: * -> *) a.
Applicative f =>
Bytes s (f a) -> f (Bytes s a)
sequenceA (MkBytes f a
x) = a -> Bytes s a
forall (s :: Size) n. n -> Bytes s n
MkBytes (a -> Bytes s a) -> f a -> f (Bytes s a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f a
x
  {-# INLINE sequenceA #-}

-- | @since 0.1
instance (FromInteger n) => FromInteger (Bytes s n) where
  afromInteger :: HasCallStack => Integer -> Bytes s n
afromInteger = n -> Bytes s n
forall (s :: Size) n. n -> Bytes s n
MkBytes (n -> Bytes s n) -> (Integer -> n) -> Integer -> Bytes s n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> n
forall a. (FromInteger a, HasCallStack) => Integer -> a
afromInteger
  {-# INLINE afromInteger #-}

-- | @since 0.1
instance (FromRational n) => FromRational (Bytes s n) where
  afromRational :: HasCallStack => Rational -> Bytes s n
afromRational = n -> Bytes s n
forall (s :: Size) n. n -> Bytes s n
MkBytes (n -> Bytes s n) -> (Rational -> n) -> Rational -> Bytes s n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> n
forall a. (FromRational a, HasCallStack) => Rational -> a
afromRational
  {-# INLINE afromRational #-}

-- | @since 0.1
instance (ASemigroup n) => ASemigroup (Bytes s n) where
  .+. :: Bytes s n -> Bytes s n -> Bytes s n
(.+.) = (n -> n -> n) -> Bytes s n -> Bytes s n -> Bytes s n
forall a b c. (a -> b -> c) -> Bytes s a -> Bytes s b -> Bytes s c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 n -> n -> n
forall s. ASemigroup s => s -> s -> s
(.+.)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance (AMonoid n) => AMonoid (Bytes s n) where
  zero :: Bytes s n
zero = n -> Bytes s n
forall (s :: Size) n. n -> Bytes s n
MkBytes n
forall m. AMonoid m => m
zero
  {-# INLINE zero #-}

-- | @since 0.1
instance (AGroup n) => AGroup (Bytes s n) where
  .-. :: Bytes s n -> Bytes s n -> Bytes s n
(.-.) = (n -> n -> n) -> Bytes s n -> Bytes s n -> Bytes s n
forall a b c. (a -> b -> c) -> Bytes s a -> Bytes s b -> Bytes s c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 n -> n -> n
forall g. AGroup g => g -> g -> g
(.-.)
  {-# INLINE (.-.) #-}

-- | @since 0.1
instance (MSemigroup n) => MSemiSpace (Bytes s n) n where
  MkBytes n
x .* :: Bytes s n -> n -> Bytes s n
.* n
k = n -> Bytes s n
forall (s :: Size) n. n -> Bytes s n
MkBytes (n -> Bytes s n) -> n -> Bytes s n
forall a b. (a -> b) -> a -> b
$ n
x n -> n -> n
forall s. MSemigroup s => s -> s -> s
.*. n
k
  {-# INLINE (.*) #-}

-- | @since 0.1
instance (MGroup n) => MSpace (Bytes s n) n where
  MkBytes n
x .% :: Bytes s n -> n -> Bytes s n
.% n
k = n -> Bytes s n
forall (s :: Size) n. n -> Bytes s n
MkBytes (n -> Bytes s n) -> n -> Bytes s n
forall a b. (a -> b) -> a -> b
$ n
x n -> n -> n
forall g. MGroup g => g -> g -> g
.%. n
k
  {-# INLINEABLE (.%) #-}

-- | @since 0.1
instance (Normed n) => Normed (Bytes s n) where
  norm :: Bytes s n -> Bytes s n
norm (MkBytes n
x) = n -> Bytes s n
forall (s :: Size) n. n -> Bytes s n
MkBytes (n -> n
forall s. Normed s => s -> s
norm n
x)
  {-# INLINE norm #-}

-- | @since 0.1
instance (Semiring n) => Semimodule (Bytes s n) n

-- | @since 0.1
instance (Ring n) => Module (Bytes s n) n

-- | @since 0.1
instance (Semifield n) => SemivectorSpace (Bytes s n) n

-- | @since 0.1
instance (Field n) => VectorSpace (Bytes s n) n

-- | @since 0.1
instance (FromInteger n, MGroup n, SingSize s) => Conversion (Bytes s n) where
  type Converted t (Bytes s n) = Bytes t n

  convert :: forall t. (SingSize t) => Proxy t -> Bytes s n -> Bytes t n
  convert :: forall (t :: Size). SingSize t => Proxy t -> Bytes s n -> Bytes t n
convert Proxy t
_ (MkBytes n
x) = n -> Bytes t n
forall (s :: Size) n. n -> Bytes s n
MkBytes (n -> Bytes t n) -> n -> Bytes t n
forall a b. (a -> b) -> a -> b
$ forall (s :: Size) n.
(FromInteger n, MGroup n, SingSize s) =>
Size -> n -> n
Conv.convertWitness @s (SSize t -> Size
forall (s :: Size). SSize s -> Size
Size.ssizeToSize (SSize t -> Size) -> SSize t -> Size
forall a b. (a -> b) -> a -> b
$ forall (s :: Size). SingSize s => SSize s
singSize @t) n
x

-- | @since 0.1
instance
  forall n s.
  (FromInteger n, MGroup n, Normed n, Ord n, SingSize s) =>
  Normalize (Bytes s n)
  where
  type Norm (Bytes s n) = SomeSize n

  normalize :: Bytes s n -> Norm (Bytes s n)
normalize bytes :: Bytes s n
bytes@(MkBytes n
x) =
    case SSize s
sz of
      SSize s
SB
        | Bool
tooLarge -> Bytes 'K n -> Norm (Bytes 'K n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'K n -> Norm (Bytes 'K n))
-> Bytes 'K n -> Norm (Bytes 'K n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (NextSize s) n
forall (s :: Size) n.
(FromInteger n, MGroup n) =>
Bytes s n -> Bytes (NextSize s) n
incSize Bytes s n
bytes
        | Bool
otherwise -> SSize s -> Bytes s n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize s
sz Bytes s n
bytes
      SSize s
SY
        | Bool
tooSmall -> Bytes 'Z n -> Norm (Bytes 'Z n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'Z n -> Norm (Bytes 'Z n))
-> Bytes 'Z n -> Norm (Bytes 'Z n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (PrevSize s) n
forall (s :: Size) n.
(FromInteger n, MSemigroup n) =>
Bytes s n -> Bytes (PrevSize s) n
decSize Bytes s n
bytes
        | Bool
otherwise -> SSize s -> Bytes s n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize s
sz Bytes s n
bytes
      SSize s
SK
        | Bool
tooSmall -> Bytes 'B n -> Norm (Bytes 'B n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'B n -> Norm (Bytes 'B n))
-> Bytes 'B n -> Norm (Bytes 'B n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (PrevSize s) n
forall (s :: Size) n.
(FromInteger n, MSemigroup n) =>
Bytes s n -> Bytes (PrevSize s) n
decSize Bytes s n
bytes
        | Bool
tooLarge -> Bytes 'M n -> Norm (Bytes 'M n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'M n -> Norm (Bytes 'M n))
-> Bytes 'M n -> Norm (Bytes 'M n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (NextSize s) n
forall (s :: Size) n.
(FromInteger n, MGroup n) =>
Bytes s n -> Bytes (NextSize s) n
incSize Bytes s n
bytes
        | Bool
otherwise -> SSize s -> Bytes s n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize s
sz Bytes s n
bytes
      SSize s
SM
        | Bool
tooSmall -> Bytes 'K n -> Norm (Bytes 'K n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'K n -> Norm (Bytes 'K n))
-> Bytes 'K n -> Norm (Bytes 'K n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (PrevSize s) n
forall (s :: Size) n.
(FromInteger n, MSemigroup n) =>
Bytes s n -> Bytes (PrevSize s) n
decSize Bytes s n
bytes
        | Bool
tooLarge -> Bytes 'G n -> Norm (Bytes 'G n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'G n -> Norm (Bytes 'G n))
-> Bytes 'G n -> Norm (Bytes 'G n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (NextSize s) n
forall (s :: Size) n.
(FromInteger n, MGroup n) =>
Bytes s n -> Bytes (NextSize s) n
incSize Bytes s n
bytes
        | Bool
otherwise -> SSize s -> Bytes s n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize s
sz Bytes s n
bytes
      SSize s
SG
        | Bool
tooSmall -> Bytes 'M n -> Norm (Bytes 'M n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'M n -> Norm (Bytes 'M n))
-> Bytes 'M n -> Norm (Bytes 'M n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (PrevSize s) n
forall (s :: Size) n.
(FromInteger n, MSemigroup n) =>
Bytes s n -> Bytes (PrevSize s) n
decSize Bytes s n
bytes
        | Bool
tooLarge -> Bytes 'T n -> Norm (Bytes 'T n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'T n -> Norm (Bytes 'T n))
-> Bytes 'T n -> Norm (Bytes 'T n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (NextSize s) n
forall (s :: Size) n.
(FromInteger n, MGroup n) =>
Bytes s n -> Bytes (NextSize s) n
incSize Bytes s n
bytes
        | Bool
otherwise -> SSize s -> Bytes s n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize s
sz Bytes s n
bytes
      SSize s
ST
        | Bool
tooSmall -> Bytes 'G n -> Norm (Bytes 'G n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'G n -> Norm (Bytes 'G n))
-> Bytes 'G n -> Norm (Bytes 'G n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (PrevSize s) n
forall (s :: Size) n.
(FromInteger n, MSemigroup n) =>
Bytes s n -> Bytes (PrevSize s) n
decSize Bytes s n
bytes
        | Bool
tooLarge -> Bytes 'P n -> Norm (Bytes 'P n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'P n -> Norm (Bytes 'P n))
-> Bytes 'P n -> Norm (Bytes 'P n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (NextSize s) n
forall (s :: Size) n.
(FromInteger n, MGroup n) =>
Bytes s n -> Bytes (NextSize s) n
incSize Bytes s n
bytes
        | Bool
otherwise -> SSize s -> Bytes s n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize s
sz Bytes s n
bytes
      SSize s
SP
        | Bool
tooSmall -> Bytes 'T n -> Norm (Bytes 'T n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'T n -> Norm (Bytes 'T n))
-> Bytes 'T n -> Norm (Bytes 'T n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (PrevSize s) n
forall (s :: Size) n.
(FromInteger n, MSemigroup n) =>
Bytes s n -> Bytes (PrevSize s) n
decSize Bytes s n
bytes
        | Bool
tooLarge -> Bytes 'E n -> Norm (Bytes 'E n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'E n -> Norm (Bytes 'E n))
-> Bytes 'E n -> Norm (Bytes 'E n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (NextSize s) n
forall (s :: Size) n.
(FromInteger n, MGroup n) =>
Bytes s n -> Bytes (NextSize s) n
incSize Bytes s n
bytes
        | Bool
otherwise -> SSize s -> Bytes s n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize s
sz Bytes s n
bytes
      SSize s
SE
        | Bool
tooSmall -> Bytes 'P n -> Norm (Bytes 'P n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'P n -> Norm (Bytes 'P n))
-> Bytes 'P n -> Norm (Bytes 'P n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (PrevSize s) n
forall (s :: Size) n.
(FromInteger n, MSemigroup n) =>
Bytes s n -> Bytes (PrevSize s) n
decSize Bytes s n
bytes
        | Bool
tooLarge -> Bytes 'Z n -> Norm (Bytes 'Z n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'Z n -> Norm (Bytes 'Z n))
-> Bytes 'Z n -> Norm (Bytes 'Z n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (NextSize s) n
forall (s :: Size) n.
(FromInteger n, MGroup n) =>
Bytes s n -> Bytes (NextSize s) n
incSize Bytes s n
bytes
        | Bool
otherwise -> SSize s -> Bytes s n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize s
sz Bytes s n
bytes
      SSize s
SZ
        | Bool
tooSmall -> Bytes 'E n -> Norm (Bytes 'E n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'E n -> Norm (Bytes 'E n))
-> Bytes 'E n -> Norm (Bytes 'E n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (PrevSize s) n
forall (s :: Size) n.
(FromInteger n, MSemigroup n) =>
Bytes s n -> Bytes (PrevSize s) n
decSize Bytes s n
bytes
        | Bool
tooLarge -> Bytes 'Y n -> Norm (Bytes 'Y n)
forall a. Normalize a => a -> Norm a
normalize (Bytes 'Y n -> Norm (Bytes 'Y n))
-> Bytes 'Y n -> Norm (Bytes 'Y n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Bytes (NextSize s) n
forall (s :: Size) n.
(FromInteger n, MGroup n) =>
Bytes s n -> Bytes (NextSize s) n
incSize Bytes s n
bytes
        | Bool
otherwise -> SSize s -> Bytes s n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize s
sz Bytes s n
bytes
    where
      absBytes :: n
absBytes = n -> n
forall s. Normed s => s -> s
norm n
x
      tooSmall :: Bool
tooSmall = n
absBytes n -> n -> Bool
forall a. Ord a => a -> a -> Bool
< Integer -> n
forall a. (FromInteger a, HasCallStack) => Integer -> a
afromInteger Integer
1
      tooLarge :: Bool
tooLarge = n
absBytes n -> n -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer -> n
forall a. (FromInteger a, HasCallStack) => Integer -> a
afromInteger Integer
1_000
      sz :: SSize s
sz = Bytes s n -> SSize s
forall (s :: Size) n. SingSize s => Bytes s n -> SSize s
bytesToSSize Bytes s n
bytes
  {-# INLINEABLE normalize #-}

-- | @since 0.1
instance (SingSize s) => Sized (Bytes s n) where
  type HideSize (Bytes s n) = SomeSize n

  sizeOf :: Bytes s n -> Size
sizeOf = SSize s -> Size
forall (s :: Size). SSize s -> Size
Size.ssizeToSize (SSize s -> Size) -> (Bytes s n -> SSize s) -> Bytes s n -> Size
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes s n -> SSize s
forall (s :: Size) n. SingSize s => Bytes s n -> SSize s
bytesToSSize
  {-# INLINE sizeOf #-}

  hideSize :: Bytes s n -> HideSize (Bytes s n)
hideSize b :: Bytes s n
b@(MkBytes n
_) = SSize s -> Bytes s n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize (forall (s :: Size). SingSize s => SSize s
singSize @s) Bytes s n
b
  {-# INLINE hideSize #-}

-- | @since 0.1
instance RawNumeric (Bytes s n) where
  type Raw (Bytes s n) = n
  toRaw :: Bytes s n -> Raw (Bytes s n)
toRaw (MkBytes n
x) = n
Raw (Bytes s n)
x
  {-# INLINE toRaw #-}

-- | @since 0.1
instance (Read n) => Parser (Bytes s n) where
  parser :: Parsec Void Text (Bytes s n)
parser = n -> Bytes s n
forall (s :: Size) n. n -> Bytes s n
MkBytes (n -> Bytes s n)
-> ParsecT Void Text Identity n -> Parsec Void Text (Bytes s n)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT Void Text Identity n
forall n. Read n => Parsec Void Text n
Parser.parseDigits ParsecT Void Text Identity n
-> ParsecT Void Text Identity () -> ParsecT Void Text Identity n
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (ParsecT Void Text Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
MPC.space ParsecT Void Text Identity ()
-> ParsecT Void Text Identity () -> ParsecT Void Text Identity ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Void Text Identity ()
forall e s (m :: * -> *). MonadParsec e s m => m ()
MP.eof))

-- | Wrapper for 'Bytes', existentially quantifying the size. This is useful
-- when a function does not know a priori what size it should return e.g.
--
-- >>> :{
--   getFileSize :: FilePath -> IO (SomeSize Float)
--   getFileSize path = do
--     -- getRawFileSize :: FilePath -> IO (Float, String)
--     (bytes, units) <- getRawFileSize path
--     pure $ case units of
--       "B" -> hideSize $ MkBytes @B bytes
--       "K" -> hideSize $ MkBytes @K bytes
--       _ -> error "todo"
-- :}
--
-- We define an equivalence relation on 'SomeSize' that takes units into
-- account. For instance,
--
-- >>> hideSize (MkBytes @G 7) == hideSize (MkBytes @M 7_000)
-- True
--
-- Because we expose the underlying @Bytes@ in several ways (e.g. 'Show',
-- the 'SSize' witness), this is technically unlawful for equality
-- as it breaks the extensionality law:
--
-- \[
-- x = y \implies f(x) = f(y).
-- \]
--
-- @since 0.1
type SomeSize :: Type -> Type
data SomeSize (n :: Type) where
  -- | @since 0.1
  MkSomeSize :: SSize s -> Bytes s n -> SomeSize n

-- | 'Iso'' between 'SomeSize' and underlying 'Bytes'. Performs any necessary
-- conversions when going from @SomeSize n -> Bytes s n@.
--
-- ==== __Examples__
--
-- >>> import Optics.Core (review, view)
-- >>> review _MkSomeSize (MkBytes @K @Int 70)
-- MkSomeSize SK (MkBytes 70)
--
-- >>> (view _MkSomeSize (hideSize $ MkBytes @K @Int 70)) :: Bytes B Int
-- MkBytes 70000
--
-- @since 0.1
_MkSomeSize :: forall s n. (FromInteger n, MGroup n, SingSize s) => Iso' (SomeSize n) (Bytes s n)
_MkSomeSize :: forall (s :: Size) n.
(FromInteger n, MGroup n, SingSize s) =>
Iso' (SomeSize n) (Bytes s n)
_MkSomeSize = (SomeSize n -> Bytes s n)
-> (Bytes s n -> SomeSize n)
-> Iso (SomeSize n) (SomeSize n) (Bytes s n) (Bytes s n)
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso (Proxy s -> SomeSize n -> Converted s (SomeSize n)
forall a (t :: Size).
(Conversion a, SingSize t) =>
Proxy t -> a -> Converted t a
forall (t :: Size).
SingSize t =>
Proxy t -> SomeSize n -> Converted t (SomeSize n)
convert Proxy s
forall {k} (t :: k). Proxy t
Proxy) Bytes s n -> HideSize (Bytes s n)
Bytes s n -> SomeSize n
forall a. Sized a => a -> HideSize a
hideSize
{-# INLINE _MkSomeSize #-}

-- | @since 0.1
deriving stock instance (Show n) => Show (SomeSize n)

-- | @since 0.1
deriving stock instance Functor SomeSize

-- | @since 0.1
instance Foldable SomeSize where
  foldr :: forall a b. (a -> b -> b) -> b -> SomeSize a -> b
foldr a -> b -> b
f b
e (MkSomeSize SSize s
_ (MkBytes a
x)) = a -> b -> b
f a
x b
e
  {-# INLINE foldr #-}

-- | @since 0.1
instance Traversable SomeSize where
  traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> SomeSize a -> f (SomeSize b)
traverse a -> f b
f (MkSomeSize SSize s
sz (MkBytes a
x)) = SSize s -> Bytes s b -> SomeSize b
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize s
sz (Bytes s b -> SomeSize b) -> (b -> Bytes s b) -> b -> SomeSize b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Bytes s b
forall (s :: Size) n. n -> Bytes s n
MkBytes (b -> SomeSize b) -> f b -> f (SomeSize b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f b
f a
x
  {-# INLINE traverse #-}

  sequenceA :: forall (f :: * -> *) a.
Applicative f =>
SomeSize (f a) -> f (SomeSize a)
sequenceA (MkSomeSize SSize s
sz (MkBytes f a
x)) = SSize s -> Bytes s a -> SomeSize a
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize s
sz (Bytes s a -> SomeSize a) -> (a -> Bytes s a) -> a -> SomeSize a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bytes s a
forall (s :: Size) n. n -> Bytes s n
MkBytes (a -> SomeSize a) -> f a -> f (SomeSize a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f a
x
  {-# INLINE sequenceA #-}

#if MIN_VERSION_base(4, 16, 0)

-- | @since 0.1
instance HasField "unSomeSize" (SomeSize n) n where
  getField :: SomeSize n -> n
getField (MkSomeSize SSize s
_ (MkBytes n
x)) = n
x

#endif

-- | @since 0.1
instance
  ( k ~ A_Getter,
    a ~ n,
    b ~ n
  ) =>
  LabelOptic "unSomeSize" k (SomeSize n) (SomeSize n) a b
  where
  labelOptic :: Optic k NoIx (SomeSize n) (SomeSize n) a b
labelOptic = (SomeSize n -> a) -> Getter (SomeSize n) a
forall s a. (s -> a) -> Getter s a
to (\(MkSomeSize SSize s
_ (MkBytes n
x)) -> a
n
x)
  {-# INLINE labelOptic #-}

-- | @since 0.1
instance (FromInteger n, Hashable n, MGroup n) => Hashable (SomeSize n) where
  hashWithSalt :: Int -> SomeSize n -> Int
hashWithSalt Int
i (MkSomeSize SSize s
sz Bytes s n
x) =
    Int
i Int -> Size -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` SSize s -> Size
forall (s :: Size). SSize s -> Size
Size.ssizeToSize SSize s
sz Int -> Bytes s n -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Bytes s n
x

-- | @since 0.1
instance (NFData n) => NFData (SomeSize n) where
  rnf :: SomeSize n -> ()
rnf (MkSomeSize SSize s
sz Bytes s n
x) = SSize s
sz SSize s -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` Bytes s n
x Bytes s n -> () -> ()
forall a b. NFData a => a -> b -> b
`deepseq` ()

-- | @since 0.1
instance (Eq n, FromInteger n, MGroup n) => Eq (SomeSize n) where
  SomeSize n
x == :: SomeSize n -> SomeSize n -> Bool
== SomeSize n
y = forall a (t :: Size).
(Conversion a, SingSize t) =>
Proxy t -> a -> Converted t a
convert @_ @B Proxy 'B
forall {k} (t :: k). Proxy t
Proxy SomeSize n
x Bytes 'B n -> Bytes 'B n -> Bool
forall a. Eq a => a -> a -> Bool
== Proxy 'B -> SomeSize n -> Converted 'B (SomeSize n)
forall a (t :: Size).
(Conversion a, SingSize t) =>
Proxy t -> a -> Converted t a
forall (t :: Size).
SingSize t =>
Proxy t -> SomeSize n -> Converted t (SomeSize n)
convert Proxy 'B
forall {k} (t :: k). Proxy t
Proxy SomeSize n
y
  {-# INLINE (==) #-}

-- | @since 0.1
instance (FromInteger n, MGroup n, Ord n) => Ord (SomeSize n) where
  SomeSize n
x <= :: SomeSize n -> SomeSize n -> Bool
<= SomeSize n
y = forall a (t :: Size).
(Conversion a, SingSize t) =>
Proxy t -> a -> Converted t a
convert @_ @B Proxy 'B
forall {k} (t :: k). Proxy t
Proxy SomeSize n
x Bytes 'B n -> Bytes 'B n -> Bool
forall a. Ord a => a -> a -> Bool
<= Proxy 'B -> SomeSize n -> Converted 'B (SomeSize n)
forall a (t :: Size).
(Conversion a, SingSize t) =>
Proxy t -> a -> Converted t a
forall (t :: Size).
SingSize t =>
Proxy t -> SomeSize n -> Converted t (SomeSize n)
convert Proxy 'B
forall {k} (t :: k). Proxy t
Proxy SomeSize n
y
  {-# INLINE (<=) #-}

-- | Fixed size 'B'.
--
-- @since 0.1
instance (FromInteger n) => FromInteger (SomeSize n) where
  afromInteger :: HasCallStack => Integer -> SomeSize n
afromInteger = SSize 'B -> Bytes 'B n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize 'B
SB (Bytes 'B n -> SomeSize n)
-> (Integer -> Bytes 'B n) -> Integer -> SomeSize n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Bytes 'B n
forall a. (FromInteger a, HasCallStack) => Integer -> a
afromInteger
  {-# INLINE afromInteger #-}

-- | Fixed size 'B'.
--
-- @since 0.1
instance (FromRational n) => FromRational (SomeSize n) where
  afromRational :: HasCallStack => Rational -> SomeSize n
afromRational = SSize 'B -> Bytes 'B n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize 'B
SB (Bytes 'B n -> SomeSize n)
-> (Rational -> Bytes 'B n) -> Rational -> SomeSize n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Bytes 'B n
forall a. (FromRational a, HasCallStack) => Rational -> a
afromRational
  {-# INLINE afromRational #-}

-- | @since 0.1
instance (ASemigroup n, FromInteger n, MGroup n) => ASemigroup (SomeSize n) where
  SomeSize n
x .+. :: SomeSize n -> SomeSize n -> SomeSize n
.+. SomeSize n
y = SSize 'B -> Bytes 'B n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize 'B
SB (Bytes 'B n -> SomeSize n) -> Bytes 'B n -> SomeSize n
forall a b. (a -> b) -> a -> b
$ Proxy 'B -> SomeSize n -> Converted 'B (SomeSize n)
forall a (t :: Size).
(Conversion a, SingSize t) =>
Proxy t -> a -> Converted t a
forall (t :: Size).
SingSize t =>
Proxy t -> SomeSize n -> Converted t (SomeSize n)
convert Proxy 'B
forall {k} (t :: k). Proxy t
Proxy SomeSize n
x Bytes 'B n -> Bytes 'B n -> Bytes 'B n
forall s. ASemigroup s => s -> s -> s
.+. Proxy 'B -> SomeSize n -> Converted 'B (SomeSize n)
forall a (t :: Size).
(Conversion a, SingSize t) =>
Proxy t -> a -> Converted t a
forall (t :: Size).
SingSize t =>
Proxy t -> SomeSize n -> Converted t (SomeSize n)
convert Proxy 'B
forall {k} (t :: k). Proxy t
Proxy SomeSize n
y
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance (FromInteger n, Semifield n) => AMonoid (SomeSize n) where
  zero :: SomeSize n
zero = SSize 'B -> Bytes 'B n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize 'B
SB Bytes 'B n
forall m. AMonoid m => m
zero
  {-# INLINE zero #-}

-- | @since 0.1
instance (Field n, FromInteger n) => AGroup (SomeSize n) where
  SomeSize n
x .-. :: SomeSize n -> SomeSize n -> SomeSize n
.-. SomeSize n
y = SSize 'B -> Bytes 'B n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize 'B
SB (Bytes 'B n -> SomeSize n) -> Bytes 'B n -> SomeSize n
forall a b. (a -> b) -> a -> b
$ Proxy 'B -> SomeSize n -> Converted 'B (SomeSize n)
forall a (t :: Size).
(Conversion a, SingSize t) =>
Proxy t -> a -> Converted t a
forall (t :: Size).
SingSize t =>
Proxy t -> SomeSize n -> Converted t (SomeSize n)
convert Proxy 'B
forall {k} (t :: k). Proxy t
Proxy SomeSize n
x Bytes 'B n -> Bytes 'B n -> Bytes 'B n
forall g. AGroup g => g -> g -> g
.-. Proxy 'B -> SomeSize n -> Converted 'B (SomeSize n)
forall a (t :: Size).
(Conversion a, SingSize t) =>
Proxy t -> a -> Converted t a
forall (t :: Size).
SingSize t =>
Proxy t -> SomeSize n -> Converted t (SomeSize n)
convert Proxy 'B
forall {k} (t :: k). Proxy t
Proxy SomeSize n
y
  {-# INLINE (.-.) #-}

-- | @since 0.1
instance (MGroup n) => MSemiSpace (SomeSize n) n where
  MkSomeSize SSize s
sz Bytes s n
x .* :: SomeSize n -> n -> SomeSize n
.* n
k = SSize s -> Bytes s n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize s
sz (Bytes s n -> SomeSize n) -> Bytes s n -> SomeSize n
forall a b. (a -> b) -> a -> b
$ Bytes s n
x Bytes s n -> n -> Bytes s n
forall m r. MSemiSpace m r => m -> r -> m
.* n
k
  {-# INLINE (.*) #-}

-- | @since 0.1
instance (MGroup n) => MSpace (SomeSize n) n where
  MkSomeSize SSize s
sz Bytes s n
x .% :: SomeSize n -> n -> SomeSize n
.% n
k = SSize s -> Bytes s n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize s
sz (Bytes s n -> SomeSize n) -> Bytes s n -> SomeSize n
forall a b. (a -> b) -> a -> b
$ Bytes s n
x Bytes s n -> n -> Bytes s n
forall v k. MSpace v k => v -> k -> v
.% n
k
  {-# INLINEABLE (.%) #-}

-- | @since 0.1
instance (Normed n) => Normed (SomeSize n) where
  norm :: SomeSize n -> SomeSize n
norm (MkSomeSize SSize s
sz Bytes s n
x) = SSize s -> Bytes s n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize s
sz (Bytes s n -> Bytes s n
forall s. Normed s => s -> s
norm Bytes s n
x)
  {-# INLINE norm #-}

-- | @since 0.1
instance (FromInteger n, Semifield n) => Semimodule (SomeSize n) n

-- | @since 0.1
instance (Field n, FromInteger n) => Module (SomeSize n) n

-- | @since 0.1
instance (FromInteger n, Semifield n) => SemivectorSpace (SomeSize n) n

-- | @since 0.1
instance (Field n, FromInteger n) => VectorSpace (SomeSize n) n

-- | @since 0.1
instance (FromInteger n, MGroup n) => Conversion (SomeSize n) where
  type Converted t (SomeSize n) = Bytes t n

  convert :: forall t. (SingSize t) => Proxy t -> SomeSize n -> Bytes t n
  convert :: forall (t :: Size).
SingSize t =>
Proxy t -> SomeSize n -> Bytes t n
convert Proxy t
proxy (MkSomeSize SSize s
sz Bytes s n
x) = SSize s -> (SingSize s => Bytes t n) -> Bytes t n
forall (s :: Size) r. SSize s -> (SingSize s => r) -> r
Size.withSingSize SSize s
sz ((SingSize s => Bytes t n) -> Bytes t n)
-> (SingSize s => Bytes t n) -> Bytes t n
forall a b. (a -> b) -> a -> b
$ Proxy t -> Bytes s n -> Converted t (Bytes s n)
forall a (t :: Size).
(Conversion a, SingSize t) =>
Proxy t -> a -> Converted t a
forall (t :: Size).
SingSize t =>
Proxy t -> Bytes s n -> Converted t (Bytes s n)
convert Proxy t
proxy Bytes s n
x

-- | @since 0.1
instance (FromInteger n, MGroup n, Normed n, Ord n) => Normalize (SomeSize n) where
  type Norm (SomeSize n) = SomeSize n
  normalize :: SomeSize n -> Norm (SomeSize n)
normalize (MkSomeSize SSize s
sz Bytes s n
x) = SSize s -> (SingSize s => Norm (SomeSize n)) -> Norm (SomeSize n)
forall (s :: Size) r. SSize s -> (SingSize s => r) -> r
Size.withSingSize SSize s
sz ((SingSize s => Norm (SomeSize n)) -> Norm (SomeSize n))
-> (SingSize s => Norm (SomeSize n)) -> Norm (SomeSize n)
forall a b. (a -> b) -> a -> b
$ Bytes s n -> Norm (Bytes s n)
forall a. Normalize a => a -> Norm a
normalize Bytes s n
x
  {-# INLINE normalize #-}

-- | @since 0.1
instance Sized (SomeSize n) where
  type HideSize (SomeSize n) = SomeSize n

  sizeOf :: SomeSize n -> Size
sizeOf (MkSomeSize SSize s
sz Bytes s n
_) = SSize s -> Size
forall (s :: Size). SSize s -> Size
Size.ssizeToSize SSize s
sz
  {-# INLINE sizeOf #-}

  hideSize :: SomeSize n -> HideSize (SomeSize n)
hideSize = SomeSize n -> HideSize (SomeSize n)
SomeSize n -> SomeSize n
forall a. a -> a
id
  {-# INLINE hideSize #-}

-- | @since 0.1
instance RawNumeric (SomeSize n) where
  type Raw (SomeSize n) = n
  toRaw :: SomeSize n -> Raw (SomeSize n)
toRaw (MkSomeSize SSize s
_ Bytes s n
b) = Bytes s n -> Raw (Bytes s n)
forall a. RawNumeric a => a -> Raw a
toRaw Bytes s n
b
  {-# INLINE toRaw #-}

-- | @since 0.1
instance (Read n) => Parser (SomeSize n) where
  parser :: Parsec Void Text (SomeSize n)
parser = do
    n
bytes <- Parsec Void Text n
forall n. Read n => Parsec Void Text n
Parser.parseDigits
    ParsecT Void Text Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
MPC.space
    Size
sz <- Parsec Void Text Size
forall a. Parser a => Parsec Void Text a
parser
    ParsecT Void Text Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
MPC.space
    ParsecT Void Text Identity ()
forall e s (m :: * -> *). MonadParsec e s m => m ()
MP.eof
    pure $ case Size
sz of
      Size
B -> SSize 'B -> Bytes 'B n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize 'B
SB (Bytes 'B n -> SomeSize n) -> Bytes 'B n -> SomeSize n
forall a b. (a -> b) -> a -> b
$ n -> Bytes 'B n
forall (s :: Size) n. n -> Bytes s n
MkBytes n
bytes
      Size
K -> SSize 'K -> Bytes 'K n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize 'K
SK (Bytes 'K n -> SomeSize n) -> Bytes 'K n -> SomeSize n
forall a b. (a -> b) -> a -> b
$ n -> Bytes 'K n
forall (s :: Size) n. n -> Bytes s n
MkBytes n
bytes
      Size
M -> SSize 'M -> Bytes 'M n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize 'M
SM (Bytes 'M n -> SomeSize n) -> Bytes 'M n -> SomeSize n
forall a b. (a -> b) -> a -> b
$ n -> Bytes 'M n
forall (s :: Size) n. n -> Bytes s n
MkBytes n
bytes
      Size
G -> SSize 'G -> Bytes 'G n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize 'G
SG (Bytes 'G n -> SomeSize n) -> Bytes 'G n -> SomeSize n
forall a b. (a -> b) -> a -> b
$ n -> Bytes 'G n
forall (s :: Size) n. n -> Bytes s n
MkBytes n
bytes
      Size
T -> SSize 'T -> Bytes 'T n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize 'T
ST (Bytes 'T n -> SomeSize n) -> Bytes 'T n -> SomeSize n
forall a b. (a -> b) -> a -> b
$ n -> Bytes 'T n
forall (s :: Size) n. n -> Bytes s n
MkBytes n
bytes
      Size
P -> SSize 'P -> Bytes 'P n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize 'P
SP (Bytes 'P n -> SomeSize n) -> Bytes 'P n -> SomeSize n
forall a b. (a -> b) -> a -> b
$ n -> Bytes 'P n
forall (s :: Size) n. n -> Bytes s n
MkBytes n
bytes
      Size
E -> SSize 'E -> Bytes 'E n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize 'E
SE (Bytes 'E n -> SomeSize n) -> Bytes 'E n -> SomeSize n
forall a b. (a -> b) -> a -> b
$ n -> Bytes 'E n
forall (s :: Size) n. n -> Bytes s n
MkBytes n
bytes
      Size
Z -> SSize 'Z -> Bytes 'Z n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize 'Z
SZ (Bytes 'Z n -> SomeSize n) -> Bytes 'Z n -> SomeSize n
forall a b. (a -> b) -> a -> b
$ n -> Bytes 'Z n
forall (s :: Size) n. n -> Bytes s n
MkBytes n
bytes
      Size
Y -> SSize 'Y -> Bytes 'Y n -> SomeSize n
forall (s :: Size) n. SSize s -> Bytes s n -> SomeSize n
MkSomeSize SSize 'Y
SY (Bytes 'Y n -> SomeSize n) -> Bytes 'Y n -> SomeSize n
forall a b. (a -> b) -> a -> b
$ n -> Bytes 'Y n
forall (s :: Size) n. n -> Bytes s n
MkBytes n
bytes
  {-# INLINEABLE parser #-}

-- | Increases 'Bytes' to the next size.
--
-- ==== __Examples__
--
-- >> incSize $ MkBytes @M @Float 2_500
-- MkBytes 2.5
--
-- >> -- type error: "The byte unit Y does not have a 'next size'."
-- >> --incSize $ MkBytes @Y @Float 2_500
--
-- @since 0.1
incSize :: forall s n. (FromInteger n, MGroup n) => Bytes s n -> Bytes (NextSize s) n
incSize :: forall (s :: Size) n.
(FromInteger n, MGroup n) =>
Bytes s n -> Bytes (NextSize s) n
incSize = Bytes Any n -> Bytes (NextSize s) n
forall (s :: Size) n (t :: Size). Bytes s n -> Bytes t n
resizeBytes (Bytes Any n -> Bytes (NextSize s) n)
-> (Bytes s n -> Bytes Any n) -> Bytes s n -> Bytes (NextSize s) n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> Bytes Any n
forall (s :: Size) n. n -> Bytes s n
MkBytes (n -> Bytes Any n) -> (Bytes s n -> n) -> Bytes s n -> Bytes Any n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (n -> n -> n
forall g. MGroup g => g -> g -> g
.%. n
nz1000) (n -> n) -> (Bytes s n -> n) -> Bytes s n -> n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes s n -> n
Bytes s n -> Raw (Bytes s n)
forall a. RawNumeric a => a -> Raw a
toRaw
  where
    nz1000 :: n
nz1000 = Integer -> n
forall a. (FromInteger a, HasCallStack) => Integer -> a
afromInteger Integer
1_000
{-# INLINE incSize #-}

-- | Decreases 'Bytes' to the previous size.
--
-- ==== __Examples__
--
-- >> decSize $ MkBytes @M @Float 2.5
-- MkBytes 2500.0
--
-- >> -- type error: "The byte unit B does not have a 'previous size'."
-- >> --decSize $ MkBytes @B @Float 2.5
--
-- @since 0.1
decSize :: forall s n. (FromInteger n, MSemigroup n) => Bytes s n -> Bytes (PrevSize s) n
decSize :: forall (s :: Size) n.
(FromInteger n, MSemigroup n) =>
Bytes s n -> Bytes (PrevSize s) n
decSize = Bytes Any n -> Bytes (PrevSize s) n
forall (s :: Size) n (t :: Size). Bytes s n -> Bytes t n
resizeBytes (Bytes Any n -> Bytes (PrevSize s) n)
-> (Bytes s n -> Bytes Any n) -> Bytes s n -> Bytes (PrevSize s) n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> Bytes Any n
forall (s :: Size) n. n -> Bytes s n
MkBytes (n -> Bytes Any n) -> (Bytes s n -> n) -> Bytes s n -> Bytes Any n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (n -> n -> n
forall s. MSemigroup s => s -> s -> s
.*. forall a. (FromInteger a, HasCallStack) => Integer -> a
afromInteger @n Integer
1_000) (n -> n) -> (Bytes s n -> n) -> Bytes s n -> n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes s n -> n
Bytes s n -> Raw (Bytes s n)
forall a. RawNumeric a => a -> Raw a
toRaw
{-# INLINE decSize #-}