{-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} module Network.IPv6DB.Types where import Data.Aeson as A import qualified Data.Text as T import qualified Data.Vector as V import Text.IPv6Addr newtype Addresses = Addresses [IPv6Addr] instance FromJSON Addresses where parseJSON :: Value -> Parser Addresses parseJSON (Array Array v) = do let rslts :: [Result IPv6Addr] rslts = forall a. FromJSON a => Value -> Result a fromJSON forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall a. Vector a -> [a] V.toList Array v if forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool all forall a. Result a -> Bool isSuccess [Result IPv6Addr] rslts then forall (f :: * -> *) a. Applicative f => a -> f a pure ([IPv6Addr] -> Addresses Addresses forall a b. (a -> b) -> a -> b $ forall a. Result a -> a fromSuccess forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [Result IPv6Addr] rslts) else forall (m :: * -> *) a. MonadFail m => String -> m a fail String "Bad JSON Array Of IPv6 Addresses" parseJSON Value _ = forall (m :: * -> *) a. MonadFail m => String -> m a fail String "JSON Array Expected" data Entry = Entry { Entry -> Text list :: !T.Text , Entry -> IPv6Addr address :: IPv6Addr } deriving (Entry -> Entry -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Entry -> Entry -> Bool $c/= :: Entry -> Entry -> Bool == :: Entry -> Entry -> Bool $c== :: Entry -> Entry -> Bool Eq, Int -> Entry -> ShowS [Entry] -> ShowS Entry -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [Entry] -> ShowS $cshowList :: [Entry] -> ShowS show :: Entry -> String $cshow :: Entry -> String showsPrec :: Int -> Entry -> ShowS $cshowsPrec :: Int -> Entry -> ShowS Show) instance FromJSON Entry where parseJSON :: Value -> Parser Entry parseJSON (Object Object o) = do Text list <- Object o forall a. FromJSON a => Object -> Key -> Parser a .: Key "list" IPv6Addr address <- Object o forall a. FromJSON a => Object -> Key -> Parser a .: Key "address" forall (f :: * -> *) a. Applicative f => a -> f a pure Entry{Text IPv6Addr address :: IPv6Addr list :: Text $sel:address:Entry :: IPv6Addr $sel:list:Entry :: Text ..} parseJSON Value _ = forall (m :: * -> *) a. MonadFail m => String -> m a fail String "JSON Object Expected" newtype Entries = Entries [Entry] instance FromJSON Entries where parseJSON :: Value -> Parser Entries parseJSON (Array Array v) = do let ents :: [Result Entry] ents = forall a. FromJSON a => Value -> Result a fromJSON forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall a. Vector a -> [a] V.toList Array v if forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool all forall a. Result a -> Bool isSuccess [Result Entry] ents then forall (f :: * -> *) a. Applicative f => a -> f a pure ([Entry] -> Entries Entries forall a b. (a -> b) -> a -> b $ forall a. Result a -> a fromSuccess forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [Result Entry] ents) else forall (m :: * -> *) a. MonadFail m => String -> m a fail String "Malformed JSON Array" parseJSON Value _ = forall (m :: * -> *) a. MonadFail m => String -> m a fail String "JSON Array Expected" newtype Source = Source Value deriving (Source -> Source -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Source -> Source -> Bool $c/= :: Source -> Source -> Bool == :: Source -> Source -> Bool $c== :: Source -> Source -> Bool Eq, Int -> Source -> ShowS [Source] -> ShowS Source -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [Source] -> ShowS $cshowList :: [Source] -> ShowS show :: Source -> String $cshow :: Source -> String showsPrec :: Int -> Source -> ShowS $cshowsPrec :: Int -> Source -> ShowS Show) instance ToJSON Source where toJSON :: Source -> Value toJSON (Source Value v) = Value v instance FromJSON Source where parseJSON :: Value -> Parser Source parseJSON Value v = forall (f :: * -> *) a. Applicative f => a -> f a pure (Value -> Source Source Value v) data Resource = Resource { Resource -> Text list :: !T.Text , Resource -> IPv6Addr address :: !IPv6Addr , Resource -> Maybe Integer ttl :: !(Maybe Integer) , Resource -> Source source :: !Source } | ResourceError { list :: !T.Text , address :: !IPv6Addr , Resource -> Text error :: !T.Text } deriving (Resource -> Resource -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Resource -> Resource -> Bool $c/= :: Resource -> Resource -> Bool == :: Resource -> Resource -> Bool $c== :: Resource -> Resource -> Bool Eq, Int -> Resource -> ShowS [Resource] -> ShowS Resource -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [Resource] -> ShowS $cshowList :: [Resource] -> ShowS show :: Resource -> String $cshow :: Resource -> String showsPrec :: Int -> Resource -> ShowS $cshowsPrec :: Int -> Resource -> ShowS Show) instance ToJSON Resource where toJSON :: Resource -> Value toJSON Resource{Maybe Integer Text IPv6Addr Source source :: Source ttl :: Maybe Integer address :: IPv6Addr list :: Text $sel:source:Resource :: Resource -> Source $sel:ttl:Resource :: Resource -> Maybe Integer $sel:address:Resource :: Resource -> IPv6Addr $sel:list:Resource :: Resource -> Text ..} = [Pair] -> Value object [ Key "list" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv .= Text list , Key "address" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv .= IPv6Addr address , Key "ttl" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv .= Maybe Integer ttl , Key "source" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv .= Source source ] toJSON ResourceError{$sel:error:Resource :: Resource -> Text error=Text err, Text IPv6Addr address :: IPv6Addr list :: Text $sel:address:Resource :: Resource -> IPv6Addr $sel:list:Resource :: Resource -> Text ..} = [Pair] -> Value object [ Key "list" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv .= Text list , Key "address" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv .= IPv6Addr address , Key "error" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv .= Text err ] instance FromJSON Resource where parseJSON :: Value -> Parser Resource parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a withObject String "resource" forall a b. (a -> b) -> a -> b $ \Object o -> do Text list <- Object o forall a. FromJSON a => Object -> Key -> Parser a .: Key "list" IPv6Addr address <- do Text ma <- Object o forall a. FromJSON a => Object -> Key -> Parser a .: Key "address" case Text -> Maybe IPv6Addr maybeIPv6Addr Text ma of Just IPv6Addr a -> forall (f :: * -> *) a. Applicative f => a -> f a pure IPv6Addr a Maybe IPv6Addr Nothing -> forall (m :: * -> *) a. MonadFail m => String -> m a fail String "Not an IPv6 Address" Maybe Integer ttl <- Object o forall a. FromJSON a => Object -> Key -> Parser (Maybe a) .:? Key "ttl" Source source <- Object o forall a. FromJSON a => Object -> Key -> Parser a .: Key "source" forall (m :: * -> *) a. Monad m => a -> m a return Resource{Maybe Integer Text IPv6Addr Source source :: Source ttl :: Maybe Integer address :: IPv6Addr list :: Text $sel:source:Resource :: Source $sel:ttl:Resource :: Maybe Integer $sel:address:Resource :: IPv6Addr $sel:list:Resource :: Text ..} newtype Resources = Resources [Resource] deriving (Resources -> Resources -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Resources -> Resources -> Bool $c/= :: Resources -> Resources -> Bool == :: Resources -> Resources -> Bool $c== :: Resources -> Resources -> Bool Eq, Int -> Resources -> ShowS [Resources] -> ShowS Resources -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [Resources] -> ShowS $cshowList :: [Resources] -> ShowS show :: Resources -> String $cshow :: Resources -> String showsPrec :: Int -> Resources -> ShowS $cshowsPrec :: Int -> Resources -> ShowS Show) instance ToJSON Resources where toJSON :: Resources -> Value toJSON (Resources [Resource] rs) = [Pair] -> Value object [ (Key "resources", Array -> Value Array (forall a. [a] -> Vector a V.fromList forall a b. (a -> b) -> a -> b $ forall a. ToJSON a => a -> Value toJSON forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [Resource] rs)) ] instance FromJSON Resources where parseJSON :: Value -> Parser Resources parseJSON (Array Array v) = do let rsrcs :: [Result Resource] rsrcs = forall a. FromJSON a => Value -> Result a fromJSON forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall a. Vector a -> [a] V.toList Array v if forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool all forall a. Result a -> Bool isSuccess [Result Resource] rsrcs then forall (f :: * -> *) a. Applicative f => a -> f a pure ([Resource] -> Resources Resources forall a b. (a -> b) -> a -> b $ forall a. Result a -> a fromSuccess forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [Result Resource] rsrcs) else forall (m :: * -> *) a. MonadFail m => String -> m a fail String "Malformed JSON Array Of Resources" parseJSON Value _ = forall (m :: * -> *) a. MonadFail m => String -> m a fail String "JSON Array Expected" isSuccess :: Result a -> Bool isSuccess :: forall a. Result a -> Bool isSuccess (A.Success a _) = Bool True isSuccess (A.Error String _) = Bool False fromSuccess :: Result a -> a fromSuccess :: forall a. Result a -> a fromSuccess (A.Success a e) = a e fromSuccess (A.Error String _) = forall a. HasCallStack => String -> a Prelude.error String "Success value only"