{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnboxedTuples #-}

{-| This module provides the Mac data type and functions for working
    with it.
-}
module Net.Mac
  ( -- * Convert
    mac
  , fromOctets
  , toOctets
    -- * Textual Conversion
    -- ** Text
  , encode
  , encodeWith
  , decode
  , decodeWith
  , builder
  , parser
  , parserWith
    -- ** ShortText
  , encodeShort
    -- ** UTF-8 ByteString
  , encodeUtf8
  , encodeWithUtf8
  , decodeUtf8
  , decodeWithUtf8
  , builderUtf8
  , parserUtf8
  , parserWithUtf8
    -- ** ByteString
  , decodeBytes
  , decodeOctets
    -- ** UTF-8 Bytes
  , boundedBuilderUtf8
  , decodeUtf8Bytes
  , parserUtf8Bytes
    -- ** Printing
  , print
    -- * Types
  , Mac(..)
  , MacCodec(..)
  , MacGrouping(..)
  ) where

import Prelude hiding (print)

import Control.DeepSeq (NFData)
import Data.Aeson (FromJSON(..),ToJSON(..))
import Data.Aeson (ToJSONKey(..),FromJSONKey(..))
import Data.Aeson (ToJSONKeyFunction(..),FromJSONKeyFunction(..))
import Data.Bits ((.|.),unsafeShiftL,unsafeShiftR,(.&.))
import Data.ByteString (ByteString)
import Data.ByteString.Short.Internal (ShortByteString(SBS))
import Data.Char (ord,chr)
import Data.Data (Data)
import Data.Hashable (Hashable)
import Data.Ix (Ix)
import Data.Primitive.ByteArray (ByteArray(ByteArray))
import Data.Primitive.Types (Prim(..))
#if !MIN_VERSION_base(4,11,0)
import Data.Semigroup ((<>))
#endif
import Data.Text (Text)
import Data.Text.Short (ShortText)
import Data.Word
import Data.Word.Synthetic.Word12 (Word12)
import GHC.Enum (predError, succError)
import GHC.Exts
import GHC.Generics (Generic)
import GHC.Word (Word16(W16#))
import Text.ParserCombinators.ReadPrec (prec,step)
import Text.Read (Read(..),Lexeme(Ident),lexP,parens)

import qualified Arithmetic.Nat as Nat
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Types as Aeson
import qualified Data.Attoparsec.ByteString as AB
import qualified Data.Attoparsec.ByteString as ABW
import qualified Data.Attoparsec.Text as AT
import qualified Data.Bytes.Builder.Bounded as BBB
import qualified Data.Bytes as Bytes
import qualified Data.Bytes.Parser as Parser
import qualified Data.Bytes.Parser.Latin as Latin
import qualified Data.ByteString as B
import qualified Data.ByteString.Builder as BB
import qualified Data.ByteString.Builder.Fixed as BFB
import qualified Data.ByteString.Unsafe as BU
import qualified Data.Text.Builder.Fixed as TFB
import qualified Data.Text.IO as TIO
import qualified Data.Text.Lazy.Builder as TBuilder
import qualified Data.Text.Short.Unsafe as TS
import qualified Data.Text as Text ()

#if MIN_VERSION_aeson(2,0,0)
import qualified Data.Aeson.Key as AK
#endif

-- $setup
--
-- These are here to get doctest's property checking to work
--
-- >>> :set -XOverloadedStrings
-- >>> import Test.QuickCheck (Arbitrary(..))
-- >>> import qualified Data.Text as Text (pack)
-- >>> import qualified Data.Text.IO as T
-- >>> import qualified Data.ByteString.Char8 as BC
-- >>> instance Arbitrary Mac where { arbitrary = fmap (Mac . (0xFFFFFFFFFFFF .&.)) arbitrary }

-- | Construct a 'Mac' address from a 'Word64'. Only the lower
--   48 bits are used.
mac :: Word64 -> Mac
mac :: Word64 -> Mac
mac Word64
w = Word64 -> Mac
Mac (Word64
w Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0xFFFFFFFFFFFF)

-- | Create a 'Mac' address from six octets.
fromOctets :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac
fromOctets :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac
fromOctets Word8
a Word8
b Word8
c Word8
d Word8
e Word8
f = Word64 -> Mac
Mac (Word64 -> Mac) -> Word64 -> Mac
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64 -> Word64 -> Word64 -> Word64 -> Word64 -> Word64
unsafeWord48FromOctets
  (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
a) (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b) (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
c)
  (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
d) (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
e) (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
f)

-- | Convert a 'Mac' address to the six octets that make it up.
--   This function and 'fromOctets' are inverses:
--
--   prop> m == (let (a,b,c,d,e,f) = toOctets m in fromOctets a b c d e f)
toOctets :: Mac -> (Word8,Word8,Word8,Word8,Word8,Word8)
toOctets :: Mac -> (Word8, Word8, Word8, Word8, Word8, Word8)
toOctets (Mac Word64
w) =
  ( Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Word8) -> Word64 -> Word8
forall a b. (a -> b) -> a -> b
$ Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
40
  , Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Word8) -> Word64 -> Word8
forall a b. (a -> b) -> a -> b
$ Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
32
  , Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Word8) -> Word64 -> Word8
forall a b. (a -> b) -> a -> b
$ Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
24
  , Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Word8) -> Word64 -> Word8
forall a b. (a -> b) -> a -> b
$ Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
16
  , Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Word8) -> Word64 -> Word8
forall a b. (a -> b) -> a -> b
$ Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
8
  , Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
w
  )

-- | This function is deprecated. It will be renamed in a future release
--   since the name is misleading.
decodeBytes :: ByteString -> Maybe Mac
{-# DEPRECATED decodeBytes "Prefer decodeOctets" #-}
decodeBytes :: ByteString -> Maybe Mac
decodeBytes = ByteString -> Maybe Mac
decodeOctets

-- | Decode a 'Mac' address from a 'ByteString'. Each byte is interpreted
--   as an octet of the 'Mac' address. Consequently, 'ByteString's
--   of length 6 successfully decode, and all other 'ByteString's fail
--   to decode.
--
--   >>> decodeOctets (B.pack [0x6B,0x47,0x18,0x90,0x55,0xC3])
--   Just (mac 0x6b47189055c3)
--   >>> decodeOctets (B.replicate 6 0x3A)
--   Just (mac 0x3a3a3a3a3a3a)
--   >>> decodeOctets (B.replicate 7 0x3A)
--   Nothing
decodeOctets :: ByteString -> Maybe Mac
decodeOctets :: ByteString -> Maybe Mac
decodeOctets ByteString
bs = if ByteString -> Int
B.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
6
  then Mac -> Maybe Mac
forall a. a -> Maybe a
Just (Mac -> Maybe Mac) -> Mac -> Maybe Mac
forall a b. (a -> b) -> a -> b
$ Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac
fromOctets
    (ByteString -> Int -> Word8
BU.unsafeIndex ByteString
bs Int
0)
    (ByteString -> Int -> Word8
BU.unsafeIndex ByteString
bs Int
1)
    (ByteString -> Int -> Word8
BU.unsafeIndex ByteString
bs Int
2)
    (ByteString -> Int -> Word8
BU.unsafeIndex ByteString
bs Int
3)
    (ByteString -> Int -> Word8
BU.unsafeIndex ByteString
bs Int
4)
    (ByteString -> Int -> Word8
BU.unsafeIndex ByteString
bs Int
5)
  else Maybe Mac
forall a. Maybe a
Nothing

rightToMaybe :: Either a b -> Maybe b
rightToMaybe :: Either a b -> Maybe b
rightToMaybe = (a -> Maybe b) -> (b -> Maybe b) -> Either a b -> Maybe b
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe b -> a -> Maybe b
forall a b. a -> b -> a
const Maybe b
forall a. Maybe a
Nothing) b -> Maybe b
forall a. a -> Maybe a
Just

c2w :: Char -> Word8
c2w :: Char -> Word8
c2w = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> (Char -> Int) -> Char -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
ord

-- | Encode a 'Mac' address using the default 'MacCodec' 'defCodec'.
--
--   >>> T.putStrLn (encode (Mac 0xA47F247AB423))
--   a4:7f:24:7a:b4:23
encode :: Mac -> Text
encode :: Mac -> Text
encode = MacCodec -> Mac -> Text
encodeWith MacCodec
defCodec

-- | Encode a 'Mac' address using the given 'MacCodec'.
--
--   >>> m = Mac 0xA47F247AB423
--   >>> T.putStrLn $ encodeWith defCodec m
--   a4:7f:24:7a:b4:23
--
--   >>> T.putStrLn $ encodeWith (MacCodec (MacGroupingTriples '-') True) m
--   A47-F24-7AB-423
encodeWith :: MacCodec -> Mac -> Text
encodeWith :: MacCodec -> Mac -> Text
encodeWith (MacCodec MacGrouping
g Bool
u) Mac
m = case MacGrouping
g of
  MacGrouping
MacGroupingNoSeparator -> case Bool
u of
    Bool
True -> Builder Mac -> Mac -> Text
forall a. Builder a -> a -> Text
TFB.run (Builder Word8 -> Builder Mac
fixedBuilderNoSeparator Builder Word8
TFB.word8HexFixedUpper) Mac
m
    Bool
False -> Builder Mac -> Mac -> Text
forall a. Builder a -> a -> Text
TFB.run (Builder Word8 -> Builder Mac
fixedBuilderNoSeparator Builder Word8
TFB.word8HexFixedLower) Mac
m
  MacGroupingPairs Char
c -> case Bool
u of
    Bool
True -> Builder Pair -> Pair -> Text
forall a. Builder a -> a -> Text
TFB.run (Builder Word8 -> Builder Pair
fixedBuilderPairs Builder Word8
TFB.word8HexFixedUpper) (Char -> Mac -> Pair
Pair Char
c Mac
m)
    Bool
False -> Builder Pair -> Pair -> Text
forall a. Builder a -> a -> Text
TFB.run (Builder Word8 -> Builder Pair
fixedBuilderPairs Builder Word8
TFB.word8HexFixedLower) (Char -> Mac -> Pair
Pair Char
c Mac
m)
    -- withCasedBuilder u $ \bw8 -> TFB.run (fixedBuilderPairs bw8) (Pair c m)
  MacGroupingTriples Char
c -> case Bool
u of
    Bool
True -> Builder Pair -> Pair -> Text
forall a. Builder a -> a -> Text
TFB.run (Builder Word12 -> Builder Pair
fixedBuilderTriples Builder Word12
TFB.word12HexFixedUpper) (Char -> Mac -> Pair
Pair Char
c Mac
m)
    Bool
False -> Builder Pair -> Pair -> Text
forall a. Builder a -> a -> Text
TFB.run (Builder Word12 -> Builder Pair
fixedBuilderTriples Builder Word12
TFB.word12HexFixedLower) (Char -> Mac -> Pair
Pair Char
c Mac
m)
  MacGroupingQuadruples Char
c -> case Bool
u of
    Bool
True -> Builder Pair -> Pair -> Text
forall a. Builder a -> a -> Text
TFB.run (Builder Word8 -> Builder Pair
fixedBuilderQuadruples Builder Word8
TFB.word8HexFixedUpper) (Char -> Mac -> Pair
Pair Char
c Mac
m)
    Bool
False -> Builder Pair -> Pair -> Text
forall a. Builder a -> a -> Text
TFB.run (Builder Word8 -> Builder Pair
fixedBuilderQuadruples Builder Word8
TFB.word8HexFixedLower) (Char -> Mac -> Pair
Pair Char
c Mac
m)

-- | Decode a 'Mac' address using the default 'MacCodec' 'defCodec'.
--
--   >>> decode (Text.pack "a4:7f:24:7a:b4:23")
--   Just (mac 0xa47f247ab423)
--
--   >>> decode (Text.pack "a47-f24-7ab-423")
--   Nothing
decode :: Text -> Maybe Mac
decode :: Text -> Maybe Mac
decode = MacCodec -> Text -> Maybe Mac
decodeWith MacCodec
defCodec

-- | Decode a 'Mac' address from 'Text' using the given 'MacCodec'.
--
-- >>> decodeWith defCodec (Text.pack "a4:7f:24:7a:b4:23")
-- Just (mac 0xa47f247ab423)
--
-- >>> decodeWith (MacCodec MacGroupingNoSeparator False) (Text.pack "a47f247ab423")
-- Just (mac 0xa47f247ab423)
decodeWith :: MacCodec -> Text -> Maybe Mac
decodeWith :: MacCodec -> Text -> Maybe Mac
decodeWith MacCodec
codec Text
t = Either String Mac -> Maybe Mac
forall a b. Either a b -> Maybe b
rightToMaybe (Parser Mac -> Text -> Either String Mac
forall a. Parser a -> Text -> Either String a
AT.parseOnly (MacCodec -> Parser Mac
parserWith MacCodec
codec Parser Mac -> Parser Text () -> Parser Mac
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Text ()
forall t. Chunk t => Parser t ()
AT.endOfInput) Text
t)

-- | Encode a 'Mac' address as a 'TBuilder.Builder'.
builder :: Mac -> TBuilder.Builder
builder :: Mac -> Builder
builder = Text -> Builder
TBuilder.fromText (Text -> Builder) -> (Mac -> Text) -> Mac -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mac -> Text
encode

-- | Parse a 'Mac' address using a 'AT.Parser'.
--
--   >>> AT.parseOnly parser (Text.pack "a4:7f:24:7a:b4:23")
--   Right (mac 0xa47f247ab423)
--
--   >>> AT.parseOnly parser (Text.pack "a47-f24-7ab-423")
--   Left "':': Failed reading: satisfy"
parser :: AT.Parser Mac
parser :: Parser Mac
parser = MacCodec -> Parser Mac
parserWith MacCodec
defCodec

-- | Parser a 'Mac' address using the given 'MacCodec'.
--
--   >>> p1 = parserWith defCodec
--   >>> AT.parseOnly p1 (Text.pack "a4:7f:24:7a:b4:23")
--   Right (mac 0xa47f247ab423)
--
--   >>> p2 = parserWith (MacCodec MacGroupingNoSeparator False)
--   >>> AT.parseOnly p2 (Text.pack "a47f247ab423")
--   Right (mac 0xa47f247ab423)
parserWith :: MacCodec -> AT.Parser Mac
parserWith :: MacCodec -> Parser Mac
parserWith (MacCodec MacGrouping
g Bool
_) = case MacGrouping
g of
  MacGroupingQuadruples Char
c -> Char -> Parser Mac
parserQuadruples Char
c
  MacGroupingTriples Char
c -> Char -> Parser Mac
parserTriples Char
c
  MacGroupingPairs Char
c -> Char -> Parser Mac
parserPairs Char
c
  MacGrouping
MacGroupingNoSeparator -> Parser Mac
parserNoSeparator

-- | The default 'MacCodec': all characters are lowercase hex, separated by colons into pairs.
--
--   >>> T.putStrLn $ encodeWith defCodec (Mac 0xa47f247ab423)
--   a4:7f:24:7a:b4:23
defCodec :: MacCodec
defCodec :: MacCodec
defCodec = MacGrouping -> Bool -> MacCodec
MacCodec (Char -> MacGrouping
MacGroupingPairs Char
':') Bool
False

parserQuadruples :: Char -> AT.Parser Mac
parserQuadruples :: Char -> Parser Mac
parserQuadruples Char
s = Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac
fromOctets
  (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Word8
-> Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text Word8
parseTwoHex Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Word8
-> Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Word8
parseTwoHex Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Char
-> Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser Text Char
AT.char Char
s
  Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Word8
-> Parser Text (Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Word8
parseTwoHex Parser Text (Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Word8 -> Parser Text (Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Word8
parseTwoHex Parser Text (Word8 -> Word8 -> Mac)
-> Parser Text Char -> Parser Text (Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser Text Char
AT.char Char
s
  Parser Text (Word8 -> Word8 -> Mac)
-> Parser Text Word8 -> Parser Text (Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Word8
parseTwoHex Parser Text (Word8 -> Mac) -> Parser Text Word8 -> Parser Mac
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Word8
parseTwoHex

parserPairs :: Char -> AT.Parser Mac
parserPairs :: Char -> Parser Mac
parserPairs Char
s = Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac
fromOctets
  (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Word8
-> Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text Word8
parseTwoHex Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Char
-> Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser Text Char
AT.char Char
s
  Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Word8
-> Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Word8
parseTwoHex Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Char
-> Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser Text Char
AT.char Char
s
  Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Word8
-> Parser Text (Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Word8
parseTwoHex Parser Text (Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Char -> Parser Text (Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser Text Char
AT.char Char
s
  Parser Text (Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Word8 -> Parser Text (Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Word8
parseTwoHex Parser Text (Word8 -> Word8 -> Mac)
-> Parser Text Char -> Parser Text (Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser Text Char
AT.char Char
s
  Parser Text (Word8 -> Word8 -> Mac)
-> Parser Text Word8 -> Parser Text (Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Word8
parseTwoHex Parser Text (Word8 -> Mac)
-> Parser Text Char -> Parser Text (Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser Text Char
AT.char Char
s
  Parser Text (Word8 -> Mac) -> Parser Text Word8 -> Parser Mac
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Word8
parseTwoHex

parserTriples :: Char -> AT.Parser Mac
parserTriples :: Char -> Parser Mac
parserTriples Char
s = do
  Word8
a1 <- Parser Text Word8
parseOneHex
  Word8
a2 <- Parser Text Word8
parseOneHex
  Word8
a3 <- Parser Text Word8
parseOneHex
  Char
_ <- Char -> Parser Text Char
AT.char Char
s
  Word8
a4 <- Parser Text Word8
parseOneHex
  Word8
a5 <- Parser Text Word8
parseOneHex
  Word8
a6 <- Parser Text Word8
parseOneHex
  Char
_ <- Char -> Parser Text Char
AT.char Char
s
  Word8
a7 <- Parser Text Word8
parseOneHex
  Word8
a8 <- Parser Text Word8
parseOneHex
  Word8
a9 <- Parser Text Word8
parseOneHex
  Char
_ <- Char -> Parser Text Char
AT.char Char
s
  Word8
a10 <- Parser Text Word8
parseOneHex
  Word8
a11 <- Parser Text Word8
parseOneHex
  Word8
a12 <- Parser Text Word8
parseOneHex
  Mac -> Parser Mac
forall (m :: * -> *) a. Monad m => a -> m a
return (Mac -> Parser Mac) -> Mac -> Parser Mac
forall a b. (a -> b) -> a -> b
$ Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac
fromOctets
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a1 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a2)
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a3 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a4)
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a5 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a6)
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a7 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a8)
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a9 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a10)
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a11 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a12)

parserNoSeparator :: AT.Parser Mac
parserNoSeparator :: Parser Mac
parserNoSeparator = Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac
fromOctets
  (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Word8
-> Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text Word8
parseTwoHex
  Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Word8
-> Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Word8
parseTwoHex
  Parser Text (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Word8
-> Parser Text (Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Word8
parseTwoHex
  Parser Text (Word8 -> Word8 -> Word8 -> Mac)
-> Parser Text Word8 -> Parser Text (Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Word8
parseTwoHex
  Parser Text (Word8 -> Word8 -> Mac)
-> Parser Text Word8 -> Parser Text (Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Word8
parseTwoHex
  Parser Text (Word8 -> Mac) -> Parser Text Word8 -> Parser Mac
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Word8
parseTwoHex

parseTwoHex :: AT.Parser Word8
parseTwoHex :: Parser Text Word8
parseTwoHex = do
  Word8
a <- Parser Text Char
AT.anyChar Parser Text Char
-> (Char -> Parser Text Word8) -> Parser Text Word8
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Char -> Parser Text Word8
parseCharHex
  Word8
b <- Parser Text Char
AT.anyChar Parser Text Char
-> (Char -> Parser Text Word8) -> Parser Text Word8
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Char -> Parser Text Word8
parseCharHex
  Word8 -> Parser Text Word8
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
b)

tryParseCharHex :: AT.Parser Word8 -> Char -> AT.Parser Word8
tryParseCharHex :: Parser Text Word8 -> Char -> Parser Text Word8
tryParseCharHex Parser Text Word8
a Char
c
  | Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
48 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
57 = Word8 -> Parser Text Word8
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
48)
  | Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
65 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
70 = Word8 -> Parser Text Word8
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
55)
  | Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
97 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
102 = Word8 -> Parser Text Word8
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
87)
  | Bool
otherwise = Parser Text Word8
a
  where w :: Word8
w = Char -> Word8
c2w Char
c

parseOneHex :: AT.Parser Word8
parseOneHex :: Parser Text Word8
parseOneHex = Parser Text Char
AT.anyChar Parser Text Char
-> (Char -> Parser Text Word8) -> Parser Text Word8
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Char -> Parser Text Word8
parseCharHex

parseCharHex :: Char -> AT.Parser Word8
parseCharHex :: Char -> Parser Text Word8
parseCharHex = Parser Text Word8 -> Char -> Parser Text Word8
tryParseCharHex (String -> Parser Text Word8
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"invalid hexadecimal character")

data Pair = Pair
  { Pair -> Char
pairSep :: {-# UNPACK #-} !Char
  , Pair -> Mac
pairMac :: {-# UNPACK #-} !Mac
  }

fixedBuilderTriples :: TFB.Builder Word12 -> TFB.Builder Pair
fixedBuilderTriples :: Builder Word12 -> Builder Pair
fixedBuilderTriples Builder Word12
tripBuilder =
     (Pair -> Word12) -> Builder Word12 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word12
word12At Int
36 (Mac -> Word12) -> (Pair -> Mac) -> Pair -> Word12
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word12
tripBuilder
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Char) -> Builder Char -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder Pair -> Char
pairSep Builder Char
TFB.charBmp
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Word12) -> Builder Word12 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word12
word12At Int
24 (Mac -> Word12) -> (Pair -> Mac) -> Pair -> Word12
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word12
tripBuilder
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Char) -> Builder Char -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder Pair -> Char
pairSep Builder Char
TFB.charBmp
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Word12) -> Builder Word12 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word12
word12At Int
12 (Mac -> Word12) -> (Pair -> Mac) -> Pair -> Word12
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word12
tripBuilder
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Char) -> Builder Char -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder Pair -> Char
pairSep Builder Char
TFB.charBmp
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Word12) -> Builder Word12 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word12
word12At Int
0 (Mac -> Word12) -> (Pair -> Mac) -> Pair -> Word12
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word12
tripBuilder
{-# INLINE fixedBuilderTriples #-}

fixedBuilderNoSeparator :: TFB.Builder Word8 -> TFB.Builder Mac
fixedBuilderNoSeparator :: Builder Word8 -> Builder Mac
fixedBuilderNoSeparator Builder Word8
hexBuilder =
     (Mac -> Word8) -> Builder Word8 -> Builder Mac
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
40) Builder Word8
hexBuilder
  Builder Mac -> Builder Mac -> Builder Mac
forall a. Semigroup a => a -> a -> a
<> (Mac -> Word8) -> Builder Word8 -> Builder Mac
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
32) Builder Word8
hexBuilder
  Builder Mac -> Builder Mac -> Builder Mac
forall a. Semigroup a => a -> a -> a
<> (Mac -> Word8) -> Builder Word8 -> Builder Mac
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
24) Builder Word8
hexBuilder
  Builder Mac -> Builder Mac -> Builder Mac
forall a. Semigroup a => a -> a -> a
<> (Mac -> Word8) -> Builder Word8 -> Builder Mac
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
16) Builder Word8
hexBuilder
  Builder Mac -> Builder Mac -> Builder Mac
forall a. Semigroup a => a -> a -> a
<> (Mac -> Word8) -> Builder Word8 -> Builder Mac
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
8) Builder Word8
hexBuilder
  Builder Mac -> Builder Mac -> Builder Mac
forall a. Semigroup a => a -> a -> a
<> (Mac -> Word8) -> Builder Word8 -> Builder Mac
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
0) Builder Word8
hexBuilder
{-# INLINE fixedBuilderNoSeparator #-}

fixedBuilderQuadruples :: TFB.Builder Word8 -> TFB.Builder Pair
fixedBuilderQuadruples :: Builder Word8 -> Builder Pair
fixedBuilderQuadruples Builder Word8
pairBuilder =
     (Pair -> Word8) -> Builder Word8 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
40 (Mac -> Word8) -> (Pair -> Mac) -> Pair -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word8
pairBuilder
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Word8) -> Builder Word8 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
32 (Mac -> Word8) -> (Pair -> Mac) -> Pair -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word8
pairBuilder
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Char) -> Builder Char -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder Pair -> Char
pairSep Builder Char
TFB.charBmp
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Word8) -> Builder Word8 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
24 (Mac -> Word8) -> (Pair -> Mac) -> Pair -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word8
pairBuilder
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Word8) -> Builder Word8 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
16 (Mac -> Word8) -> (Pair -> Mac) -> Pair -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word8
pairBuilder
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Char) -> Builder Char -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder Pair -> Char
pairSep Builder Char
TFB.charBmp
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Word8) -> Builder Word8 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
8 (Mac -> Word8) -> (Pair -> Mac) -> Pair -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word8
pairBuilder
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Word8) -> Builder Word8 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
0 (Mac -> Word8) -> (Pair -> Mac) -> Pair -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word8
pairBuilder
{-# INLINE fixedBuilderQuadruples #-}

fixedBuilderPairs :: TFB.Builder Word8 -> TFB.Builder Pair
fixedBuilderPairs :: Builder Word8 -> Builder Pair
fixedBuilderPairs Builder Word8
pairBuilder =
     (Pair -> Word8) -> Builder Word8 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
40 (Mac -> Word8) -> (Pair -> Mac) -> Pair -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word8
pairBuilder
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Char) -> Builder Char -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder Pair -> Char
pairSep Builder Char
TFB.charBmp
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Word8) -> Builder Word8 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
32 (Mac -> Word8) -> (Pair -> Mac) -> Pair -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word8
pairBuilder
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Char) -> Builder Char -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder Pair -> Char
pairSep Builder Char
TFB.charBmp
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Word8) -> Builder Word8 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
24 (Mac -> Word8) -> (Pair -> Mac) -> Pair -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word8
pairBuilder
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Char) -> Builder Char -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder Pair -> Char
pairSep Builder Char
TFB.charBmp
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Word8) -> Builder Word8 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
16 (Mac -> Word8) -> (Pair -> Mac) -> Pair -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word8
pairBuilder
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Char) -> Builder Char -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder Pair -> Char
pairSep Builder Char
TFB.charBmp
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Word8) -> Builder Word8 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
8 (Mac -> Word8) -> (Pair -> Mac) -> Pair -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word8
pairBuilder
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Char) -> Builder Char -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder Pair -> Char
pairSep Builder Char
TFB.charBmp
  Builder Pair -> Builder Pair -> Builder Pair
forall a. Semigroup a => a -> a -> a
<> (Pair -> Word8) -> Builder Word8 -> Builder Pair
forall b a. (b -> a) -> Builder a -> Builder b
TFB.contramapBuilder (Int -> Mac -> Word8
word8At Int
0 (Mac -> Word8) -> (Pair -> Mac) -> Pair -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Mac
pairMac) Builder Word8
pairBuilder
{-# INLINE fixedBuilderPairs #-}

word8At :: Int -> Mac -> Word8
word8At :: Int -> Mac -> Word8
word8At Int
i (Mac Word64
w) = Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
i)
{-# INLINE word8At #-}

word12At :: Int -> Mac -> Word12
word12At :: Int -> Mac -> Word12
word12At Int
i (Mac Word64
w) = Word64 -> Word12
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
i)
{-# INLINE word12At #-}

-- | Encode a 'Mac' address using the default 'MacCodec' 'defCodec'.
--
--   >>> BC.putStrLn (encodeUtf8 (mac 0x64255A0F2C47))
--   64:25:5a:0f:2c:47
encodeUtf8 :: Mac -> ByteString
encodeUtf8 :: Mac -> ByteString
encodeUtf8 = MacCodec -> Mac -> ByteString
encodeWithUtf8 MacCodec
defCodec

-- | Lenient decoding of MAC address that accepts lowercase, uppercase,
--   and any kind of separator.
--
--   >>> decodeUtf8 "A2:DE:AD:BE:EF:67"
--   Just (mac 0xa2deadbeef67)
--   >>> decodeUtf8 "13-a2-fe-a4-17-96"
--   Just (mac 0x13a2fea41796)
--   >>> decodeUtf8 "0A42.47BA.67C2"
--   Just (mac 0x0a4247ba67c2)
decodeUtf8 :: ByteString -> Maybe Mac
decodeUtf8 :: ByteString -> Maybe Mac
decodeUtf8 = ByteString -> Maybe Mac
decodeLenientUtf8

-- | Decode a 'ByteString' as a 'Mac' address using the given 'MacCodec'.
--
--   >>> decodeWithUtf8 defCodec (BC.pack "64:25:5a:0f:2c:47")
--   Just (mac 0x64255a0f2c47)
--
--   >>> decodeWithUtf8 (MacCodec MacGroupingNoSeparator False) (BC.pack "64255a0f2c47")
--   Just (mac 0x64255a0f2c47)
decodeWithUtf8 :: MacCodec -> ByteString -> Maybe Mac
decodeWithUtf8 :: MacCodec -> ByteString -> Maybe Mac
decodeWithUtf8 MacCodec
codec ByteString
bs = Either String Mac -> Maybe Mac
forall a b. Either a b -> Maybe b
rightToMaybe (Parser Mac -> ByteString -> Either String Mac
forall a. Parser a -> ByteString -> Either String a
AB.parseOnly (MacCodec -> Parser Mac
parserWithUtf8 MacCodec
codec Parser Mac -> Parser ByteString () -> Parser Mac
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString ()
forall t. Chunk t => Parser t ()
AB.endOfInput) ByteString
bs)

decodeLenientUtf8 :: ByteString -> Maybe Mac
decodeLenientUtf8 :: ByteString -> Maybe Mac
decodeLenientUtf8 ByteString
bs = Either String Mac -> Maybe Mac
forall a b. Either a b -> Maybe b
rightToMaybe (Parser Mac -> ByteString -> Either String Mac
forall a. Parser a -> ByteString -> Either String a
AB.parseOnly (Parser Mac
parserLenientUtf8 Parser Mac -> Parser ByteString () -> Parser Mac
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString ()
forall t. Chunk t => Parser t ()
AB.endOfInput) ByteString
bs)

-- | Encode a 'Mac' address as colon-separated hexadecimal octets,
--   preferring lowercase for alphabetical characters.
encodeShort :: Mac -> ShortText
encodeShort :: Mac -> ShortText
encodeShort !Mac
m = case Nat 17 -> Builder 17 -> ByteArray
forall (n :: Nat). Nat n -> Builder n -> ByteArray
BBB.run Nat 17
forall (n :: Nat). KnownNat n => Nat n
Nat.constant (Mac -> Builder 17
boundedBuilderUtf8 Mac
m) of
  ByteArray ByteArray#
x -> ShortByteString -> ShortText
TS.fromShortByteStringUnsafe (ByteArray# -> ShortByteString
SBS ByteArray#
x)

-- | Encode a 'Mac' address as colon-separated hexadecimal octets,
--   preferring lowercase for alphabetical characters.
--
--   >>> BBB.run Nat.constant $ boundedBuilderUtf8 $ mac 0xDEADBEEF1609
--   [0x64, 0x65, 0x3a, 0x61, 0x64, 0x3a, 0x62, 0x65, 0x3a, 0x65, 0x66, 0x3a, 0x31, 0x36, 0x3a, 0x30, 0x39]
boundedBuilderUtf8 :: Mac -> BBB.Builder 17
boundedBuilderUtf8 :: Mac -> Builder 17
boundedBuilderUtf8 !Mac
w =
  Word8 -> Builder 2
BBB.word8PaddedLowerHex Word8
w0
  Builder 2 -> Builder 15 -> Builder (2 + 15)
forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`BBB.append`
  Char -> Builder 1
BBB.ascii Char
':'
  Builder 1 -> Builder 14 -> Builder (1 + 14)
forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`BBB.append`
  Word8 -> Builder 2
BBB.word8PaddedLowerHex Word8
w1
  Builder 2 -> Builder 12 -> Builder (2 + 12)
forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`BBB.append`
  Char -> Builder 1
BBB.ascii Char
':'
  Builder 1 -> Builder 11 -> Builder (1 + 11)
forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`BBB.append`
  Word8 -> Builder 2
BBB.word8PaddedLowerHex Word8
w2
  Builder 2 -> Builder 9 -> Builder (2 + 9)
forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`BBB.append`
  Char -> Builder 1
BBB.ascii Char
':'
  Builder 1 -> Builder 8 -> Builder (1 + 8)
forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`BBB.append`
  Word8 -> Builder 2
BBB.word8PaddedLowerHex Word8
w3
  Builder 2 -> Builder 6 -> Builder (2 + 6)
forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`BBB.append`
  Char -> Builder 1
BBB.ascii Char
':'
  Builder 1 -> Builder 5 -> Builder (1 + 5)
forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`BBB.append`
  Word8 -> Builder 2
BBB.word8PaddedLowerHex Word8
w4
  Builder 2 -> Builder 3 -> Builder (2 + 3)
forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`BBB.append`
  Char -> Builder 1
BBB.ascii Char
':'
  Builder 1 -> Builder 2 -> Builder (1 + 2)
forall (m :: Nat) (n :: Nat).
Builder m -> Builder n -> Builder (m + n)
`BBB.append`
  Word8 -> Builder 2
BBB.word8PaddedLowerHex Word8
w5
  where
  (Word8
w0,Word8
w1,Word8
w2,Word8
w3,Word8
w4,Word8
w5) = Mac -> (Word8, Word8, Word8, Word8, Word8, Word8)
toOctets Mac
w

-- | Lenient decoding of MAC address. This
--   is case insensitive and allows either @:@ or @-@ as the separator.
--   It also allows leading zeroes to be missing.
--
--   >>> decodeUtf8Bytes (Bytes.fromAsciiString "A2:DE:AD:BE:EF:67")
--   Just (mac 0xa2deadbeef67)
--   >>> decodeUtf8Bytes (Bytes.fromAsciiString "13-a2-FE-A4-17-96")
--   Just (mac 0x13a2fea41796)
decodeUtf8Bytes :: Bytes.Bytes -> Maybe Mac
decodeUtf8Bytes :: Bytes -> Maybe Mac
decodeUtf8Bytes = (forall s. Parser () s Mac) -> Bytes -> Maybe Mac
forall e a. (forall s. Parser e s a) -> Bytes -> Maybe a
Parser.parseBytesMaybe (() -> Parser () s Mac
forall e s. e -> Parser e s Mac
parserUtf8Bytes ())

-- | Leniently parse UTF-8-encoded 'Bytes' as a 'Mac' address. This
--   is case insensitive and allows either @:@ or @-@ as the separator.
--   It also allows leading zeroes to be missing.
--
--   >>> Parser.parseBytes (parserUtf8Bytes ()) (Bytes.fromAsciiString "de:ad:BE:EF:1:23")
--   Success (Slice {offset = 16, length = 0, value = mac 0xdeadbeef0123})
parserUtf8Bytes :: e -> Parser.Parser e s Mac
parserUtf8Bytes :: e -> Parser e s Mac
parserUtf8Bytes e
e = do
  Word8
w1 <- e -> Parser e s Word8
forall e s. e -> Parser e s Word8
Latin.hexWord8 e
e
  e -> Parser e s Char
forall e s. e -> Parser e s Char
Latin.any e
e Parser e s Char -> (Char -> Parser e s Mac) -> Parser e s Mac
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Char
':' -> do
      Word8
w2 <- e -> Parser e s Word8
forall e s. e -> Parser e s Word8
Latin.hexWord8 e
e Parser e s Word8 -> Parser e s () -> Parser e s Word8
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* e -> Char -> Parser e s ()
forall e s. e -> Char -> Parser e s ()
Latin.char e
e Char
':'
      Word8
w3 <- e -> Parser e s Word8
forall e s. e -> Parser e s Word8
Latin.hexWord8 e
e Parser e s Word8 -> Parser e s () -> Parser e s Word8
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* e -> Char -> Parser e s ()
forall e s. e -> Char -> Parser e s ()
Latin.char e
e Char
':'
      Word8
w4 <- e -> Parser e s Word8
forall e s. e -> Parser e s Word8
Latin.hexWord8 e
e Parser e s Word8 -> Parser e s () -> Parser e s Word8
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* e -> Char -> Parser e s ()
forall e s. e -> Char -> Parser e s ()
Latin.char e
e Char
':'
      Word8
w5 <- e -> Parser e s Word8
forall e s. e -> Parser e s Word8
Latin.hexWord8 e
e Parser e s Word8 -> Parser e s () -> Parser e s Word8
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* e -> Char -> Parser e s ()
forall e s. e -> Char -> Parser e s ()
Latin.char e
e Char
':'
      Word8
w6 <- e -> Parser e s Word8
forall e s. e -> Parser e s Word8
Latin.hexWord8 e
e
      Mac -> Parser e s Mac
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac
fromOctets Word8
w1 Word8
w2 Word8
w3 Word8
w4 Word8
w5 Word8
w6)
    Char
'-' -> do
      Word8
w2 <- e -> Parser e s Word8
forall e s. e -> Parser e s Word8
Latin.hexWord8 e
e Parser e s Word8 -> Parser e s () -> Parser e s Word8
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* e -> Char -> Parser e s ()
forall e s. e -> Char -> Parser e s ()
Latin.char e
e Char
'-'
      Word8
w3 <- e -> Parser e s Word8
forall e s. e -> Parser e s Word8
Latin.hexWord8 e
e Parser e s Word8 -> Parser e s () -> Parser e s Word8
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* e -> Char -> Parser e s ()
forall e s. e -> Char -> Parser e s ()
Latin.char e
e Char
'-'
      Word8
w4 <- e -> Parser e s Word8
forall e s. e -> Parser e s Word8
Latin.hexWord8 e
e Parser e s Word8 -> Parser e s () -> Parser e s Word8
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* e -> Char -> Parser e s ()
forall e s. e -> Char -> Parser e s ()
Latin.char e
e Char
'-'
      Word8
w5 <- e -> Parser e s Word8
forall e s. e -> Parser e s Word8
Latin.hexWord8 e
e Parser e s Word8 -> Parser e s () -> Parser e s Word8
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* e -> Char -> Parser e s ()
forall e s. e -> Char -> Parser e s ()
Latin.char e
e Char
'-'
      Word8
w6 <- e -> Parser e s Word8
forall e s. e -> Parser e s Word8
Latin.hexWord8 e
e
      Mac -> Parser e s Mac
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac
fromOctets Word8
w1 Word8
w2 Word8
w3 Word8
w4 Word8
w5 Word8
w6)
    Char
_ -> e -> Parser e s Mac
forall e s a. e -> Parser e s a
Parser.fail e
e

-- | Make a bytestring builder from a 'Mac' address
--   using a colon as the separator.
builderUtf8 :: Mac -> BB.Builder
builderUtf8 :: Mac -> Builder
builderUtf8 = ByteString -> Builder
BB.byteString (ByteString -> Builder) -> (Mac -> ByteString) -> Mac -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mac -> ByteString
encodeUtf8

-- | Lenient parser for a 'Mac' address using any character
--   as the separator and accepting any digit grouping
--   (i.e. @FA:43:B2:C0:0F:99@ or @A065.647B.87FA@).
parserUtf8 :: AB.Parser Mac
parserUtf8 :: Parser Mac
parserUtf8 = Parser Mac
parserLenientUtf8

-- | Parser for a 'Mac' address using the provided settings.
parserWithUtf8 :: MacCodec -> AB.Parser Mac
parserWithUtf8 :: MacCodec -> Parser Mac
parserWithUtf8 (MacCodec MacGrouping
g Bool
_) = case MacGrouping
g of
  MacGroupingPairs Char
s -> Word8 -> Parser Mac
parserPairsUtf8 (Char -> Word8
c2w Char
s)
  MacGroupingTriples Char
s -> Word8 -> Parser Mac
parserTriplesUtf8 (Char -> Word8
c2w Char
s)
  MacGroupingQuadruples Char
s -> Word8 -> Parser Mac
parserQuadruplesUtf8 (Char -> Word8
c2w Char
s)
  MacGrouping
MacGroupingNoSeparator -> Parser Mac
parserNoSeparatorUtf8

parserLenientUtf8 :: AB.Parser Mac
parserLenientUtf8 :: Parser Mac
parserLenientUtf8 = do
  Word8
a1 <- Parser Word8
parseOneHexUtf8
  Word8
a2 <- Parser Word8
parseOneHexLenientUtf8
  Word8
a3 <- Parser Word8
parseOneHexLenientUtf8
  Word8
a4 <- Parser Word8
parseOneHexLenientUtf8
  Word8
a5 <- Parser Word8
parseOneHexLenientUtf8
  Word8
a6 <- Parser Word8
parseOneHexLenientUtf8
  Word8
a7 <- Parser Word8
parseOneHexLenientUtf8
  Word8
a8 <- Parser Word8
parseOneHexLenientUtf8
  Word8
a9 <- Parser Word8
parseOneHexLenientUtf8
  Word8
a10 <- Parser Word8
parseOneHexLenientUtf8
  Word8
a11 <- Parser Word8
parseOneHexLenientUtf8
  Word8
a12 <- Parser Word8
parseOneHexLenientUtf8
  Mac -> Parser Mac
forall (m :: * -> *) a. Monad m => a -> m a
return (Mac -> Parser Mac) -> Mac -> Parser Mac
forall a b. (a -> b) -> a -> b
$ Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac
fromOctets
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a1 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a2)
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a3 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a4)
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a5 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a6)
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a7 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a8)
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a9 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a10)
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a11 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a12)


parserNoSeparatorUtf8 :: AB.Parser Mac
parserNoSeparatorUtf8 :: Parser Mac
parserNoSeparatorUtf8 = Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac
fromOctets
  (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8
-> Parser
     ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8
parseTwoHexUtf8
  Parser
  ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8
-> Parser ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
parseTwoHexUtf8
  Parser ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8
-> Parser ByteString (Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
parseTwoHexUtf8
  Parser ByteString (Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8 -> Parser ByteString (Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
parseTwoHexUtf8
  Parser ByteString (Word8 -> Word8 -> Mac)
-> Parser Word8 -> Parser ByteString (Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
parseTwoHexUtf8
  Parser ByteString (Word8 -> Mac) -> Parser Word8 -> Parser Mac
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
parseTwoHexUtf8

parserPairsUtf8 :: Word8 -> AB.Parser Mac
parserPairsUtf8 :: Word8 -> Parser Mac
parserPairsUtf8 Word8
s = Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac
fromOctets
  (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8
-> Parser
     ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8
parseTwoHexUtf8 Parser
  ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8
-> Parser
     ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Word8 -> Parser Word8
ABW.word8 Word8
s
  Parser
  ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8
-> Parser ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
parseTwoHexUtf8 Parser ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8
-> Parser ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Word8 -> Parser Word8
ABW.word8 Word8
s
  Parser ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8
-> Parser ByteString (Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
parseTwoHexUtf8 Parser ByteString (Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8
-> Parser ByteString (Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Word8 -> Parser Word8
ABW.word8 Word8
s
  Parser ByteString (Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8 -> Parser ByteString (Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
parseTwoHexUtf8 Parser ByteString (Word8 -> Word8 -> Mac)
-> Parser Word8 -> Parser ByteString (Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Word8 -> Parser Word8
ABW.word8 Word8
s
  Parser ByteString (Word8 -> Word8 -> Mac)
-> Parser Word8 -> Parser ByteString (Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
parseTwoHexUtf8 Parser ByteString (Word8 -> Mac)
-> Parser Word8 -> Parser ByteString (Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Word8 -> Parser Word8
ABW.word8 Word8
s
  Parser ByteString (Word8 -> Mac) -> Parser Word8 -> Parser Mac
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
parseTwoHexUtf8

parserTriplesUtf8 :: Word8 -> AB.Parser Mac
parserTriplesUtf8 :: Word8 -> Parser Mac
parserTriplesUtf8 Word8
s = do
  Word8
a1 <- Parser Word8
parseOneHexUtf8
  Word8
a2 <- Parser Word8
parseOneHexUtf8
  Word8
a3 <- Parser Word8
parseOneHexUtf8
  Word8
_ <- Word8 -> Parser Word8
ABW.word8 Word8
s
  Word8
a4 <- Parser Word8
parseOneHexUtf8
  Word8
a5 <- Parser Word8
parseOneHexUtf8
  Word8
a6 <- Parser Word8
parseOneHexUtf8
  Word8
_ <- Word8 -> Parser Word8
ABW.word8 Word8
s
  Word8
a7 <- Parser Word8
parseOneHexUtf8
  Word8
a8 <- Parser Word8
parseOneHexUtf8
  Word8
a9 <- Parser Word8
parseOneHexUtf8
  Word8
_ <- Word8 -> Parser Word8
ABW.word8 Word8
s
  Word8
a10 <- Parser Word8
parseOneHexUtf8
  Word8
a11 <- Parser Word8
parseOneHexUtf8
  Word8
a12 <- Parser Word8
parseOneHexUtf8
  Mac -> Parser Mac
forall (m :: * -> *) a. Monad m => a -> m a
return (Mac -> Parser Mac) -> Mac -> Parser Mac
forall a b. (a -> b) -> a -> b
$ Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac
fromOctets
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a1 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a2)
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a3 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a4)
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a5 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a6)
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a7 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a8)
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a9 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a10)
    (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a11 Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
a12)

parserQuadruplesUtf8 :: Word8 -> AB.Parser Mac
parserQuadruplesUtf8 :: Word8 -> Parser Mac
parserQuadruplesUtf8 Word8
s  = Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac
fromOctets
  (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8
-> Parser
     ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8
parseTwoHexUtf8 Parser
  ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8
-> Parser ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
parseTwoHexUtf8 Parser ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8
-> Parser ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Word8 -> Parser Word8
ABW.word8 Word8
s
  Parser ByteString (Word8 -> Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8
-> Parser ByteString (Word8 -> Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
parseTwoHexUtf8 Parser ByteString (Word8 -> Word8 -> Word8 -> Mac)
-> Parser Word8 -> Parser ByteString (Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
parseTwoHexUtf8 Parser ByteString (Word8 -> Word8 -> Mac)
-> Parser Word8 -> Parser ByteString (Word8 -> Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Word8 -> Parser Word8
ABW.word8 Word8
s
  Parser ByteString (Word8 -> Word8 -> Mac)
-> Parser Word8 -> Parser ByteString (Word8 -> Mac)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
parseTwoHexUtf8 Parser ByteString (Word8 -> Mac) -> Parser Word8 -> Parser Mac
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
parseTwoHexUtf8

parseOneHexUtf8 :: AB.Parser Word8
parseOneHexUtf8 :: Parser Word8
parseOneHexUtf8 = Parser Word8
ABW.anyWord8 Parser Word8 -> (Word8 -> Parser Word8) -> Parser Word8
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Word8 -> Parser Word8
parseWord8Hex

-- | Parse a single hexidecimal character. This will skip
--   at most one character to do this.
parseOneHexLenientUtf8 :: AB.Parser Word8
parseOneHexLenientUtf8 :: Parser Word8
parseOneHexLenientUtf8 = do
  Word8
a <- Parser Word8
ABW.anyWord8
  (Parser Word8 -> Word8 -> Parser Word8)
-> Word8 -> Parser Word8 -> Parser Word8
forall a b c. (a -> b -> c) -> b -> a -> c
flip Parser Word8 -> Word8 -> Parser Word8
tryParseWord8Hex Word8
a (Parser Word8 -> Parser Word8) -> Parser Word8 -> Parser Word8
forall a b. (a -> b) -> a -> b
$ do
    Word8
b <- Parser Word8
ABW.anyWord8
    Parser Word8 -> Word8 -> Parser Word8
tryParseWord8Hex (String -> Parser Word8
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"invalid hexadecimal character") Word8
b

parseTwoHexUtf8 :: AB.Parser Word8
parseTwoHexUtf8 :: Parser Word8
parseTwoHexUtf8 = do
  Word8
a <- Parser Word8
ABW.anyWord8 Parser Word8 -> (Word8 -> Parser Word8) -> Parser Word8
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Word8 -> Parser Word8
parseWord8Hex
  Word8
b <- Parser Word8
ABW.anyWord8 Parser Word8 -> (Word8 -> Parser Word8) -> Parser Word8
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Word8 -> Parser Word8
parseWord8Hex
  Word8 -> Parser Word8
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
a Int
4 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
b)

-- | Kind of a confusing type signature. The Word8 that stands
--   alone represented an ascii-encoded value. The others actually
--   describes the numbers that would be decoded from this value.
tryParseWord8Hex :: AB.Parser Word8 -> Word8 -> AB.Parser Word8
tryParseWord8Hex :: Parser Word8 -> Word8 -> Parser Word8
tryParseWord8Hex Parser Word8
a Word8
w
  | Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
48 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
57 = Word8 -> Parser Word8
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
48)
  | Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
65 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
70 = Word8 -> Parser Word8
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
55)
  | Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
97 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
102 = Word8 -> Parser Word8
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
w Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
87)
  | Bool
otherwise = Parser Word8
a

parseWord8Hex :: Word8 -> AB.Parser Word8
parseWord8Hex :: Word8 -> Parser Word8
parseWord8Hex = Parser Word8 -> Word8 -> Parser Word8
tryParseWord8Hex (String -> Parser Word8
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"invalid hexadecimal character")

-- | Encode a 'Mac' address as a 'ByteString' using the given 'MacCodec'.
--
--   >>> m = Mac 0xA47F247AB423
--   >>> BC.putStrLn $ encodeWithUtf8 defCodec m
--   a4:7f:24:7a:b4:23
--
--   >>> BC.putStrLn $ encodeWithUtf8 (MacCodec (MacGroupingTriples '-') True) m
--   A47-F24-7AB-423
encodeWithUtf8 :: MacCodec -> Mac -> ByteString
encodeWithUtf8 :: MacCodec -> Mac -> ByteString
encodeWithUtf8 (MacCodec MacGrouping
g Bool
u) Mac
m = case MacGrouping
g of
  MacGrouping
MacGroupingNoSeparator -> case Bool
u of
    Bool
True -> Builder Mac -> Mac -> ByteString
forall a. Builder a -> a -> ByteString
BFB.run (Builder Word8 -> Builder Mac
fixedBuilderNoSeparatorUtf8 Builder Word8
BFB.word8HexFixedUpper) Mac
m
    Bool
False -> Builder Mac -> Mac -> ByteString
forall a. Builder a -> a -> ByteString
BFB.run (Builder Word8 -> Builder Mac
fixedBuilderNoSeparatorUtf8 Builder Word8
BFB.word8HexFixedLower) Mac
m
  MacGroupingPairs Char
c -> case Bool
u of
    Bool
True -> Builder PairUtf8 -> PairUtf8 -> ByteString
forall a. Builder a -> a -> ByteString
BFB.run (Builder Word8 -> Builder PairUtf8
fixedBuilderPairsUtf8 Builder Word8
BFB.word8HexFixedUpper) (Word8 -> Mac -> PairUtf8
PairUtf8 (Char -> Word8
c2w Char
c) Mac
m)
    Bool
False -> Builder PairUtf8 -> PairUtf8 -> ByteString
forall a. Builder a -> a -> ByteString
BFB.run (Builder Word8 -> Builder PairUtf8
fixedBuilderPairsUtf8 Builder Word8
BFB.word8HexFixedLower) (Word8 -> Mac -> PairUtf8
PairUtf8 (Char -> Word8
c2w Char
c) Mac
m)
    -- withCasedBuilder u $ \bw8 -> BFB.run (fixedBuilderPairs bw8) (Pair c m)
  MacGroupingTriples Char
c -> case Bool
u of
    Bool
True -> Builder PairUtf8 -> PairUtf8 -> ByteString
forall a. Builder a -> a -> ByteString
BFB.run (Builder Word12 -> Builder PairUtf8
fixedBuilderTriplesUtf8 Builder Word12
BFB.word12HexFixedUpper) (Word8 -> Mac -> PairUtf8
PairUtf8 (Char -> Word8
c2w Char
c) Mac
m)
    Bool
False -> Builder PairUtf8 -> PairUtf8 -> ByteString
forall a. Builder a -> a -> ByteString
BFB.run (Builder Word12 -> Builder PairUtf8
fixedBuilderTriplesUtf8 Builder Word12
BFB.word12HexFixedLower) (Word8 -> Mac -> PairUtf8
PairUtf8 (Char -> Word8
c2w Char
c) Mac
m)
  MacGroupingQuadruples Char
c -> case Bool
u of
    Bool
True -> Builder PairUtf8 -> PairUtf8 -> ByteString
forall a. Builder a -> a -> ByteString
BFB.run (Builder Word8 -> Builder PairUtf8
fixedBuilderQuadruplesUtf8 Builder Word8
BFB.word8HexFixedUpper) (Word8 -> Mac -> PairUtf8
PairUtf8 (Char -> Word8
c2w Char
c) Mac
m)
    Bool
False -> Builder PairUtf8 -> PairUtf8 -> ByteString
forall a. Builder a -> a -> ByteString
BFB.run (Builder Word8 -> Builder PairUtf8
fixedBuilderQuadruplesUtf8 Builder Word8
BFB.word8HexFixedLower) (Word8 -> Mac -> PairUtf8
PairUtf8 (Char -> Word8
c2w Char
c) Mac
m)

data PairUtf8 = PairUtf8
  { PairUtf8 -> Word8
pairSepUtf8 :: {-# UNPACK #-} !Word8
  , PairUtf8 -> Mac
pairMacUtf8 :: {-# UNPACK #-} !Mac
  }

fixedBuilderTriplesUtf8 :: BFB.Builder Word12 -> BFB.Builder PairUtf8
fixedBuilderTriplesUtf8 :: Builder Word12 -> Builder PairUtf8
fixedBuilderTriplesUtf8 Builder Word12
tripBuilder =
     (PairUtf8 -> Word12) -> Builder Word12 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word12
word12AtUtf8 Int
36 (Mac -> Word12) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word12
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word12
tripBuilder
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder PairUtf8 -> Word8
pairSepUtf8 Builder Word8
BFB.word8
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word12) -> Builder Word12 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word12
word12AtUtf8 Int
24 (Mac -> Word12) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word12
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word12
tripBuilder
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder PairUtf8 -> Word8
pairSepUtf8 Builder Word8
BFB.word8
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word12) -> Builder Word12 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word12
word12AtUtf8 Int
12 (Mac -> Word12) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word12
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word12
tripBuilder
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder PairUtf8 -> Word8
pairSepUtf8 Builder Word8
BFB.word8
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word12) -> Builder Word12 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word12
word12AtUtf8 Int
0 (Mac -> Word12) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word12
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word12
tripBuilder
{-# INLINE fixedBuilderTriplesUtf8 #-}

fixedBuilderQuadruplesUtf8 :: BFB.Builder Word8 -> BFB.Builder PairUtf8
fixedBuilderQuadruplesUtf8 :: Builder Word8 -> Builder PairUtf8
fixedBuilderQuadruplesUtf8 Builder Word8
pairBuilder =
     (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
40 (Mac -> Word8) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word8
pairBuilder
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
32 (Mac -> Word8) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word8
pairBuilder
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder PairUtf8 -> Word8
pairSepUtf8 Builder Word8
BFB.word8
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
24 (Mac -> Word8) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word8
pairBuilder
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
16 (Mac -> Word8) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word8
pairBuilder
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder PairUtf8 -> Word8
pairSepUtf8 Builder Word8
BFB.word8
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
8 (Mac -> Word8) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word8
pairBuilder
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
0 (Mac -> Word8) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word8
pairBuilder
{-# INLINE fixedBuilderQuadruplesUtf8 #-}

fixedBuilderPairsUtf8 :: BFB.Builder Word8 -> BFB.Builder PairUtf8
fixedBuilderPairsUtf8 :: Builder Word8 -> Builder PairUtf8
fixedBuilderPairsUtf8 Builder Word8
pairBuilder =
     (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
40 (Mac -> Word8) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word8
pairBuilder
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder PairUtf8 -> Word8
pairSepUtf8 Builder Word8
BFB.word8
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
32 (Mac -> Word8) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word8
pairBuilder
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder PairUtf8 -> Word8
pairSepUtf8 Builder Word8
BFB.word8
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
24 (Mac -> Word8) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word8
pairBuilder
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder PairUtf8 -> Word8
pairSepUtf8 Builder Word8
BFB.word8
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
16 (Mac -> Word8) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word8
pairBuilder
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder PairUtf8 -> Word8
pairSepUtf8 Builder Word8
BFB.word8
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
8 (Mac -> Word8) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word8
pairBuilder
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder PairUtf8 -> Word8
pairSepUtf8 Builder Word8
BFB.word8
  Builder PairUtf8 -> Builder PairUtf8 -> Builder PairUtf8
forall a. Semigroup a => a -> a -> a
<> (PairUtf8 -> Word8) -> Builder Word8 -> Builder PairUtf8
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
0 (Mac -> Word8) -> (PairUtf8 -> Mac) -> PairUtf8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairUtf8 -> Mac
pairMacUtf8) Builder Word8
pairBuilder
{-# INLINE fixedBuilderPairsUtf8 #-}

fixedBuilderNoSeparatorUtf8 :: BFB.Builder Word8 -> BFB.Builder Mac
fixedBuilderNoSeparatorUtf8 :: Builder Word8 -> Builder Mac
fixedBuilderNoSeparatorUtf8 Builder Word8
hexBuilder =
     (Mac -> Word8) -> Builder Word8 -> Builder Mac
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
40) Builder Word8
hexBuilder
  Builder Mac -> Builder Mac -> Builder Mac
forall a. Semigroup a => a -> a -> a
<> (Mac -> Word8) -> Builder Word8 -> Builder Mac
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
32) Builder Word8
hexBuilder
  Builder Mac -> Builder Mac -> Builder Mac
forall a. Semigroup a => a -> a -> a
<> (Mac -> Word8) -> Builder Word8 -> Builder Mac
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
24) Builder Word8
hexBuilder
  Builder Mac -> Builder Mac -> Builder Mac
forall a. Semigroup a => a -> a -> a
<> (Mac -> Word8) -> Builder Word8 -> Builder Mac
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
16) Builder Word8
hexBuilder
  Builder Mac -> Builder Mac -> Builder Mac
forall a. Semigroup a => a -> a -> a
<> (Mac -> Word8) -> Builder Word8 -> Builder Mac
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
8) Builder Word8
hexBuilder
  Builder Mac -> Builder Mac -> Builder Mac
forall a. Semigroup a => a -> a -> a
<> (Mac -> Word8) -> Builder Word8 -> Builder Mac
forall b a. (b -> a) -> Builder a -> Builder b
BFB.contramapBuilder (Int -> Mac -> Word8
word8AtUtf8 Int
0) Builder Word8
hexBuilder
{-# INLINE fixedBuilderNoSeparatorUtf8 #-}

word8AtUtf8 :: Int -> Mac -> Word8
word8AtUtf8 :: Int -> Mac -> Word8
word8AtUtf8 Int
i (Mac Word64
w) = Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
i)
{-# INLINE word8AtUtf8 #-}

word12AtUtf8 :: Int -> Mac -> Word12
word12AtUtf8 :: Int -> Mac -> Word12
word12AtUtf8 Int
i (Mac Word64
w) = Word64 -> Word12
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
i)
{-# INLINE word12AtUtf8 #-}

-- | A 48-bit MAC address. Do not use the data constructor for this
--   type. It is not considered part of the stable API, and it
--   allows you to construct invalid MAC addresses.
newtype Mac = Mac Word64
  deriving (Mac -> Mac -> Bool
(Mac -> Mac -> Bool) -> (Mac -> Mac -> Bool) -> Eq Mac
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Mac -> Mac -> Bool
$c/= :: Mac -> Mac -> Bool
== :: Mac -> Mac -> Bool
$c== :: Mac -> Mac -> Bool
Eq,Eq Mac
Eq Mac
-> (Mac -> Mac -> Ordering)
-> (Mac -> Mac -> Bool)
-> (Mac -> Mac -> Bool)
-> (Mac -> Mac -> Bool)
-> (Mac -> Mac -> Bool)
-> (Mac -> Mac -> Mac)
-> (Mac -> Mac -> Mac)
-> Ord Mac
Mac -> Mac -> Bool
Mac -> Mac -> Ordering
Mac -> Mac -> Mac
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
min :: Mac -> Mac -> Mac
$cmin :: Mac -> Mac -> Mac
max :: Mac -> Mac -> Mac
$cmax :: Mac -> Mac -> Mac
>= :: Mac -> Mac -> Bool
$c>= :: Mac -> Mac -> Bool
> :: Mac -> Mac -> Bool
$c> :: Mac -> Mac -> Bool
<= :: Mac -> Mac -> Bool
$c<= :: Mac -> Mac -> Bool
< :: Mac -> Mac -> Bool
$c< :: Mac -> Mac -> Bool
compare :: Mac -> Mac -> Ordering
$ccompare :: Mac -> Mac -> Ordering
$cp1Ord :: Eq Mac
Ord,(forall x. Mac -> Rep Mac x)
-> (forall x. Rep Mac x -> Mac) -> Generic Mac
forall x. Rep Mac x -> Mac
forall x. Mac -> Rep Mac x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Mac x -> Mac
$cfrom :: forall x. Mac -> Rep Mac x
Generic,Ord Mac
Ord Mac
-> ((Mac, Mac) -> [Mac])
-> ((Mac, Mac) -> Mac -> Int)
-> ((Mac, Mac) -> Mac -> Int)
-> ((Mac, Mac) -> Mac -> Bool)
-> ((Mac, Mac) -> Int)
-> ((Mac, Mac) -> Int)
-> Ix Mac
(Mac, Mac) -> Int
(Mac, Mac) -> [Mac]
(Mac, Mac) -> Mac -> Bool
(Mac, Mac) -> Mac -> Int
forall a.
Ord a
-> ((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
unsafeRangeSize :: (Mac, Mac) -> Int
$cunsafeRangeSize :: (Mac, Mac) -> Int
rangeSize :: (Mac, Mac) -> Int
$crangeSize :: (Mac, Mac) -> Int
inRange :: (Mac, Mac) -> Mac -> Bool
$cinRange :: (Mac, Mac) -> Mac -> Bool
unsafeIndex :: (Mac, Mac) -> Mac -> Int
$cunsafeIndex :: (Mac, Mac) -> Mac -> Int
index :: (Mac, Mac) -> Mac -> Int
$cindex :: (Mac, Mac) -> Mac -> Int
range :: (Mac, Mac) -> [Mac]
$crange :: (Mac, Mac) -> [Mac]
$cp1Ix :: Ord Mac
Ix,Typeable Mac
DataType
Constr
Typeable Mac
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Mac -> c Mac)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Mac)
-> (Mac -> Constr)
-> (Mac -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Mac))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Mac))
-> ((forall b. Data b => b -> b) -> Mac -> Mac)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Mac -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Mac -> r)
-> (forall u. (forall d. Data d => d -> u) -> Mac -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Mac -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Mac -> m Mac)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Mac -> m Mac)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Mac -> m Mac)
-> Data Mac
Mac -> DataType
Mac -> Constr
(forall b. Data b => b -> b) -> Mac -> Mac
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Mac -> c Mac
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Mac
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Mac -> u
forall u. (forall d. Data d => d -> u) -> Mac -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Mac -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Mac -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Mac -> m Mac
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Mac -> m Mac
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Mac
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Mac -> c Mac
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Mac)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Mac)
$cMac :: Constr
$tMac :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Mac -> m Mac
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Mac -> m Mac
gmapMp :: (forall d. Data d => d -> m d) -> Mac -> m Mac
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Mac -> m Mac
gmapM :: (forall d. Data d => d -> m d) -> Mac -> m Mac
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Mac -> m Mac
gmapQi :: Int -> (forall d. Data d => d -> u) -> Mac -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Mac -> u
gmapQ :: (forall d. Data d => d -> u) -> Mac -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Mac -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Mac -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Mac -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Mac -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Mac -> r
gmapT :: (forall b. Data b => b -> b) -> Mac -> Mac
$cgmapT :: (forall b. Data b => b -> b) -> Mac -> Mac
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Mac)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Mac)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Mac)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Mac)
dataTypeOf :: Mac -> DataType
$cdataTypeOf :: Mac -> DataType
toConstr :: Mac -> Constr
$ctoConstr :: Mac -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Mac
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Mac
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Mac -> c Mac
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Mac -> c Mac
$cp1Data :: Typeable Mac
Data)

instance NFData Mac

-- | This only preserves the lower 6 bytes of the 8-byte word that backs a mac address.
-- It runs slower than it would if it used a full 8-byte word, but it consumes less
-- space. When storing millions of mac addresses, this is a good trade to make. When
-- storing a small number of mac address, it might be preferable to make a primitive
-- array of 'Word64' instead and use the mac address data constructor to coerce between
-- the two.
instance Prim Mac where
  sizeOf# :: Mac -> Int#
sizeOf# Mac
_ = Int#
6#
  alignment# :: Mac -> Int#
alignment# Mac
_ = Int#
2#
  indexByteArray# :: ByteArray# -> Int# -> Mac
indexByteArray# ByteArray#
arr Int#
i0 = Word# -> Word# -> Word# -> Mac
macFromWord16#
    (ByteArray# -> Int# -> Word#
indexWord16Array# ByteArray#
arr Int#
i)
    (ByteArray# -> Int# -> Word#
indexWord16Array# ByteArray#
arr (Int#
i Int# -> Int# -> Int#
+# Int#
1#))
    (ByteArray# -> Int# -> Word#
indexWord16Array# ByteArray#
arr (Int#
i Int# -> Int# -> Int#
+# Int#
2#))
    where !i :: Int#
i = Int#
3# Int# -> Int# -> Int#
*# Int#
i0
  readByteArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Mac #)
readByteArray# MutableByteArray# s
arr Int#
i0 State# s
s0 = case MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
forall d.
MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)
readWord16Array# MutableByteArray# s
arr Int#
i State# s
s0 of
    (# State# s
s1, Word#
a #) -> case MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
forall d.
MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)
readWord16Array# MutableByteArray# s
arr (Int#
i Int# -> Int# -> Int#
+# Int#
1#) State# s
s1 of
      (# State# s
s2, Word#
b #) -> case MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
forall d.
MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)
readWord16Array# MutableByteArray# s
arr (Int#
i Int# -> Int# -> Int#
+# Int#
2#) State# s
s2 of
        (# State# s
s3, Word#
c #) -> (# State# s
s3, Word# -> Word# -> Word# -> Mac
macFromWord16# Word#
a Word#
b Word#
c #)
    where !i :: Int#
i = Int#
3# Int# -> Int# -> Int#
*# Int#
i0
  writeByteArray# :: MutableByteArray# s -> Int# -> Mac -> State# s -> State# s
writeByteArray# MutableByteArray# s
arr Int#
i0 Mac
m State# s
s0 = case MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
forall d.
MutableByteArray# d -> Int# -> Word# -> State# d -> State# d
writeWord16Array# MutableByteArray# s
arr Int#
i (Mac -> Word#
macToWord16A# Mac
m) State# s
s0 of
    State# s
s1 -> case MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
forall d.
MutableByteArray# d -> Int# -> Word# -> State# d -> State# d
writeWord16Array# MutableByteArray# s
arr (Int#
i Int# -> Int# -> Int#
+# Int#
1#) (Mac -> Word#
macToWord16B# Mac
m) State# s
s1 of
      State# s
s2 -> MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
forall d.
MutableByteArray# d -> Int# -> Word# -> State# d -> State# d
writeWord16Array# MutableByteArray# s
arr (Int#
i Int# -> Int# -> Int#
+# Int#
2#) (Mac -> Word#
macToWord16C# Mac
m) State# s
s2
    where !i :: Int#
i = Int#
3# Int# -> Int# -> Int#
*# Int#
i0
  indexOffAddr# :: Addr# -> Int# -> Mac
indexOffAddr# Addr#
arr Int#
i0 = Word# -> Word# -> Word# -> Mac
macFromWord16#
    (Addr# -> Int# -> Word#
indexWord16OffAddr# Addr#
arr Int#
i)
    (Addr# -> Int# -> Word#
indexWord16OffAddr# Addr#
arr (Int#
i Int# -> Int# -> Int#
+# Int#
1#))
    (Addr# -> Int# -> Word#
indexWord16OffAddr# Addr#
arr (Int#
i Int# -> Int# -> Int#
+# Int#
2#))
    where !i :: Int#
i = Int#
3# Int# -> Int# -> Int#
*# Int#
i0
  readOffAddr# :: Addr# -> Int# -> State# s -> (# State# s, Mac #)
readOffAddr# Addr#
arr Int#
i0 State# s
s0 = case Addr# -> Int# -> State# s -> (# State# s, Word# #)
forall d. Addr# -> Int# -> State# d -> (# State# d, Word# #)
readWord16OffAddr# Addr#
arr Int#
i State# s
s0 of
    (# State# s
s1, Word#
a #) -> case Addr# -> Int# -> State# s -> (# State# s, Word# #)
forall d. Addr# -> Int# -> State# d -> (# State# d, Word# #)
readWord16OffAddr# Addr#
arr (Int#
i Int# -> Int# -> Int#
+# Int#
1#) State# s
s1 of
      (# State# s
s2, Word#
b #) -> case Addr# -> Int# -> State# s -> (# State# s, Word# #)
forall d. Addr# -> Int# -> State# d -> (# State# d, Word# #)
readWord16OffAddr# Addr#
arr (Int#
i Int# -> Int# -> Int#
+# Int#
2#) State# s
s2 of
        (# State# s
s3, Word#
c #) -> (# State# s
s3, Word# -> Word# -> Word# -> Mac
macFromWord16# Word#
a Word#
b Word#
c #)
    where !i :: Int#
i = Int#
3# Int# -> Int# -> Int#
*# Int#
i0
  writeOffAddr# :: Addr# -> Int# -> Mac -> State# s -> State# s
writeOffAddr# Addr#
arr Int#
i0 Mac
m State# s
s0 = case Addr# -> Int# -> Word# -> State# s -> State# s
forall d. Addr# -> Int# -> Word# -> State# d -> State# d
writeWord16OffAddr# Addr#
arr Int#
i (Mac -> Word#
macToWord16A# Mac
m) State# s
s0 of
    State# s
s1 -> case Addr# -> Int# -> Word# -> State# s -> State# s
forall d. Addr# -> Int# -> Word# -> State# d -> State# d
writeWord16OffAddr# Addr#
arr (Int#
i Int# -> Int# -> Int#
+# Int#
1#) (Mac -> Word#
macToWord16B# Mac
m) State# s
s1 of
      State# s
s2 -> Addr# -> Int# -> Word# -> State# s -> State# s
forall d. Addr# -> Int# -> Word# -> State# d -> State# d
writeWord16OffAddr# Addr#
arr (Int#
i Int# -> Int# -> Int#
+# Int#
2#) (Mac -> Word#
macToWord16C# Mac
m) State# s
s2
    where !i :: Int#
i = Int#
3# Int# -> Int# -> Int#
*# Int#
i0
  setByteArray# :: MutableByteArray# s -> Int# -> Int# -> Mac -> State# s -> State# s
setByteArray# MutableByteArray# s
arr# Int#
i# Int#
len# Mac
ident = Int# -> State# s -> State# s
go Int#
0#
    where
      go :: Int# -> State# s -> State# s
go Int#
ix# State# s
s0 = if Int# -> Bool
isTrue# (Int#
ix# Int# -> Int# -> Int#
<# Int#
len#)
        then case MutableByteArray# s -> Int# -> Mac -> State# s -> State# s
forall a s.
Prim a =>
MutableByteArray# s -> Int# -> a -> State# s -> State# s
writeByteArray# MutableByteArray# s
arr# (Int#
i# Int# -> Int# -> Int#
+# Int#
ix#) Mac
ident State# s
s0 of
          State# s
s1 -> Int# -> State# s -> State# s
go (Int#
ix# Int# -> Int# -> Int#
+# Int#
1#) State# s
s1
        else State# s
s0
  setOffAddr# :: Addr# -> Int# -> Int# -> Mac -> State# s -> State# s
setOffAddr# Addr#
addr# Int#
i# Int#
len# Mac
ident = Int# -> State# s -> State# s
go Int#
0#
    where
      go :: Int# -> State# s -> State# s
go Int#
ix# State# s
s0 = if Int# -> Bool
isTrue# (Int#
ix# Int# -> Int# -> Int#
<# Int#
len#)
        then case Addr# -> Int# -> Mac -> State# s -> State# s
forall a s. Prim a => Addr# -> Int# -> a -> State# s -> State# s
writeOffAddr# Addr#
addr# (Int#
i# Int# -> Int# -> Int#
+# Int#
ix#) Mac
ident State# s
s0 of
          State# s
s1 -> Int# -> State# s -> State# s
go (Int#
ix# Int# -> Int# -> Int#
+# Int#
1#) State# s
s1
        else State# s
s0

macToWord16A# :: Mac -> Word#
macToWord16A# :: Mac -> Word#
macToWord16A# (Mac Word64
w) = case Word64 -> Word16
word64ToWord16 (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
32) of
  W16# Word#
x -> Word#
x

macToWord16B# :: Mac -> Word#
macToWord16B# :: Mac -> Word#
macToWord16B# (Mac Word64
w) = case Word64 -> Word16
word64ToWord16 (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
w Int
16) of
  W16# Word#
x -> Word#
x

macToWord16C# :: Mac -> Word#
macToWord16C# :: Mac -> Word#
macToWord16C# (Mac Word64
w) = case Word64 -> Word16
word64ToWord16 Word64
w of
  W16# Word#
x -> Word#
x

macFromWord16# :: Word# -> Word# -> Word# -> Mac
macFromWord16# :: Word# -> Word# -> Word# -> Mac
macFromWord16# Word#
a Word#
b Word#
c = Word64 -> Mac
Mac
    (Word64 -> Mac) -> Word64 -> Mac
forall a b. (a -> b) -> a -> b
$ (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word16 -> Word64
word16ToWord64 (Word# -> Word16
W16# Word#
a)) Int
32)
  Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word16 -> Word64
word16ToWord64 (Word# -> Word16
W16# Word#
b)) Int
16)
  Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word16 -> Word64
word16ToWord64 (Word# -> Word16
W16# Word#
c))

word16ToWord64 :: Word16 -> Word64
word16ToWord64 :: Word16 -> Word64
word16ToWord64 = Word16 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral

word64ToWord16 :: Word64 -> Word16
word64ToWord16 :: Word64 -> Word16
word64ToWord16 = Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral

-- What this instance does is to display the
-- inner contents in hexadecimal and pad them out to
-- 6 bytes in case it begins with several zeroes.
-- It also uses the smart constructor instead
-- of the actual constructor
instance Show Mac where
  showsPrec :: Int -> Mac -> ShowS
showsPrec Int
p (Mac Word64
addr) = Bool -> ShowS -> ShowS
showParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10)
    (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ String -> ShowS
showString String
"mac "
    ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> ShowS
showHexWord48 Word64
addr

instance Read Mac where
  readPrec :: ReadPrec Mac
readPrec = ReadPrec Mac -> ReadPrec Mac
forall a. ReadPrec a -> ReadPrec a
parens (ReadPrec Mac -> ReadPrec Mac) -> ReadPrec Mac -> ReadPrec Mac
forall a b. (a -> b) -> a -> b
$ Int -> ReadPrec Mac -> ReadPrec Mac
forall a. Int -> ReadPrec a -> ReadPrec a
prec Int
10 (ReadPrec Mac -> ReadPrec Mac) -> ReadPrec Mac -> ReadPrec Mac
forall a b. (a -> b) -> a -> b
$ do
    Ident String
"mac" <- ReadPrec Lexeme
lexP
    Word64
w <- ReadPrec Word64 -> ReadPrec Word64
forall a. ReadPrec a -> ReadPrec a
step ReadPrec Word64
forall a. Read a => ReadPrec a
readPrec
    Mac -> ReadPrec Mac
forall (m :: * -> *) a. Monad m => a -> m a
return (Word64 -> Mac
mac Word64
w)

instance Bounded Mac where
  minBound :: Mac
minBound = Word64 -> Mac
Mac Word64
0
  maxBound :: Mac
maxBound = Word64 -> Mac
Mac Word64
0xFFFFFFFFFFFF

instance Enum Mac where
  succ :: Mac -> Mac
succ m :: Mac
m@(Mac Word64
x)
    | Mac
m Mac -> Mac -> Bool
forall a. Eq a => a -> a -> Bool
== Mac
forall a. Bounded a => a
maxBound = String -> Mac
forall a. String -> a
succError String
"Mac"
    | Bool
otherwise = Word64 -> Mac
Mac (Word64
x Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
1)
  pred :: Mac -> Mac
pred m :: Mac
m@(Mac Word64
x)
    | Mac
m Mac -> Mac -> Bool
forall a. Eq a => a -> a -> Bool
== Mac
forall a. Bounded a => a
minBound = String -> Mac
forall a. String -> a
predError String
"Mac"
    | Bool
otherwise = Word64 -> Mac
Mac (Word64
x Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
1)
  toEnum :: Int -> Mac
toEnum Int
i = Word64 -> Mac
Mac (Int -> Word64
forall a. Enum a => Int -> a
toEnum Int
i)
  fromEnum :: Mac -> Int
fromEnum (Mac Word64
x) = Word64 -> Int
forall a. Enum a => a -> Int
fromEnum Word64
x

-- | Print a 'Mac' address using the textual encoding.
print :: Mac -> IO ()
print :: Mac -> IO ()
print = Text -> IO ()
TIO.putStrLn (Text -> IO ()) -> (Mac -> Text) -> Mac -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mac -> Text
encode

showHexWord48 :: Word64 -> ShowS
showHexWord48 :: Word64 -> ShowS
showHexWord48 Word64
w = String -> ShowS
showString String
"0x" ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
go Int
11
  where
  go :: Int -> ShowS
  go :: Int -> ShowS
go !Int
ix = if Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
    then Char -> ShowS
showChar (Word -> Char
nibbleToHex ((Word -> Int -> Word
forall a. Bits a => a -> Int -> a
unsafeShiftR (Word64 -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
w) (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
4)) Word -> Word -> Word
forall a. Bits a => a -> a -> a
.&. Word
0xF)) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
    else ShowS
forall a. a -> a
id

nibbleToHex :: Word -> Char
nibbleToHex :: Word -> Char
nibbleToHex Word
w
  | Word
w Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
< Word
10 = Int -> Char
chr (Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word
w Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word
48))
  | Bool
otherwise = Int -> Char
chr (Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word
w Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word
87))

-- | A 'MacCodec' allows users to control the encoding/decoding
--   of their 'Mac' addresses.
data MacCodec = MacCodec
  { MacCodec -> MacGrouping
macCodecGrouping :: !MacGrouping
  , MacCodec -> Bool
macCodecUpperCase :: !Bool
  } deriving (MacCodec -> MacCodec -> Bool
(MacCodec -> MacCodec -> Bool)
-> (MacCodec -> MacCodec -> Bool) -> Eq MacCodec
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MacCodec -> MacCodec -> Bool
$c/= :: MacCodec -> MacCodec -> Bool
== :: MacCodec -> MacCodec -> Bool
$c== :: MacCodec -> MacCodec -> Bool
Eq,Eq MacCodec
Eq MacCodec
-> (MacCodec -> MacCodec -> Ordering)
-> (MacCodec -> MacCodec -> Bool)
-> (MacCodec -> MacCodec -> Bool)
-> (MacCodec -> MacCodec -> Bool)
-> (MacCodec -> MacCodec -> Bool)
-> (MacCodec -> MacCodec -> MacCodec)
-> (MacCodec -> MacCodec -> MacCodec)
-> Ord MacCodec
MacCodec -> MacCodec -> Bool
MacCodec -> MacCodec -> Ordering
MacCodec -> MacCodec -> MacCodec
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
min :: MacCodec -> MacCodec -> MacCodec
$cmin :: MacCodec -> MacCodec -> MacCodec
max :: MacCodec -> MacCodec -> MacCodec
$cmax :: MacCodec -> MacCodec -> MacCodec
>= :: MacCodec -> MacCodec -> Bool
$c>= :: MacCodec -> MacCodec -> Bool
> :: MacCodec -> MacCodec -> Bool
$c> :: MacCodec -> MacCodec -> Bool
<= :: MacCodec -> MacCodec -> Bool
$c<= :: MacCodec -> MacCodec -> Bool
< :: MacCodec -> MacCodec -> Bool
$c< :: MacCodec -> MacCodec -> Bool
compare :: MacCodec -> MacCodec -> Ordering
$ccompare :: MacCodec -> MacCodec -> Ordering
$cp1Ord :: Eq MacCodec
Ord,Int -> MacCodec -> ShowS
[MacCodec] -> ShowS
MacCodec -> String
(Int -> MacCodec -> ShowS)
-> (MacCodec -> String) -> ([MacCodec] -> ShowS) -> Show MacCodec
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MacCodec] -> ShowS
$cshowList :: [MacCodec] -> ShowS
show :: MacCodec -> String
$cshow :: MacCodec -> String
showsPrec :: Int -> MacCodec -> ShowS
$cshowsPrec :: Int -> MacCodec -> ShowS
Show,ReadPrec [MacCodec]
ReadPrec MacCodec
Int -> ReadS MacCodec
ReadS [MacCodec]
(Int -> ReadS MacCodec)
-> ReadS [MacCodec]
-> ReadPrec MacCodec
-> ReadPrec [MacCodec]
-> Read MacCodec
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [MacCodec]
$creadListPrec :: ReadPrec [MacCodec]
readPrec :: ReadPrec MacCodec
$creadPrec :: ReadPrec MacCodec
readList :: ReadS [MacCodec]
$creadList :: ReadS [MacCodec]
readsPrec :: Int -> ReadS MacCodec
$creadsPrec :: Int -> ReadS MacCodec
Read,(forall x. MacCodec -> Rep MacCodec x)
-> (forall x. Rep MacCodec x -> MacCodec) -> Generic MacCodec
forall x. Rep MacCodec x -> MacCodec
forall x. MacCodec -> Rep MacCodec x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep MacCodec x -> MacCodec
$cfrom :: forall x. MacCodec -> Rep MacCodec x
Generic,Typeable MacCodec
DataType
Constr
Typeable MacCodec
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> MacCodec -> c MacCodec)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c MacCodec)
-> (MacCodec -> Constr)
-> (MacCodec -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c MacCodec))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MacCodec))
-> ((forall b. Data b => b -> b) -> MacCodec -> MacCodec)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> MacCodec -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> MacCodec -> r)
-> (forall u. (forall d. Data d => d -> u) -> MacCodec -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> MacCodec -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> MacCodec -> m MacCodec)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> MacCodec -> m MacCodec)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> MacCodec -> m MacCodec)
-> Data MacCodec
MacCodec -> DataType
MacCodec -> Constr
(forall b. Data b => b -> b) -> MacCodec -> MacCodec
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MacCodec -> c MacCodec
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MacCodec
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> MacCodec -> u
forall u. (forall d. Data d => d -> u) -> MacCodec -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MacCodec -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MacCodec -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> MacCodec -> m MacCodec
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MacCodec -> m MacCodec
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MacCodec
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MacCodec -> c MacCodec
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c MacCodec)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MacCodec)
$cMacCodec :: Constr
$tMacCodec :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> MacCodec -> m MacCodec
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MacCodec -> m MacCodec
gmapMp :: (forall d. Data d => d -> m d) -> MacCodec -> m MacCodec
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MacCodec -> m MacCodec
gmapM :: (forall d. Data d => d -> m d) -> MacCodec -> m MacCodec
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> MacCodec -> m MacCodec
gmapQi :: Int -> (forall d. Data d => d -> u) -> MacCodec -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> MacCodec -> u
gmapQ :: (forall d. Data d => d -> u) -> MacCodec -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> MacCodec -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MacCodec -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MacCodec -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MacCodec -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MacCodec -> r
gmapT :: (forall b. Data b => b -> b) -> MacCodec -> MacCodec
$cgmapT :: (forall b. Data b => b -> b) -> MacCodec -> MacCodec
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MacCodec)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MacCodec)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c MacCodec)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c MacCodec)
dataTypeOf :: MacCodec -> DataType
$cdataTypeOf :: MacCodec -> DataType
toConstr :: MacCodec -> Constr
$ctoConstr :: MacCodec -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MacCodec
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MacCodec
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MacCodec -> c MacCodec
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MacCodec -> c MacCodec
$cp1Data :: Typeable MacCodec
Data)

-- | The format expected by the mac address parser. The 'Word8' taken
--   by some of these constructors is the ascii value of the character
--   to be used as the separator. This is typically a colon, a hyphen, or
--   a space character. All decoding functions are case insensitive.
data MacGrouping
  = MacGroupingPairs !Char -- ^ Two-character groups, @FA:2B:40:09:8C:11@
  | MacGroupingTriples !Char -- ^ Three-character groups, @24B-F0A-025-829@
  | MacGroupingQuadruples !Char -- ^ Four-character groups, @A220.0745.CAC7@
  | MacGroupingNoSeparator -- ^ No separator, @24AF4B5B0780@
  deriving (MacGrouping -> MacGrouping -> Bool
(MacGrouping -> MacGrouping -> Bool)
-> (MacGrouping -> MacGrouping -> Bool) -> Eq MacGrouping
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MacGrouping -> MacGrouping -> Bool
$c/= :: MacGrouping -> MacGrouping -> Bool
== :: MacGrouping -> MacGrouping -> Bool
$c== :: MacGrouping -> MacGrouping -> Bool
Eq,Eq MacGrouping
Eq MacGrouping
-> (MacGrouping -> MacGrouping -> Ordering)
-> (MacGrouping -> MacGrouping -> Bool)
-> (MacGrouping -> MacGrouping -> Bool)
-> (MacGrouping -> MacGrouping -> Bool)
-> (MacGrouping -> MacGrouping -> Bool)
-> (MacGrouping -> MacGrouping -> MacGrouping)
-> (MacGrouping -> MacGrouping -> MacGrouping)
-> Ord MacGrouping
MacGrouping -> MacGrouping -> Bool
MacGrouping -> MacGrouping -> Ordering
MacGrouping -> MacGrouping -> MacGrouping
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
min :: MacGrouping -> MacGrouping -> MacGrouping
$cmin :: MacGrouping -> MacGrouping -> MacGrouping
max :: MacGrouping -> MacGrouping -> MacGrouping
$cmax :: MacGrouping -> MacGrouping -> MacGrouping
>= :: MacGrouping -> MacGrouping -> Bool
$c>= :: MacGrouping -> MacGrouping -> Bool
> :: MacGrouping -> MacGrouping -> Bool
$c> :: MacGrouping -> MacGrouping -> Bool
<= :: MacGrouping -> MacGrouping -> Bool
$c<= :: MacGrouping -> MacGrouping -> Bool
< :: MacGrouping -> MacGrouping -> Bool
$c< :: MacGrouping -> MacGrouping -> Bool
compare :: MacGrouping -> MacGrouping -> Ordering
$ccompare :: MacGrouping -> MacGrouping -> Ordering
$cp1Ord :: Eq MacGrouping
Ord,Int -> MacGrouping -> ShowS
[MacGrouping] -> ShowS
MacGrouping -> String
(Int -> MacGrouping -> ShowS)
-> (MacGrouping -> String)
-> ([MacGrouping] -> ShowS)
-> Show MacGrouping
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MacGrouping] -> ShowS
$cshowList :: [MacGrouping] -> ShowS
show :: MacGrouping -> String
$cshow :: MacGrouping -> String
showsPrec :: Int -> MacGrouping -> ShowS
$cshowsPrec :: Int -> MacGrouping -> ShowS
Show,ReadPrec [MacGrouping]
ReadPrec MacGrouping
Int -> ReadS MacGrouping
ReadS [MacGrouping]
(Int -> ReadS MacGrouping)
-> ReadS [MacGrouping]
-> ReadPrec MacGrouping
-> ReadPrec [MacGrouping]
-> Read MacGrouping
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [MacGrouping]
$creadListPrec :: ReadPrec [MacGrouping]
readPrec :: ReadPrec MacGrouping
$creadPrec :: ReadPrec MacGrouping
readList :: ReadS [MacGrouping]
$creadList :: ReadS [MacGrouping]
readsPrec :: Int -> ReadS MacGrouping
$creadsPrec :: Int -> ReadS MacGrouping
Read,(forall x. MacGrouping -> Rep MacGrouping x)
-> (forall x. Rep MacGrouping x -> MacGrouping)
-> Generic MacGrouping
forall x. Rep MacGrouping x -> MacGrouping
forall x. MacGrouping -> Rep MacGrouping x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep MacGrouping x -> MacGrouping
$cfrom :: forall x. MacGrouping -> Rep MacGrouping x
Generic,Typeable MacGrouping
DataType
Constr
Typeable MacGrouping
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> MacGrouping -> c MacGrouping)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c MacGrouping)
-> (MacGrouping -> Constr)
-> (MacGrouping -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c MacGrouping))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c MacGrouping))
-> ((forall b. Data b => b -> b) -> MacGrouping -> MacGrouping)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> MacGrouping -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> MacGrouping -> r)
-> (forall u. (forall d. Data d => d -> u) -> MacGrouping -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> MacGrouping -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> MacGrouping -> m MacGrouping)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> MacGrouping -> m MacGrouping)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> MacGrouping -> m MacGrouping)
-> Data MacGrouping
MacGrouping -> DataType
MacGrouping -> Constr
(forall b. Data b => b -> b) -> MacGrouping -> MacGrouping
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MacGrouping -> c MacGrouping
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MacGrouping
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> MacGrouping -> u
forall u. (forall d. Data d => d -> u) -> MacGrouping -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MacGrouping -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MacGrouping -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> MacGrouping -> m MacGrouping
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MacGrouping -> m MacGrouping
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MacGrouping
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MacGrouping -> c MacGrouping
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c MacGrouping)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c MacGrouping)
$cMacGroupingNoSeparator :: Constr
$cMacGroupingQuadruples :: Constr
$cMacGroupingTriples :: Constr
$cMacGroupingPairs :: Constr
$tMacGrouping :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> MacGrouping -> m MacGrouping
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MacGrouping -> m MacGrouping
gmapMp :: (forall d. Data d => d -> m d) -> MacGrouping -> m MacGrouping
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MacGrouping -> m MacGrouping
gmapM :: (forall d. Data d => d -> m d) -> MacGrouping -> m MacGrouping
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> MacGrouping -> m MacGrouping
gmapQi :: Int -> (forall d. Data d => d -> u) -> MacGrouping -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> MacGrouping -> u
gmapQ :: (forall d. Data d => d -> u) -> MacGrouping -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> MacGrouping -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MacGrouping -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MacGrouping -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MacGrouping -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MacGrouping -> r
gmapT :: (forall b. Data b => b -> b) -> MacGrouping -> MacGrouping
$cgmapT :: (forall b. Data b => b -> b) -> MacGrouping -> MacGrouping
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c MacGrouping)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c MacGrouping)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c MacGrouping)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c MacGrouping)
dataTypeOf :: MacGrouping -> DataType
$cdataTypeOf :: MacGrouping -> DataType
toConstr :: MacGrouping -> Constr
$ctoConstr :: MacGrouping -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MacGrouping
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MacGrouping
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MacGrouping -> c MacGrouping
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MacGrouping -> c MacGrouping
$cp1Data :: Typeable MacGrouping
Data)

instance Hashable Mac

instance ToJSON Mac where
  toJSON :: Mac -> Value
toJSON = Text -> Value
Aeson.String (Text -> Value) -> (Mac -> Text) -> Mac -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mac -> Text
encode

instance ToJSONKey Mac where
  toJSONKey :: ToJSONKeyFunction Mac
toJSONKey = (Mac -> Key) -> (Mac -> Encoding' Key) -> ToJSONKeyFunction Mac
forall a. (a -> Key) -> (a -> Encoding' Key) -> ToJSONKeyFunction a
ToJSONKeyText
    (Text -> Key
keyFromText (Text -> Key) -> (Mac -> Text) -> Mac -> Key
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mac -> Text
encode)
    (\Mac
m -> Builder -> Encoding' Key
forall a. Builder -> Encoding' a
Aeson.unsafeToEncoding (Builder -> Encoding' Key) -> Builder -> Encoding' Key
forall a b. (a -> b) -> a -> b
$ Char -> Builder
BB.char7 Char
'"' Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Mac -> Builder
builderUtf8 Mac
m Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Char -> Builder
BB.char7 Char
'"')
    where
#if MIN_VERSION_aeson(2,0,0)
      keyFromText :: Text -> Key
keyFromText = Text -> Key
AK.fromText
#else
      keyFromText = id
#endif

instance FromJSONKey Mac where
  fromJSONKey :: FromJSONKeyFunction Mac
fromJSONKey = (Text -> Parser Mac) -> FromJSONKeyFunction Mac
forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser ((Text -> Parser Mac) -> FromJSONKeyFunction Mac)
-> (Text -> Parser Mac) -> FromJSONKeyFunction Mac
forall a b. (a -> b) -> a -> b
$ \Text
t -> case Text -> Maybe Mac
decode Text
t of
    Maybe Mac
Nothing -> String -> Parser Mac
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"invalid mac address"
    Just Mac
addr -> Mac -> Parser Mac
forall (m :: * -> *) a. Monad m => a -> m a
return Mac
addr

instance FromJSON Mac where
  parseJSON :: Value -> Parser Mac
parseJSON = Parser Mac -> Value -> Parser Mac
forall a. Parser a -> Value -> Parser a
attoparsecParseJSON Parser Mac
parser

attoparsecParseJSON :: AT.Parser a -> Aeson.Value -> Aeson.Parser a
attoparsecParseJSON :: Parser a -> Value -> Parser a
attoparsecParseJSON Parser a
p Value
v =
  case Value
v of
    Aeson.String Text
t ->
      case Parser a -> Text -> Either String a
forall a. Parser a -> Text -> Either String a
AT.parseOnly Parser a
p Text
t of
        Left String
err  -> String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
err
        Right a
res -> a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return a
res
    Value
_ -> String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"expected a String"

-- Unchecked invariant: each of these Word64s must be smaller
-- than 256.
unsafeWord48FromOctets :: Word64 -> Word64 -> Word64 -> Word64 -> Word64 -> Word64 -> Word64
unsafeWord48FromOctets :: Word64 -> Word64 -> Word64 -> Word64 -> Word64 -> Word64 -> Word64
unsafeWord48FromOctets Word64
a Word64
b Word64
c Word64
d Word64
e Word64
f =
    Word64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  (Word64 -> Word64) -> Word64 -> Word64
forall a b. (a -> b) -> a -> b
$ Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
a Int
40
  Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
b Int
32
  Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
c Int
24
  Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
d Int
16
  Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
e Int
8
  Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64
f