asn-0.1.0.0: Asn.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE UnboxedTuples #-}
module Asn
( Asn(..)
, encode
, decode
) where
import Data.Text (Text)
import Data.Primitive.Types (Prim)
import Data.Word (Word32)
import Data.Hashable (Hashable)
import Foreign.Storable (Storable)
import qualified Data.Aeson as AE
import qualified Data.Scientific as SCI
import qualified Data.Text as T
import qualified Data.Text.Read as TR
newtype Asn = Asn { getAsn :: Word32 }
deriving (Show,Read,Eq,Ord,Prim,Hashable,Storable)
instance AE.ToJSON Asn where
toJSON = AE.String . encode
instance AE.FromJSON Asn where
parseJSON v = case v of
AE.Object _ -> fail "expected ASN (String or Number), encountered Object"
AE.Array _ -> fail "expected ASN (String or Number), encountered Array"
AE.String t -> case decode t of
Nothing -> fail "ASN string was invalid"
Just w -> return w
AE.Number n -> case SCI.toBoundedInteger n of
Nothing -> fail "numeric ASN was invalid"
Just w -> return (Asn w)
AE.Bool _ -> fail "expected ASN (String or Number), encountered Bool"
AE.Null -> fail "expected ASN (String or Number), encountered Null"
encode :: Asn -> Text
encode (Asn w) = T.pack (show w)
decode :: Text -> Maybe Asn
decode t
| T.take 2 t == "AS" = decodeAsnDigits (T.drop 2 t)
| otherwise = decodeAsnDigits t
decodeAsnDigits :: Text -> Maybe Asn
decodeAsnDigits t = case TR.decimal t of
Left _ -> Nothing
Right (w,extra) -> if T.null extra
then Just (Asn w)
else Nothing