{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Data.Connection.Int (
    -- * Int16
    w08i16,
    i08i16,

    -- * Int32
    w08i32,
    w16i32,
    i08i32,
    i16i32,

    -- * Int64
    w08i64,
    w16i64,
    w32i64,
    i08i64,
    i16i64,
    i32i64,

    -- * Int
    w08ixx,
    w16ixx,
    w32ixx,
    i08ixx,
    i16ixx,
    i32ixx,
    i64ixx,

    -- * Integer
    w08int,
    w16int,
    w32int,
    w64int,
    wxxint,
    natint,
    i08int,
    i16int,
    i32int,
    i64int,
    ixxint,
) where

import safe Control.Applicative
import safe Control.Monad
import safe Data.Connection.Conn
import safe Data.Int
import safe Data.Word
import safe Numeric.Natural
import safe Prelude

-- Int16
w08i16 :: ConnL Word8 (Maybe Int16)
w08i16 :: ConnL Word8 (Maybe Int16)
w08i16 = ConnL Word8 (Maybe Int16)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

i08i16 :: ConnL Int8 (Maybe Int16)
i08i16 :: ConnL Int8 (Maybe Int16)
i08i16 = ConnL Int8 (Maybe Int16)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

-- Int32
w08i32 :: ConnL Word8 (Maybe Int32)
w08i32 :: ConnL Word8 (Maybe Int32)
w08i32 = ConnL Word8 (Maybe Int32)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

w16i32 :: ConnL Word16 (Maybe Int32)
w16i32 :: ConnL Word16 (Maybe Int32)
w16i32 = ConnL Word16 (Maybe Int32)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

i08i32 :: ConnL Int8 (Maybe Int32)
i08i32 :: ConnL Int8 (Maybe Int32)
i08i32 = ConnL Int8 (Maybe Int32)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

i16i32 :: ConnL Int16 (Maybe Int32)
i16i32 :: ConnL Int16 (Maybe Int32)
i16i32 = ConnL Int16 (Maybe Int32)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

-- Int64
w08i64 :: ConnL Word8 (Maybe Int64)
w08i64 :: ConnL Word8 (Maybe Int64)
w08i64 = ConnL Word8 (Maybe Int64)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

w16i64 :: ConnL Word16 (Maybe Int64)
w16i64 :: ConnL Word16 (Maybe Int64)
w16i64 = ConnL Word16 (Maybe Int64)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

w32i64 :: ConnL Word32 (Maybe Int64)
w32i64 :: ConnL Word32 (Maybe Int64)
w32i64 = ConnL Word32 (Maybe Int64)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

i08i64 :: ConnL Int8 (Maybe Int64)
i08i64 :: ConnL Int8 (Maybe Int64)
i08i64 = ConnL Int8 (Maybe Int64)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

i16i64 :: ConnL Int16 (Maybe Int64)
i16i64 :: ConnL Int16 (Maybe Int64)
i16i64 = ConnL Int16 (Maybe Int64)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

i32i64 :: ConnL Int32 (Maybe Int64)
i32i64 :: ConnL Int32 (Maybe Int64)
i32i64 = ConnL Int32 (Maybe Int64)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

-- Int
w08ixx :: ConnL Word8 (Maybe Int)
w08ixx :: ConnL Word8 (Maybe Int)
w08ixx = ConnL Word8 (Maybe Int)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

w16ixx :: ConnL Word16 (Maybe Int)
w16ixx :: ConnL Word16 (Maybe Int)
w16ixx = ConnL Word16 (Maybe Int)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

w32ixx :: ConnL Word32 (Maybe Int)
w32ixx :: ConnL Word32 (Maybe Int)
w32ixx = ConnL Word32 (Maybe Int)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

i08ixx :: ConnL Int8 (Maybe Int)
i08ixx :: ConnL Int8 (Maybe Int)
i08ixx = ConnL Int8 (Maybe Int)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

i16ixx :: ConnL Int16 (Maybe Int)
i16ixx :: ConnL Int16 (Maybe Int)
i16ixx = ConnL Int16 (Maybe Int)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

i32ixx :: ConnL Int32 (Maybe Int)
i32ixx :: ConnL Int32 (Maybe Int)
i32ixx = ConnL Int32 (Maybe Int)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

-- | /Caution/: This assumes that 'Int' on your system is 64 bits.
i64ixx :: Conn k Int64 Int
i64ixx :: Conn k Int64 Int
i64ixx = (Int64 -> Int)
-> (Int -> Int64) -> (Int64 -> Int) -> Conn k Int64 Int
forall a b (k :: Kan).
(a -> b) -> (b -> a) -> (a -> b) -> Conn k a b
Conn Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral

-- Integer
w08int :: ConnL Word8 (Maybe Integer)
w08int :: ConnL Word8 (Maybe Integer)
w08int = ConnL Word8 (Maybe Integer)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

w16int :: ConnL Word16 (Maybe Integer)
w16int :: ConnL Word16 (Maybe Integer)
w16int = ConnL Word16 (Maybe Integer)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

w32int :: ConnL Word32 (Maybe Integer)
w32int :: ConnL Word32 (Maybe Integer)
w32int = ConnL Word32 (Maybe Integer)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

w64int :: ConnL Word64 (Maybe Integer)
w64int :: ConnL Word64 (Maybe Integer)
w64int = ConnL Word64 (Maybe Integer)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

wxxint :: ConnL Word (Maybe Integer)
wxxint :: ConnL Word (Maybe Integer)
wxxint = ConnL Word (Maybe Integer)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

natint :: ConnL Natural (Maybe Integer)
natint :: ConnL Natural (Maybe Integer)
natint = (Natural -> Maybe Integer)
-> (Maybe Integer -> Natural) -> ConnL Natural (Maybe Integer)
forall a b. (a -> b) -> (b -> a) -> ConnL a b
ConnL ((Natural -> Integer) -> Maybe Natural -> Maybe Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Natural -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Maybe Natural -> Maybe Integer)
-> (Natural -> Maybe Natural) -> Natural -> Maybe Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Natural -> Bool) -> Natural -> Maybe Natural
forall a. (a -> Bool) -> a -> Maybe a
fromPred (Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
/= Natural
0)) (Natural -> (Integer -> Natural) -> Maybe Integer -> Natural
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Natural
0 ((Integer -> Natural) -> Maybe Integer -> Natural)
-> (Integer -> Natural) -> Maybe Integer -> Natural
forall a b. (a -> b) -> a -> b
$ Integer -> Natural
forall a. Num a => Integer -> a
fromInteger (Integer -> Natural) -> (Integer -> Integer) -> Integer -> Natural
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Integer -> Integer
forall a. Ord a => a -> a -> a
max Integer
0)

i08int :: ConnL Int8 (Maybe Integer)
i08int :: ConnL Int8 (Maybe Integer)
i08int = ConnL Int8 (Maybe Integer)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

i16int :: ConnL Int16 (Maybe Integer)
i16int :: ConnL Int16 (Maybe Integer)
i16int = ConnL Int16 (Maybe Integer)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

i32int :: ConnL Int32 (Maybe Integer)
i32int :: ConnL Int32 (Maybe Integer)
i32int = ConnL Int32 (Maybe Integer)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

i64int :: ConnL Int64 (Maybe Integer)
i64int :: ConnL Int64 (Maybe Integer)
i64int = ConnL Int64 (Maybe Integer)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

ixxint :: ConnL Int (Maybe Integer)
ixxint :: ConnL Int (Maybe Integer)
ixxint = ConnL Int (Maybe Integer)
forall a b.
(Bounded a, Integral a, Integral b) =>
ConnL a (Maybe b)
signed

---------------------------------------------------------------------
-- Internal
---------------------------------------------------------------------

fromPred :: (a -> Bool) -> a -> Maybe a
fromPred :: (a -> Bool) -> a -> Maybe a
fromPred a -> Bool
p a
a = a
a a -> Maybe () -> Maybe a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (a -> Bool
p a
a)

signed :: forall a b. (Bounded a, Integral a, Integral b) => ConnL a (Maybe b)
signed :: ConnL a (Maybe b)
signed = (a -> Maybe b) -> (Maybe b -> a) -> ConnL a (Maybe b)
forall a b. (a -> b) -> (b -> a) -> ConnL a b
ConnL a -> Maybe b
f Maybe b -> a
g
  where
    f :: a -> Maybe b
f = (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Maybe a -> Maybe b) -> (a -> Maybe a) -> a -> Maybe b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> a -> Maybe a
forall a. (a -> Bool) -> a -> Maybe a
fromPred (a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
forall a. Bounded a => a
minBound)
    g :: Maybe b -> a
g = a -> (b -> a) -> Maybe b -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
forall a. Bounded a => a
minBound ((b -> a) -> Maybe b -> a) -> (b -> a) -> Maybe b -> a
forall a b. (a -> b) -> a -> b
$ forall b. (Integral b, Num b) => b -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral @b (b -> a) -> (b -> b) -> b -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> b -> b
forall a. Ord a => a -> a -> a
min (a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral @a a
forall a. Bounded a => a
maxBound) (b -> b) -> (b -> b) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> b -> b
forall a. Ord a => a -> a -> a
max (a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral @a a
forall a. Bounded a => a
minBound)