use chrono::{DateTime, Local};
use serde::{ser::SerializeStruct, Deserialize, Serialize};
use std::cmp::Ordering;
use super::EventMessage;
use super::{serializer::to_string, KeyEvent};
use crate::{
error::Error,
event::{
receipt::Receipt,
sections::seal::{EventSeal, SourceSeal},
},
event_parsing::Attachment,
prefix::{AttachedSignaturePrefix, BasicPrefix, SelfSigningPrefix},
state::{EventSemantics, IdentifierState},
};
#[cfg(feature = "query")]
use crate::query::{query::SignedQuery, reply::SignedReply};
#[derive(Clone, Debug, PartialEq)]
pub enum Message {
Event(Box<SignedEventMessage>),
NontransferableRct(SignedNontransferableReceipt),
TransferableRct(Box<SignedTransferableReceipt>),
#[cfg(feature = "query")]
KeyStateNotice(SignedReply),
#[cfg(feature = "query")]
Query(SignedQuery),
}
#[derive(Debug, Clone, Deserialize)]
pub struct SignedEventMessage {
pub event_message: EventMessage<KeyEvent>,
#[serde(skip_serializing)]
pub signatures: Vec<AttachedSignaturePrefix>,
#[serde(skip_serializing)]
pub delegator_seal: Option<SourceSeal>,
}
impl Serialize for SignedEventMessage {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if serializer.is_human_readable() {
let mut em = serializer.serialize_struct("EventMessage", 2)?;
em.serialize_field("", &self.event_message)?;
let att_sigs = Attachment::AttachedSignatures(self.signatures.clone());
em.serialize_field("-", &att_sigs.to_cesr())?;
em.end()
} else {
let mut em = serializer.serialize_struct("SignedEventMessage", 2)?;
em.serialize_field("event_message", &self.event_message)?;
em.serialize_field("signatures", &self.signatures)?;
em.end()
}
}
}
impl PartialEq for SignedEventMessage {
fn eq(&self, other: &Self) -> bool {
self.event_message == other.event_message && self.signatures == other.signatures
}
}
#[derive(Serialize, Deserialize)]
pub struct TimestampedSignedEventMessage {
pub timestamp: DateTime<Local>,
pub signed_event_message: SignedEventMessage,
}
impl TimestampedSignedEventMessage {
pub fn new(event: SignedEventMessage) -> Self {
Self {
timestamp: Local::now(),
signed_event_message: event,
}
}
}
impl From<TimestampedSignedEventMessage> for SignedEventMessage {
fn from(event: TimestampedSignedEventMessage) -> SignedEventMessage {
event.signed_event_message
}
}
impl From<SignedEventMessage> for TimestampedSignedEventMessage {
fn from(event: SignedEventMessage) -> TimestampedSignedEventMessage {
TimestampedSignedEventMessage::new(event)
}
}
impl From<&SignedEventMessage> for TimestampedSignedEventMessage {
fn from(event: &SignedEventMessage) -> TimestampedSignedEventMessage {
TimestampedSignedEventMessage::new(event.clone())
}
}
impl PartialEq for TimestampedSignedEventMessage {
fn eq(&self, other: &Self) -> bool {
self.signed_event_message == other.signed_event_message
}
}
impl PartialOrd for TimestampedSignedEventMessage {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(
match self.signed_event_message.event_message.event.get_sn()
== other.signed_event_message.event_message.event.get_sn()
{
true => Ordering::Equal,
false => {
match self.signed_event_message.event_message.event.get_sn()
> other.signed_event_message.event_message.event.get_sn()
{
true => Ordering::Greater,
false => Ordering::Less,
}
}
},
)
}
}
impl Ord for TimestampedSignedEventMessage {
fn cmp(&self, other: &Self) -> Ordering {
match self.signed_event_message.event_message.event.get_sn()
== other.signed_event_message.event_message.event.get_sn()
{
true => Ordering::Equal,
false => match self.signed_event_message.event_message.event.get_sn()
> other.signed_event_message.event_message.event.get_sn()
{
true => Ordering::Greater,
false => Ordering::Less,
},
}
}
}
impl Eq for TimestampedSignedEventMessage {}
impl SignedEventMessage {
pub fn new(
message: &EventMessage<KeyEvent>,
sigs: Vec<AttachedSignaturePrefix>,
delegator_seal: Option<SourceSeal>,
) -> Self {
Self {
event_message: message.clone(),
signatures: sigs,
delegator_seal,
}
}
pub fn serialize(&self) -> Result<Vec<u8>, Error> {
Ok(to_string(&self)?.as_bytes().to_vec())
}
}
impl EventSemantics for SignedEventMessage {
fn apply_to(&self, state: IdentifierState) -> Result<IdentifierState, Error> {
self.event_message.apply_to(state)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct SignedTransferableReceipt {
pub body: EventMessage<Receipt>,
pub validator_seal: EventSeal,
pub signatures: Vec<AttachedSignaturePrefix>,
}
impl SignedTransferableReceipt {
pub fn new(
message: EventMessage<Receipt>,
event_seal: EventSeal,
sigs: Vec<AttachedSignaturePrefix>,
) -> Self {
Self {
body: message,
validator_seal: event_seal,
signatures: sigs,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct SignedNontransferableReceipt {
pub body: EventMessage<Receipt>,
pub couplets: Vec<(BasicPrefix, SelfSigningPrefix)>,
}
impl SignedNontransferableReceipt {
pub fn new(
message: &EventMessage<Receipt>,
couplets: Vec<(BasicPrefix, SelfSigningPrefix)>,
) -> Self {
Self {
body: message.clone(),
couplets,
}
}
}