syrup_rail_postgres/
transactions.rs1#![warn(missing_docs)]
2
3use std::{error::Error, fmt, time::Duration};
4
5use async_trait::async_trait;
6use sqlx::PgConnection;
7use syrup_rail::{BillingEvent, BillingEventSubject};
8
9use crate::host_error::{BoxError, RedactedHostErrorSource};
10
11#[derive(Debug)]
13pub struct BillingTransactionError {
14 source: RedactedHostErrorSource,
15}
16
17impl BillingTransactionError {
18 pub fn new(source: impl Error + Send + Sync + 'static) -> Self {
21 Self {
22 source: RedactedHostErrorSource::new(source),
23 }
24 }
25
26 pub fn into_source(self) -> BoxError {
31 self.source.into_inner()
32 }
33}
34
35impl fmt::Display for BillingTransactionError {
36 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
37 formatter.write_str("billing transaction operation failed")
38 }
39}
40
41impl Error for BillingTransactionError {}
42
43#[derive(Debug)]
45pub struct BillingEventWriteError {
46 source: RedactedHostErrorSource,
47}
48
49impl BillingEventWriteError {
50 pub fn new(source: impl Error + Send + Sync + 'static) -> Self {
53 Self {
54 source: RedactedHostErrorSource::new(source),
55 }
56 }
57
58 pub fn into_source(self) -> BoxError {
63 self.source.into_inner()
64 }
65}
66
67impl fmt::Display for BillingEventWriteError {
68 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
69 formatter.write_str("billing event append failed")
70 }
71}
72
73impl Error for BillingEventWriteError {}
74
75#[derive(Clone, Copy, Debug, Eq, PartialEq)]
77pub enum BillingTransactionSubjectState {
78 LiveRecipient,
80 RetainedSubject,
82}
83
84#[async_trait]
87pub trait BillingTransactionCoordinator: Send + Sync {
88 async fn begin(
91 &self,
92 subject: BillingEventSubject,
93 lock_timeout: Duration,
94 ) -> Result<Box<dyn BillingTransaction>, BillingTransactionError>;
95}
96
97#[async_trait]
102pub trait BillingTransaction: Send {
103 fn connection(&mut self) -> &mut PgConnection;
105
106 fn subject_state(&self) -> BillingTransactionSubjectState;
108
109 async fn append_event(&mut self, event: &BillingEvent) -> Result<(), BillingEventWriteError>;
111
112 async fn commit(self: Box<Self>) -> Result<(), BillingTransactionError>;
114
115 async fn rollback(self: Box<Self>) -> Result<(), BillingTransactionError>;
117}