use std::any::Any;
use std::fmt::{Debug, Display};
use std::hash::Hash;
use serde::de::DeserializeOwned;
use serde::Serialize;
use crate::algebra::signature::Signature;
use crate::algebra::Matcher;
use crate::claims::{Claim, SecurityViolationPolicy};
use crate::codec::Codec;
use crate::error::Error;
use crate::trace::{Knowledge, Source, Trace};
pub trait AsAny {
fn as_any(&self) -> &dyn Any;
}
impl<T: 'static> AsAny for T {
fn as_any(&self) -> &dyn Any {
self
}
}
pub trait EvaluatedTerm<PT: ProtocolTypes>: std::fmt::Debug + AsAny {
fn extract_knowledge<'a>(
&'a self,
knowledges: &mut Vec<Knowledge<'a, PT>>,
matcher: Option<PT::Matcher>,
source: &'a Source,
) -> Result<(), Error>;
}
#[macro_export]
macro_rules! dummy_extract_knowledge {
($protocol_type:ty, $extract_type:ty) => {
impl EvaluatedTerm<$protocol_type> for $extract_type {
fn extract_knowledge<'a>(
&'a self,
_knowledges: &mut Vec<Knowledge<'a, $protocol_type>>,
_matcher: Option<<$protocol_type as ProtocolTypes>::Matcher>,
_source: &'a Source,
) -> Result<(), Error> {
Ok(())
}
}
};
}
#[macro_export]
macro_rules! atom_extract_knowledge {
($protocol_type:ty, $extract_type:ty) => {
impl EvaluatedTerm<$protocol_type> for $extract_type {
fn extract_knowledge<'a>(
&'a self,
knowledges: &mut Vec<Knowledge<'a, $protocol_type>>,
matcher: Option<<$protocol_type as ProtocolTypes>::Matcher>,
source: &'a Source,
) -> Result<(), Error> {
knowledges.push(Knowledge {
source,
matcher,
data: self,
});
Ok(())
}
}
};
}
pub trait ProtocolMessageFlight<
PT: ProtocolTypes,
M: ProtocolMessage<PT, O>,
O: OpaqueProtocolMessage<PT>,
OF: OpaqueProtocolMessageFlight<PT, O>,
>: Clone + Debug + From<M> + TryFrom<OF> + Into<OF> + EvaluatedTerm<PT>
{
fn new() -> Self;
fn push(&mut self, msg: M);
fn debug(&self, info: &str);
}
pub trait OpaqueProtocolMessageFlight<PT: ProtocolTypes, O: OpaqueProtocolMessage<PT>>:
Clone + Debug + Codec + From<O> + EvaluatedTerm<PT>
{
fn new() -> Self;
fn debug(&self, info: &str);
fn push(&mut self, msg: O);
}
pub trait ProtocolMessage<PT: ProtocolTypes, O: OpaqueProtocolMessage<PT>>:
Clone + Debug + EvaluatedTerm<PT>
{
fn create_opaque(&self) -> O;
fn debug(&self, info: &str);
}
pub trait OpaqueProtocolMessage<PT: ProtocolTypes>:
Clone + Debug + Codec + EvaluatedTerm<PT>
{
fn debug(&self, info: &str);
}
pub trait ProtocolMessageDeframer<PT: ProtocolTypes> {
type OpaqueProtocolMessage: OpaqueProtocolMessage<PT>;
fn pop_frame(&mut self) -> Option<Self::OpaqueProtocolMessage>;
fn read(&mut self, rd: &mut dyn std::io::Read) -> std::io::Result<usize>;
}
pub trait ProtocolTypes:
'static + Clone + Hash + Display + Debug + Serialize + DeserializeOwned
{
type Matcher: Matcher;
fn signature() -> &'static Signature<Self>;
}
pub trait ProtocolBehavior: 'static {
type ProtocolTypes: ProtocolTypes;
type Claim: Claim<Self::ProtocolTypes>;
type SecurityViolationPolicy: SecurityViolationPolicy<Self::ProtocolTypes, Self::Claim>;
type ProtocolMessage: ProtocolMessage<Self::ProtocolTypes, Self::OpaqueProtocolMessage>;
type OpaqueProtocolMessage: OpaqueProtocolMessage<Self::ProtocolTypes>;
type ProtocolMessageFlight: ProtocolMessageFlight<
Self::ProtocolTypes,
Self::ProtocolMessage,
Self::OpaqueProtocolMessage,
Self::OpaqueProtocolMessageFlight,
>;
type OpaqueProtocolMessageFlight: OpaqueProtocolMessageFlight<Self::ProtocolTypes, Self::OpaqueProtocolMessage>
+ From<Self::ProtocolMessageFlight>;
fn create_corpus() -> Vec<(Trace<Self::ProtocolTypes>, &'static str)>;
}