1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use std::sync::Arc;

use async_trait::async_trait;
use chrono::{DateTime, Utc};
use tokio::sync::RwLock;
use uuid::Uuid;

use crate::{prelude::BaseError, unit_of_work::Executor};

#[derive(Debug, Clone)]
pub struct OutBox {
	pub id: Uuid,
	pub aggregate_id: String,
	pub topic: String,
	pub state: String,
	pub processed: bool,
	pub create_dt: DateTime<Utc>,
}

impl OutBox {
	pub fn new(aggregate_id: String, topic: String, state: String) -> Self {
		Self {
			id: Uuid::new_v4(),
			aggregate_id,
			topic,
			state,
			processed: false,
			create_dt: Default::default(),
		}
	}
	// fn convert_event(&self) -> Box<dyn Message> {
	// 	// convert event. it takes outbox reference and target type that is to be deserialized.
	// 	// you can insert any number of desired type as long as it is outboxable type.
	// 	convert_event!(self,)
	// }
	pub fn tag_processed(&mut self) {
		self.processed = true
	}

	pub fn id(&self) -> Uuid {
		self.id
	}
	pub fn aggregate_id(&self) -> &str {
		&self.aggregate_id
	}
	pub fn topic(&self) -> &str {
		&self.topic
	}
	pub fn state(&self) -> &str {
		&self.state
	}
	pub fn processed(&self) -> bool {
		self.processed
	}
	pub fn create_dt(&self) -> DateTime<Utc> {
		self.create_dt
	}
}

#[async_trait]
pub trait IOutBox<E: Executor> {
	fn new(aggregate_id: String, topic: String, state: String) -> Self;
	async fn add(executor: Arc<RwLock<E>>, outboxes: Vec<OutBox>) -> Result<(), BaseError>;
	async fn get(executor: Arc<RwLock<E>>) -> Result<Vec<OutBox>, BaseError>;
	async fn update(&self, executor: Arc<RwLock<E>>) -> Result<(), BaseError>;
}