revision.rs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. use crate::{transaction::Error, RevId, Status, TxId};
  2. use chrono::{serde::ts_milliseconds, DateTime, Utc};
  3. use serde::{Deserialize, Serialize};
  4. use sha2::{Digest, Sha256};
  5. #[derive(Debug, Clone, Deserialize, Serialize, borsh::BorshSerialize, borsh::BorshDeserialize)]
  6. /// A transaction revision
  7. pub struct Revision {
  8. #[serde(rename = "_id")]
  9. /// TransactionId
  10. pub transaction_id: TxId,
  11. /// Previous revision or None if this is the first revision
  12. #[serde(rename = "_prev_rev", skip_serializing_if = "Option::is_none")]
  13. pub previous: Option<RevId>,
  14. /// A human-readable changelog for this revision
  15. pub changelog: String,
  16. /// Vector of tags associated with a transaction
  17. pub tags: Vec<String>,
  18. /// Transaction status
  19. pub status: Status,
  20. #[serde(rename = "updated_at", with = "ts_milliseconds")]
  21. #[borsh(
  22. serialize_with = "super::to_ts_microseconds",
  23. deserialize_with = "super::from_ts_microseconds"
  24. )]
  25. /// Timestamp when this revision has been created
  26. pub created_at: DateTime<Utc>,
  27. }
  28. impl Revision {
  29. /// Creates a new revision
  30. pub fn new(
  31. transaction_id: TxId,
  32. previous: Option<RevId>,
  33. changelog: String,
  34. tags: Vec<String>,
  35. status: Status,
  36. ) -> Self {
  37. Self {
  38. transaction_id,
  39. previous,
  40. changelog,
  41. tags,
  42. status,
  43. created_at: Utc::now(),
  44. }
  45. }
  46. /// Calculates the ID of the inner revision
  47. pub fn rev_id(&self) -> Result<RevId, Error> {
  48. let mut hasher = Sha256::new();
  49. let bytes = borsh::to_vec(self)?;
  50. hasher.update(&bytes);
  51. Ok(RevId::new(hasher.finalize().into()))
  52. }
  53. /// Returns the transaction ID
  54. pub fn transaction_id(&self) -> &TxId {
  55. &self.transaction_id
  56. }
  57. /// Returns the revision ID
  58. pub fn previous_revision_id(&self) -> Option<&RevId> {
  59. self.previous.as_ref()
  60. }
  61. }