{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE DerivingStrategies         #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

module Ouroboros.Network.Protocol.ObjectDiffusion.Codec.CDDL
  ( objectDiffusionCodec
  , ObjectId
  , Object
  ) where

import Codec.CBOR.Read qualified as CBOR
import Codec.Serialise (Serialise)
import Codec.Serialise.Class qualified as Serialise
import Control.DeepSeq (NFData)
import Data.ByteString.Lazy qualified as BL
import GHC.Generics (Generic)
import Network.TypedProtocol.Codec
import Ouroboros.Network.Protocol.ObjectDiffusion.Codec
import Ouroboros.Network.Protocol.ObjectDiffusion.Type
import Ouroboros.Network.Util.ShowProxy (ShowProxy (..))
import Test.Data.CDDL (Any (..))
import Test.QuickCheck (Arbitrary)

-- | Simple wrapper around 'Any' matching @objectId = any@ in the CDDL spec.
-- This is intentionally different from the 'ObjectId' in
-- 'ObjectDiffusion.Test' which wraps @Maybe Word64@ for the caught-up sentinel.
--
newtype ObjectId = ObjectId Any
  deriving (ObjectId -> ObjectId -> Bool
(ObjectId -> ObjectId -> Bool)
-> (ObjectId -> ObjectId -> Bool) -> Eq ObjectId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ObjectId -> ObjectId -> Bool
== :: ObjectId -> ObjectId -> Bool
$c/= :: ObjectId -> ObjectId -> Bool
/= :: ObjectId -> ObjectId -> Bool
Eq, Eq ObjectId
Eq ObjectId =>
(ObjectId -> ObjectId -> Ordering)
-> (ObjectId -> ObjectId -> Bool)
-> (ObjectId -> ObjectId -> Bool)
-> (ObjectId -> ObjectId -> Bool)
-> (ObjectId -> ObjectId -> Bool)
-> (ObjectId -> ObjectId -> ObjectId)
-> (ObjectId -> ObjectId -> ObjectId)
-> Ord ObjectId
ObjectId -> ObjectId -> Bool
ObjectId -> ObjectId -> Ordering
ObjectId -> ObjectId -> ObjectId
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
$ccompare :: ObjectId -> ObjectId -> Ordering
compare :: ObjectId -> ObjectId -> Ordering
$c< :: ObjectId -> ObjectId -> Bool
< :: ObjectId -> ObjectId -> Bool
$c<= :: ObjectId -> ObjectId -> Bool
<= :: ObjectId -> ObjectId -> Bool
$c> :: ObjectId -> ObjectId -> Bool
> :: ObjectId -> ObjectId -> Bool
$c>= :: ObjectId -> ObjectId -> Bool
>= :: ObjectId -> ObjectId -> Bool
$cmax :: ObjectId -> ObjectId -> ObjectId
max :: ObjectId -> ObjectId -> ObjectId
$cmin :: ObjectId -> ObjectId -> ObjectId
min :: ObjectId -> ObjectId -> ObjectId
Ord, Int -> ObjectId -> ShowS
[ObjectId] -> ShowS
ObjectId -> String
(Int -> ObjectId -> ShowS)
-> (ObjectId -> String) -> ([ObjectId] -> ShowS) -> Show ObjectId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ObjectId -> ShowS
showsPrec :: Int -> ObjectId -> ShowS
$cshow :: ObjectId -> String
show :: ObjectId -> String
$cshowList :: [ObjectId] -> ShowS
showList :: [ObjectId] -> ShowS
Show, Gen ObjectId
Gen ObjectId -> (ObjectId -> [ObjectId]) -> Arbitrary ObjectId
ObjectId -> [ObjectId]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen ObjectId
arbitrary :: Gen ObjectId
$cshrink :: ObjectId -> [ObjectId]
shrink :: ObjectId -> [ObjectId]
Arbitrary, [ObjectId] -> Encoding
ObjectId -> Encoding
(ObjectId -> Encoding)
-> (forall s. Decoder s ObjectId)
-> ([ObjectId] -> Encoding)
-> (forall s. Decoder s [ObjectId])
-> Serialise ObjectId
forall s. Decoder s [ObjectId]
forall s. Decoder s ObjectId
forall a.
(a -> Encoding)
-> (forall s. Decoder s a)
-> ([a] -> Encoding)
-> (forall s. Decoder s [a])
-> Serialise a
$cencode :: ObjectId -> Encoding
encode :: ObjectId -> Encoding
$cdecode :: forall s. Decoder s ObjectId
decode :: forall s. Decoder s ObjectId
$cencodeList :: [ObjectId] -> Encoding
encodeList :: [ObjectId] -> Encoding
$cdecodeList :: forall s. Decoder s [ObjectId]
decodeList :: forall s. Decoder s [ObjectId]
Serialise, (forall x. ObjectId -> Rep ObjectId x)
-> (forall x. Rep ObjectId x -> ObjectId) -> Generic ObjectId
forall x. Rep ObjectId x -> ObjectId
forall x. ObjectId -> Rep ObjectId x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ObjectId -> Rep ObjectId x
from :: forall x. ObjectId -> Rep ObjectId x
$cto :: forall x. Rep ObjectId x -> ObjectId
to :: forall x. Rep ObjectId x -> ObjectId
Generic, ObjectId -> ()
(ObjectId -> ()) -> NFData ObjectId
forall a. (a -> ()) -> NFData a
$crnf :: ObjectId -> ()
rnf :: ObjectId -> ()
NFData)

instance ShowProxy ObjectId where
    showProxy :: Proxy ObjectId -> String
showProxy Proxy ObjectId
_ = String
"ObjectId"

-- | Simple wrapper around 'Any' matching @object = any@ in the CDDL spec.
--
newtype Object = Object Any
  deriving (Object -> Object -> Bool
(Object -> Object -> Bool)
-> (Object -> Object -> Bool) -> Eq Object
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Object -> Object -> Bool
== :: Object -> Object -> Bool
$c/= :: Object -> Object -> Bool
/= :: Object -> Object -> Bool
Eq, Int -> Object -> ShowS
[Object] -> ShowS
Object -> String
(Int -> Object -> ShowS)
-> (Object -> String) -> ([Object] -> ShowS) -> Show Object
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Object -> ShowS
showsPrec :: Int -> Object -> ShowS
$cshow :: Object -> String
show :: Object -> String
$cshowList :: [Object] -> ShowS
showList :: [Object] -> ShowS
Show, Gen Object
Gen Object -> (Object -> [Object]) -> Arbitrary Object
Object -> [Object]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen Object
arbitrary :: Gen Object
$cshrink :: Object -> [Object]
shrink :: Object -> [Object]
Arbitrary, [Object] -> Encoding
Object -> Encoding
(Object -> Encoding)
-> (forall s. Decoder s Object)
-> ([Object] -> Encoding)
-> (forall s. Decoder s [Object])
-> Serialise Object
forall s. Decoder s [Object]
forall s. Decoder s Object
forall a.
(a -> Encoding)
-> (forall s. Decoder s a)
-> ([a] -> Encoding)
-> (forall s. Decoder s [a])
-> Serialise a
$cencode :: Object -> Encoding
encode :: Object -> Encoding
$cdecode :: forall s. Decoder s Object
decode :: forall s. Decoder s Object
$cencodeList :: [Object] -> Encoding
encodeList :: [Object] -> Encoding
$cdecodeList :: forall s. Decoder s [Object]
decodeList :: forall s. Decoder s [Object]
Serialise, (forall x. Object -> Rep Object x)
-> (forall x. Rep Object x -> Object) -> Generic Object
forall x. Rep Object x -> Object
forall x. Object -> Rep Object x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Object -> Rep Object x
from :: forall x. Object -> Rep Object x
$cto :: forall x. Rep Object x -> Object
to :: forall x. Rep Object x -> Object
Generic, Object -> ()
(Object -> ()) -> NFData Object
forall a. (a -> ()) -> NFData a
$crnf :: Object -> ()
rnf :: Object -> ()
NFData)

instance ShowProxy Object where
    showProxy :: Proxy Object -> String
showProxy Proxy Object
_ = String
"Object"

objectDiffusionCodec :: Codec (ObjectDiffusion ObjectId Object)
                            CBOR.DeserialiseFailure IO BL.ByteString
objectDiffusionCodec :: Codec
  (ObjectDiffusion ObjectId Object) DeserialiseFailure IO ByteString
objectDiffusionCodec =
    (ObjectId -> Encoding)
-> (forall s. Decoder s ObjectId)
-> (Object -> Encoding)
-> (forall s. Decoder s Object)
-> Codec
     (ObjectDiffusion ObjectId Object) DeserialiseFailure IO ByteString
forall objectId object (m :: * -> *).
MonadST m =>
(objectId -> Encoding)
-> (forall s. Decoder s objectId)
-> (object -> Encoding)
-> (forall s. Decoder s object)
-> Codec
     (ObjectDiffusion objectId object) DeserialiseFailure m ByteString
codecObjectDiffusion
      ObjectId -> Encoding
forall a. Serialise a => a -> Encoding
Serialise.encode
      Decoder s ObjectId
forall s. Decoder s ObjectId
forall a s. Serialise a => Decoder s a
Serialise.decode
      Object -> Encoding
forall a. Serialise a => a -> Encoding
Serialise.encode
      Decoder s Object
forall s. Decoder s Object
forall a s. Serialise a => Decoder s a
Serialise.decode