module Data.Bytes.Network.Direction
(
Direction (..),
SDirection (..),
SingDirection (..),
Directed (..),
withSingDirection,
sdirectionToDirection,
_Down,
_Up,
)
where
import Control.DeepSeq (NFData (rnf))
import Data.Bytes.Class.Parser (Parser (parser))
import Data.Hashable (Hashable)
import Data.Kind (Constraint, Type)
import Data.Type.Equality (TestEquality (testEquality), (:~:) (Refl))
import GHC.Generics (Generic)
import Optics.Core (Prism', prism)
import Text.Megaparsec qualified as MP
import Text.Megaparsec.Char qualified as MPC
type Direction :: Type
data Direction
=
Down
|
Up
deriving stock
(
Direction -> Direction -> Bool
(Direction -> Direction -> Bool)
-> (Direction -> Direction -> Bool) -> Eq Direction
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Direction -> Direction -> Bool
== :: Direction -> Direction -> Bool
$c/= :: Direction -> Direction -> Bool
/= :: Direction -> Direction -> Bool
Eq,
(forall x. Direction -> Rep Direction x)
-> (forall x. Rep Direction x -> Direction) -> Generic Direction
forall x. Rep Direction x -> Direction
forall x. Direction -> Rep Direction x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Direction -> Rep Direction x
from :: forall x. Direction -> Rep Direction x
$cto :: forall x. Rep Direction x -> Direction
to :: forall x. Rep Direction x -> Direction
Generic,
Int -> Direction -> ShowS
[Direction] -> ShowS
Direction -> String
(Int -> Direction -> ShowS)
-> (Direction -> String)
-> ([Direction] -> ShowS)
-> Show Direction
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Direction -> ShowS
showsPrec :: Int -> Direction -> ShowS
$cshow :: Direction -> String
show :: Direction -> String
$cshowList :: [Direction] -> ShowS
showList :: [Direction] -> ShowS
Show
)
deriving anyclass
(
Eq Direction
Eq Direction =>
(Int -> Direction -> Int)
-> (Direction -> Int) -> Hashable Direction
Int -> Direction -> Int
Direction -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> Direction -> Int
hashWithSalt :: Int -> Direction -> Int
$chash :: Direction -> Int
hash :: Direction -> Int
Hashable,
Direction -> ()
(Direction -> ()) -> NFData Direction
forall a. (a -> ()) -> NFData a
$crnf :: Direction -> ()
rnf :: Direction -> ()
NFData
)
instance Parser Direction where
parser :: Parsec Void Text Direction
parser =
[Parsec Void Text Direction] -> Parsec Void Text Direction
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
MP.choice
[ Direction -> Char -> Tokens Text -> Parsec Void Text Direction
forall {s} {f :: * -> *} {e} {b}.
(Token s ~ Char, MonadParsec e s f, FoldCase (Tokens s)) =>
b -> Char -> Tokens s -> f b
parseU Direction
Up Char
'u' Tokens Text
"p",
Direction -> Char -> Tokens Text -> Parsec Void Text Direction
forall {s} {f :: * -> *} {e} {b}.
(Token s ~ Char, MonadParsec e s f, FoldCase (Tokens s)) =>
b -> Char -> Tokens s -> f b
parseU Direction
Down Char
'd' Tokens Text
"own"
]
where
parseU :: b -> Char -> Tokens s -> f b
parseU b
u Char
ushort Tokens s
ulong = do
Char
_ <- Token s -> f (Token s)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
MPC.char' Char
Token s
ushort
Maybe (Tokens s)
_ <- f (Tokens s) -> f (Maybe (Tokens s))
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
MP.optional (Tokens s -> f (Tokens s)
forall e s (m :: * -> *).
(MonadParsec e s m, FoldCase (Tokens s)) =>
Tokens s -> m (Tokens s)
MPC.string' Tokens s
ulong)
pure b
u
{-# INLINEABLE parser #-}
type SDirection :: Direction -> Type
data SDirection (d :: Direction) where
SDown :: SDirection Down
SUp :: SDirection Up
deriving stock instance Show (SDirection d)
instance NFData (SDirection d) where
rnf :: SDirection d -> ()
rnf SDirection d
SDown = ()
rnf SDirection d
SUp = ()
sdirectionToDirection :: SDirection d -> Direction
sdirectionToDirection :: forall (d :: Direction). SDirection d -> Direction
sdirectionToDirection SDirection d
SDown = Direction
Down
sdirectionToDirection SDirection d
SUp = Direction
Up
{-# INLINEABLE sdirectionToDirection #-}
instance TestEquality SDirection where
testEquality :: forall (a :: Direction) (b :: Direction).
SDirection a -> SDirection b -> Maybe (a :~: b)
testEquality SDirection a
x SDirection b
y = case (SDirection a
x, SDirection b
y) of
(SDirection a
SDown, SDirection b
SDown) -> (a :~: b) -> Maybe (a :~: b)
forall a. a -> Maybe a
Just a :~: a
a :~: b
forall {k} (a :: k). a :~: a
Refl
(SDirection a
SUp, SDirection b
SUp) -> (a :~: b) -> Maybe (a :~: b)
forall a. a -> Maybe a
Just a :~: a
a :~: b
forall {k} (a :: k). a :~: a
Refl
(SDirection a, SDirection b)
_ -> Maybe (a :~: b)
forall a. Maybe a
Nothing
{-# INLINEABLE testEquality #-}
type SingDirection :: Direction -> Constraint
class SingDirection (d :: Direction) where
singDirection :: SDirection d
instance SingDirection Down where
singDirection :: SDirection 'Down
singDirection = SDirection 'Down
SDown
{-# INLINE singDirection #-}
instance SingDirection Up where
singDirection :: SDirection 'Up
singDirection = SDirection 'Up
SUp
{-# INLINE singDirection #-}
withSingDirection :: SDirection d -> ((SingDirection d) => r) -> r
withSingDirection :: forall (d :: Direction) r.
SDirection d -> (SingDirection d => r) -> r
withSingDirection SDirection d
s SingDirection d => r
x = case SDirection d
s of
SDirection d
SDown -> r
SingDirection d => r
x
SDirection d
SUp -> r
SingDirection d => r
x
{-# INLINEABLE withSingDirection #-}
class Directed a where
type HideDirection a
directionOf :: a -> Direction
hideDirection :: a -> HideDirection a
_Down :: Prism' Direction ()
_Down :: Prism' Direction ()
_Down = (() -> Direction)
-> (Direction -> Either Direction ()) -> Prism' Direction ()
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism (Direction -> () -> Direction
forall a b. a -> b -> a
const Direction
Down) Direction -> Either Direction ()
f
where
f :: Direction -> Either Direction ()
f Direction
Down = () -> Either Direction ()
forall a b. b -> Either a b
Right ()
f Direction
x = Direction -> Either Direction ()
forall a b. a -> Either a b
Left Direction
x
{-# INLINE _Down #-}
_Up :: Prism' Direction ()
_Up :: Prism' Direction ()
_Up = (() -> Direction)
-> (Direction -> Either Direction ()) -> Prism' Direction ()
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism (Direction -> () -> Direction
forall a b. a -> b -> a
const Direction
Up) Direction -> Either Direction ()
f
where
f :: Direction -> Either Direction ()
f Direction
Up = () -> Either Direction ()
forall a b. b -> Either a b
Right ()
f Direction
x = Direction -> Either Direction ()
forall a b. a -> Either a b
Left Direction
x
{-# INLINE _Up #-}