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