use crate::{transaction::Error, RevId, Status, TxId}; use chrono::{serde::ts_milliseconds, DateTime, Utc}; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; #[derive(Debug, Clone, Deserialize, Serialize, borsh::BorshSerialize, borsh::BorshDeserialize)] /// A transaction revision pub struct Revision { #[serde(rename = "_id")] /// TransactionId pub transaction_id: TxId, /// Previous revision or None if this is the first revision #[serde(rename = "_prev_rev", skip_serializing_if = "Option::is_none")] pub previous: Option, /// A human-readable changelog for this revision pub changelog: String, /// Vector of tags associated with a transaction pub tags: Vec, /// Transaction status pub status: Status, #[serde(rename = "updated_at", with = "ts_milliseconds")] #[borsh( serialize_with = "super::to_ts_microseconds", deserialize_with = "super::from_ts_microseconds" )] /// Timestamp when this revision has been created pub created_at: DateTime, } impl Revision { /// Creates a new revision pub fn new( transaction_id: TxId, previous: Option, changelog: String, tags: Vec, status: Status, ) -> Self { Self { transaction_id, previous, changelog, tags, status, created_at: Utc::now(), } } /// Calculates the ID of the inner revision pub fn rev_id(&self) -> Result { let mut hasher = Sha256::new(); let bytes = borsh::to_vec(self)?; hasher.update(&bytes); Ok(RevId::new(hasher.finalize().into())) } /// Returns the transaction ID pub fn transaction_id(&self) -> &TxId { &self.transaction_id } /// Returns the revision ID pub fn previous_revision_id(&self) -> Option<&RevId> { self.previous.as_ref() } }