use std::sync::Arc;
use uuid::Uuid;
use crate::entities::client::ClientId;
#[derive(Clone, Debug)]
pub struct RequestContext {
pub tx: Arc<str>,
pub client_id: Option<ClientId>,
pub lineage: Vec<Arc<str>>,
pub host_id: Uuid,
pub created_at: String,
pub windback: Option<Arc<str>>,
}
impl RequestContext {
pub fn new(
tx: Arc<str>,
client_id: Option<Arc<str>>,
lineage: Vec<Arc<str>>,
host_id: Uuid,
created_at: String,
) -> Self {
Self {
tx,
client_id: client_id.map(Into::into),
lineage,
host_id,
created_at,
windback: None,
}
}
pub fn from_client(tx: Arc<str>, client_id: Arc<str>, host_id: Uuid) -> Self {
Self {
tx,
client_id: Some(client_id.into()),
lineage: vec![Arc::from("client")],
host_id,
created_at: chrono::Utc::now().to_rfc3339(),
windback: None,
}
}
pub fn from_client_with_windback(
tx: Arc<str>,
client_id: Arc<str>,
host_id: Uuid,
windback: Option<Arc<str>>,
) -> Self {
Self {
tx,
client_id: Some(client_id.into()),
lineage: vec![Arc::from("client")],
host_id,
created_at: chrono::Utc::now().to_rfc3339(),
windback,
}
}
pub fn internal(tx: Arc<str>, host_id: Uuid, origin: &str) -> Self {
Self {
tx,
client_id: None,
lineage: vec![Arc::from(origin)],
host_id,
created_at: chrono::Utc::now().to_rfc3339(),
windback: None,
}
}
pub fn child(&self, operation: &str) -> Self {
let mut lineage = self.lineage.clone();
lineage.push(Arc::from(operation));
Self {
tx: self.tx.clone(),
client_id: self.client_id.clone(),
lineage,
host_id: self.host_id,
created_at: self.created_at.clone(),
windback: self.windback.clone(),
}
}
pub fn is_windback(&self) -> bool {
self.windback.is_some()
}
pub fn windback(&self) -> Option<&str> {
self.windback.as_deref()
}
pub fn tx(&self) -> &str {
&self.tx
}
pub fn client_id(&self) -> Option<&str> {
self.client_id.as_deref()
}
pub fn lineage_string(&self) -> String {
self.lineage
.iter()
.map(|s| s.as_ref())
.collect::<Vec<_>>()
.join(" → ")
}
}