packages feed

hOpenPGP-3.3: Data/Conduit/OpenPGP/Filter.hs

-- Filter.hs: OpenPGP (RFC4880) packet filtering
-- Copyright © 2014-2026  Clint Adams
-- This software is released under the terms of the Expat license.
-- (See the LICENSE file).
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Data.Conduit.OpenPGP.Filter
    ( conduitPktFilter
    , conduitPktWithExtraFilter
    , FilterPredicates (..)
    , runPredicate
    ) where

import Control.Monad.Trans.Reader (Reader, runReader)
import Data.Conduit (ConduitT)
import qualified Data.Conduit.List as CL
import Data.Typeable (Typeable)
import Data.Void (Void)

import Codec.Encryption.OpenPGP.Types

data FilterPredicates r a
    = -- | fp for context-less packets
      RPFilterPredicate (Reader Pkt Bool)
    | -- | generic filter predicate
      RFilterPredicate (Reader a Bool)
    | -- | generic filter predicate with additional context
      RPairFilterPredicate (Reader (r, a) Bool)

runPredicate
    :: forall r a. Typeable a => FilterPredicates r a -> a -> Bool
runPredicate (RFilterPredicate e) = runReader e
runPredicate _ = const False

conduitPktFilter
    :: Monad m => FilterPredicates Void Pkt -> ConduitT Pkt Pkt m ()
conduitPktFilter = CL.filter . superPredicate

superPredicate :: FilterPredicates Void Pkt -> Pkt -> Bool
superPredicate (RPFilterPredicate e) p = runReader e p
superPredicate (RFilterPredicate e) p = runReader e p
superPredicate _ _ = False -- do not match incorrect type of packet

conduitPktWithExtraFilter
    :: Monad m => r -> FilterPredicates r Pkt -> ConduitT Pkt Pkt m ()
conduitPktWithExtraFilter extra = CL.filter . superPairPredicate extra

superPairPredicate :: r -> FilterPredicates r a -> a -> Bool
superPairPredicate r (RPairFilterPredicate e) p = runReader e (r, p)