opentracing-0.2.0: OpenTracing/Types.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StrictData #-}
module OpenTracing.Types
( TraceID(..)
, IPv4(..)
, IPv6(..)
, Port(..)
, Protocol(..)
, Addr(..)
, addrHostName
, addrPort
, addrSecure
, Hex
, knownHex
, AsHex(..)
, hexText
)
where
import Control.Lens
import Data.Aeson (ToJSON (..))
import Data.Aeson.Encoding
import Data.ByteString.Builder as B
import qualified Data.IP as IP
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Text.Lazy.Encoding as E
import qualified Data.Text.Read as TR
import Data.Word
import Network.Socket (HostName)
data TraceID = TraceID
{ traceIdHi :: Maybe Word64
, traceIdLo :: Word64
} deriving (Eq, Ord, Show)
newtype IPv4 = IPv4 { fromIPv4 :: IP.IPv4 }
deriving (Bounded, Enum, Eq, Ord)
newtype IPv6 = IPv6 { fromIPv6 :: IP.IPv6 }
deriving (Bounded, Enum, Eq, Ord)
instance Show IPv4 where show = show . fromIPv4
instance Show IPv6 where show = show . fromIPv6
instance Read IPv4 where readsPrec p = map (over _1 IPv4) . readsPrec p
instance Read IPv6 where readsPrec p = map (over _1 IPv6) . readsPrec p
instance ToJSON IPv4 where
toJSON = toJSON . show . fromIPv4
toEncoding = string . show . fromIPv4
instance ToJSON IPv6 where
toJSON = toJSON . show . fromIPv6
toEncoding = string . show . fromIPv6
newtype Port = Port { fromPort :: Word16 }
deriving (Enum, Eq, Num, Ord)
instance Show Port where show = show . fromPort
instance Read Port where readsPrec p = map (over _1 Port) . readsPrec p
instance ToJSON Port where
toJSON = toJSON . fromPort
toEncoding = word16 . fromPort
data Protocol = UDP | HTTP
data Addr a where
UDPAddr :: HostName -> Port -> Addr 'UDP
HTTPAddr :: HostName -> Port -> Bool -> Addr 'HTTP
addrHostName :: Lens' (Addr a) HostName
addrHostName f (UDPAddr h p ) = (\h' -> UDPAddr h' p ) <$> f h
addrHostName f (HTTPAddr h p s) = (\h' -> HTTPAddr h' p s) <$> f h
addrPort :: Lens' (Addr a) Port
addrPort f (UDPAddr h p ) = (\p' -> UDPAddr h p' ) <$> f p
addrPort f (HTTPAddr h p s) = (\p' -> HTTPAddr h p' s) <$> f p
addrSecure :: Lens' (Addr 'HTTP) Bool
addrSecure f (HTTPAddr h p s) = (\s' -> HTTPAddr h p s') <$> f s
newtype Hex = Hex { unHex :: Text }
deriving (Eq, Show, Monoid, Semigroup)
knownHex :: Text -> Hex
knownHex = Hex
class AsHex a where
_Hex :: Prism' Hex a
instance AsHex TraceID where
_Hex = prism' enc dec
where
enc (TraceID hi lo)
= Hex . unHex $ maybe mempty (review _Hex) hi <> review _Hex lo
dec (Hex t)
= case Text.splitAt 16 t of
("", lo) -> TraceID Nothing <$> preview _Hex (Hex lo)
(hi, lo) -> TraceID <$> Just (preview _Hex (Hex hi))
<*> preview _Hex (Hex lo)
{-# INLINE _Hex #-}
instance AsHex Word64 where
_Hex = prism' enc dec
where
enc = Hex . view strict . E.decodeUtf8 . B.toLazyByteString . B.word64HexFixed
dec = either (const Nothing) (pure . fst) . TR.hexadecimal . unHex
{-# INLINE _Hex #-}
hexText :: AsHex a => Getter a Text
hexText = re _Hex . to unHex
{-# INLINE hexText #-}