You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
1.9 KiB
79 lines
1.9 KiB
|
1 year ago
|
{-# LANGUAGE DeriveDataTypeable #-}
|
||
|
|
module Types
|
||
|
|
(
|
||
|
|
mkVlanId
|
||
|
|
, vlanId
|
||
|
|
, VlanId
|
||
|
|
, IpAddress
|
||
|
|
, ip
|
||
|
|
) where
|
||
|
|
|
||
|
|
import Control.Error (hush)
|
||
|
|
import Data.Data (Data)
|
||
|
|
import GHC.Word (Word8)
|
||
|
|
import Language.Haskell.TH.Quote (QuasiQuoter (..))
|
||
|
|
import Language.Haskell.TH.Syntax (dataToExpQ)
|
||
|
|
import Text.Parsec (char, digit, many1, parse)
|
||
|
|
import Text.Read (readMaybe)
|
||
|
|
|
||
|
|
newtype VlanId = VlanId Int
|
||
|
|
deriving (Show, Eq, Data)
|
||
|
|
|
||
|
|
mkVlanId :: Int -> Maybe VlanId
|
||
|
|
mkVlanId i =
|
||
|
|
if i >= minVlanId && i <= maxVlanId
|
||
|
|
then Just $ VlanId i
|
||
|
|
else Nothing
|
||
|
|
where
|
||
|
|
minVlanId = 1
|
||
|
|
maxVlanId = 4094
|
||
|
|
|
||
|
|
vlanId :: QuasiQuoter
|
||
|
|
vlanId = QuasiQuoter
|
||
|
|
{
|
||
|
|
quoteExp = parseVlanId
|
||
|
|
, quotePat = undefined
|
||
|
|
, quoteType = undefined
|
||
|
|
, quoteDec = undefined
|
||
|
|
}
|
||
|
|
where
|
||
|
|
parseVlanId s =
|
||
|
|
case readMaybe s >>= mkVlanId of
|
||
|
|
Just vid -> dataToExpQ (const Nothing) vid
|
||
|
|
Nothing -> fail "Invalid VlanId"
|
||
|
|
|
||
|
|
|
||
|
|
newtype IpAddress = IpAddress (Word8, Word8, Word8, Word8)
|
||
|
|
deriving (Eq, Data)
|
||
|
|
|
||
|
|
instance Show IpAddress where
|
||
|
|
show (IpAddress (a, b, c, d)) = show a <> "." <> show b <> "." <> show c <> "." <> show d
|
||
|
|
|
||
|
|
parseIp :: String -> Maybe IpAddress
|
||
|
|
parseIp = hush . parse ipParser ""
|
||
|
|
where
|
||
|
|
ipParser = do
|
||
|
|
a <- read <$> many1 digit
|
||
|
|
_ <- char '.'
|
||
|
|
b <- read <$> many1 digit
|
||
|
|
_ <- char '.'
|
||
|
|
c <- read <$> many1 digit
|
||
|
|
_ <- char '.'
|
||
|
|
d <- read <$> many1 digit
|
||
|
|
return $ IpAddress (a, b, c, d)
|
||
|
|
|
||
|
|
ip :: QuasiQuoter
|
||
|
|
ip = QuasiQuoter
|
||
|
|
{
|
||
|
|
quoteExp = doParseIp
|
||
|
|
, quotePat = undefined
|
||
|
|
, quoteType = undefined
|
||
|
|
, quoteDec = undefined
|
||
|
|
}
|
||
|
|
where
|
||
|
|
doParseIp s = do
|
||
|
|
case parseIp s of
|
||
|
|
Just m' -> dataToExpQ (const Nothing) m'
|
||
|
|
_ -> fail "Unable to parse MAC address"
|
||
|
|
|