use crate::event_message::msg::KeriEvent;
use crate::event_message::{EventTypeTag, Typeable};
use crate::prefix::IdentifierPrefix;
use crate::state::IdentifierState;
use said::derivation::HashFunction;
use said::version::format::SerializationFormats;
use serde::{Deserialize, Serialize};
pub mod event_data;
pub mod receipt;
pub mod sections;
use self::event_data::EventData;
use crate::error::Error;
use crate::state::EventSemantics;
use serde_hex::{Compact, SerHex};
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct KeyEvent {
#[serde(rename = "i")]
pub prefix: IdentifierPrefix,
#[serde(rename = "s", with = "SerHex::<Compact>")]
pub sn: u64,
#[serde(flatten)]
pub event_data: EventData,
}
impl KeyEvent {
pub fn new(prefix: IdentifierPrefix, sn: u64, event_data: EventData) -> Self {
KeyEvent {
prefix,
sn,
event_data,
}
}
pub fn to_message(
self,
format: SerializationFormats,
derivation: HashFunction,
) -> Result<KeriEvent<KeyEvent>, Error> {
match (&self.prefix, self.event_data.clone()) {
(IdentifierPrefix::SelfAddressing(_), EventData::Icp(icp)) => {
icp.incept_self_addressing(derivation.clone(), format)
}
(IdentifierPrefix::SelfAddressing(_), EventData::Dip(dip)) => {
dip.incept_self_addressing(derivation.clone(), format)
}
_ => KeriEvent::new(format, derivation, self),
}
}
}
impl Typeable for KeyEvent {
type TypeTag = EventTypeTag;
fn get_type(&self) -> EventTypeTag {
self.event_data.get_type()
}
}
impl EventSemantics for KeyEvent {
fn apply_to(&self, state: IdentifierState) -> Result<IdentifierState, Error> {
match self.event_data {
EventData::Icp(_) | EventData::Dip(_) => {
if state.prefix != IdentifierPrefix::default() {
return Err(Error::EventDuplicateError);
}
if self.sn != 0 {
return Err(Error::SemanticError("SN is not correct".to_string()));
}
}
_ => {
if self.prefix != state.prefix {
return Err(Error::SemanticError("Prefix does not match".to_string()));
} else if self.sn < state.sn + 1 {
return Err(Error::EventDuplicateError);
} else if self.sn > state.sn + 1 {
return Err(Error::EventOutOfOrderError);
}
}
};
self.event_data.apply_to(IdentifierState {
sn: self.sn,
prefix: self.prefix.clone(),
..state
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json;
#[test]
fn ser_der() -> Result<(), serde_json::Error> {
let event_str = "{
\"i\": \"DXq5YqaL6L48pf0fu7IUhL0JRaU2_RxFP0AL43wYn148\",
\"s\": \"0\",
\"t\": \"icp\",
\"kt\": \"2\",
\"k\":
[
\"BWoNZsa88VrTkep6HQt27fTh-4HA8tr54sHON1vWl6FE\",
\"B8tr54sHON1vWVrTkep6H-4HAl6FEQt27fThWoNZsa88\",
\"BVrTkep6HHA8tr54sHON1Qt27fThWoNZsa88-4vWl6FE\"
],
\"nt\": \"3\",
\"n\" :
[
\"ETNZH3ULvYawyZ-i0d8JZU6JR2nmAoAfSVPzhzS6b5CM\",
\"EnmwyZdi0d8JZAoTNZYAfSVPzhzaU6JR2H3ULvS6b5CM\",
\"ETNZH3ULvS6bYAfSVPzhzaU6JR2nmwyZfi0d8JZ5s8bk\"
],
\"bt\": \"2\",
\"b\":
[
\"DVrTkep6H-Qt27fThWoNZsa884HA8tr54sHON1vWl6FE\",
\"DHON1vWl6FEQt27fThWoNZsa88VrTkep6H-4HA8tr54s\",
\"DThWoNZsa88VrTkeQt27fp6H-4HA8tr54sHON1vWl6FE\"
],
\"c\": [],
\"a\": []
}";
let event: KeyEvent = serde_json::from_str(event_str)?;
print!("\n{}\n", serde_json::to_string(&event)?);
Ok(())
}
}