1use crate::{
2 error::Error,
3 event::vc_event::{VCEventMessage, VCEventType},
4};
5use said::SelfAddressingIdentifier;
6use serde::{Deserialize, Serialize};
7
8#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default)]
9pub enum TelState {
10 #[default]
11 NotIssued,
12 Issued(SelfAddressingIdentifier),
13 Revoked,
14}
15
16impl TelState {
17 pub fn apply(&self, event: &VCEventMessage) -> Result<Self, Error> {
18 let event_content = event.data.data.clone();
19 match event_content.event_type {
20 VCEventType::Bis(_iss) => match self {
21 TelState::NotIssued => {
22 if event_content.sn == 0 {
23 Ok(TelState::Issued(event.digest()?))
24 } else {
25 Err(Error::Generic("Wrong sn".into()))
26 }
27 }
28 _ => Err(Error::EventAlreadySavedError),
29 },
30 VCEventType::Brv(rev) => match self {
31 TelState::Issued(last) => {
32 if rev.prev_event_hash.eq(last) && event_content.sn == 1 {
33 Ok(TelState::Revoked)
34 } else {
35 Err(Error::Generic("Previous event doesn't match".to_string()))
36 }
37 }
38 TelState::NotIssued => Err(Error::OutOfOrderError),
39 TelState::Revoked => Err(Error::Generic("Already revoked".into())),
40 },
41 VCEventType::Iss(_iss) => match self {
42 TelState::NotIssued => Ok(TelState::Issued(event.digest()?)),
43 _ => Err(Error::EventAlreadySavedError),
44 },
45 VCEventType::Rev(rev) => match self {
46 TelState::Issued(last) => {
47 if &rev.prev_event_hash == last {
48 Ok(TelState::Revoked)
49 } else {
50 Err(Error::Generic("Previous event doesn't match".to_string()))
51 }
52 }
53 TelState::NotIssued => Err(Error::OutOfOrderError),
54 TelState::Revoked => Err(Error::Generic("Already revoked".into())),
55 },
56 }
57 }
58}
59
60#[test]
61fn test_apply() -> Result<(), Error> {
62 let bis_raw = r#"{"v":"KERI10JSON000162_","t":"bis","d":"EFXbFFjdUNRgg_blTx76RAdcIoRoLtPl5tA3yAw5vS9W","i":"EC8Oej-3HAUpBY_kxzBK3B-0RV9j4dXw1H0NRKxJg7g-","s":"0","ii":"EKKJ0FoLxO1TYmyuprguKO7kJ7Hbn0m0Wuk5aMtSrMtY","ra":{"i":"EIZlA3TANi3p8vEu4VQMjPnY0sPFAag1ekIwyyR6lAsq","s":"0","d":"EFSL6HebpbWsxKxfdS4t6NbKTdO4hAUIAxvhmWVf3Z8o"},"dt":"2023-01-10T10:36:50.842679+00:00"}"#;
63 let bis_ev: VCEventMessage = serde_json::from_str(&bis_raw).unwrap();
64 assert_eq!(serde_json::to_string(&bis_ev).unwrap(), bis_raw);
65
66 let brv_raw = r#"{"v":"KERI10JSON000161_","t":"brv","d":"ENJrZygsUPsqzxjrmgXIjweuQX5I2lXbgcGFn7iEyDyG","i":"EC8Oej-3HAUpBY_kxzBK3B-0RV9j4dXw1H0NRKxJg7g-","s":"1","p":"EFXbFFjdUNRgg_blTx76RAdcIoRoLtPl5tA3yAw5vS9W","ra":{"i":"EIZlA3TANi3p8vEu4VQMjPnY0sPFAag1ekIwyyR6lAsq","s":"0","d":"EFSL6HebpbWsxKxfdS4t6NbKTdO4hAUIAxvhmWVf3Z8o"},"dt":"2023-01-10T10:36:50.843652+00:00"}"#;
67 let brv_ev: VCEventMessage = serde_json::from_str(&brv_raw).unwrap();
68 assert_eq!(serde_json::to_string(&brv_ev).unwrap(), brv_raw);
69
70 let state = TelState::default();
71 let state = state.apply(&bis_ev)?;
72 assert!(matches!(state, TelState::Issued(_)));
73
74 if let TelState::Issued(last) = state.clone() {
75 match brv_ev.data.data.event_type {
76 VCEventType::Brv(ref brv) => assert!(brv.prev_event_hash == last),
77 _ => (),
78 };
79 }
80 let state = state.apply(&brv_ev)?;
81 assert_eq!(state, TelState::Revoked);
82
83 let state = state.apply(&brv_ev);
84 assert!(state.is_err());
85
86 Ok(())
87}