use std::sync::Arc;
use crate::component_graph::ComponentUpdateSender;
use crate::identity::IdentityProvider;
use crate::state_store::StateStoreProvider;
#[derive(Clone)]
pub struct SourceRuntimeContext {
pub instance_id: String,
pub source_id: String,
pub state_store: Option<Arc<dyn StateStoreProvider>>,
pub update_tx: ComponentUpdateSender,
pub identity_provider: Option<Arc<dyn IdentityProvider>>,
}
impl SourceRuntimeContext {
pub fn new(
instance_id: impl Into<String>,
source_id: impl Into<String>,
state_store: Option<Arc<dyn StateStoreProvider>>,
update_tx: ComponentUpdateSender,
identity_provider: Option<Arc<dyn IdentityProvider>>,
) -> Self {
Self {
instance_id: instance_id.into(),
source_id: source_id.into(),
state_store,
update_tx,
identity_provider,
}
}
pub fn instance_id(&self) -> &str {
&self.instance_id
}
pub fn source_id(&self) -> &str {
&self.source_id
}
pub fn state_store(&self) -> Option<&Arc<dyn StateStoreProvider>> {
self.state_store.as_ref()
}
}
impl std::fmt::Debug for SourceRuntimeContext {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SourceRuntimeContext")
.field("instance_id", &self.instance_id)
.field("source_id", &self.source_id)
.field(
"state_store",
&self.state_store.as_ref().map(|_| "<StateStoreProvider>"),
)
.field("update_tx", &"<ComponentUpdateSender>")
.field(
"identity_provider",
&self
.identity_provider
.as_ref()
.map(|_| "<IdentityProvider>"),
)
.finish()
}
}
#[derive(Clone)]
pub struct ReactionRuntimeContext {
pub instance_id: String,
pub reaction_id: String,
pub state_store: Option<Arc<dyn StateStoreProvider>>,
pub update_tx: ComponentUpdateSender,
pub identity_provider: Option<Arc<dyn IdentityProvider>>,
}
impl ReactionRuntimeContext {
pub fn new(
instance_id: impl Into<String>,
reaction_id: impl Into<String>,
state_store: Option<Arc<dyn StateStoreProvider>>,
update_tx: ComponentUpdateSender,
identity_provider: Option<Arc<dyn IdentityProvider>>,
) -> Self {
Self {
instance_id: instance_id.into(),
reaction_id: reaction_id.into(),
state_store,
update_tx,
identity_provider,
}
}
pub fn instance_id(&self) -> &str {
&self.instance_id
}
pub fn reaction_id(&self) -> &str {
&self.reaction_id
}
pub fn state_store(&self) -> Option<&Arc<dyn StateStoreProvider>> {
self.state_store.as_ref()
}
}
impl std::fmt::Debug for ReactionRuntimeContext {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ReactionRuntimeContext")
.field("instance_id", &self.instance_id)
.field("reaction_id", &self.reaction_id)
.field(
"state_store",
&self.state_store.as_ref().map(|_| "<StateStoreProvider>"),
)
.field("update_tx", &"<ComponentUpdateSender>")
.field(
"identity_provider",
&self
.identity_provider
.as_ref()
.map(|_| "<IdentityProvider>"),
)
.finish()
}
}
#[derive(Clone)]
pub struct QueryRuntimeContext {
pub instance_id: String,
pub query_id: String,
pub update_tx: ComponentUpdateSender,
}
impl QueryRuntimeContext {
pub fn new(
instance_id: impl Into<String>,
query_id: impl Into<String>,
update_tx: ComponentUpdateSender,
) -> Self {
Self {
instance_id: instance_id.into(),
query_id: query_id.into(),
update_tx,
}
}
pub fn instance_id(&self) -> &str {
&self.instance_id
}
pub fn query_id(&self) -> &str {
&self.query_id
}
}
impl std::fmt::Debug for QueryRuntimeContext {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("QueryRuntimeContext")
.field("instance_id", &self.instance_id)
.field("query_id", &self.query_id)
.field("update_tx", &"<ComponentUpdateSender>")
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::component_graph::ComponentGraph;
use crate::state_store::MemoryStateStoreProvider;
use std::sync::Arc;
fn test_update_tx() -> ComponentUpdateSender {
let (graph, _rx) = ComponentGraph::new("test-instance");
graph.update_sender()
}
#[tokio::test]
async fn test_source_runtime_context_creation() {
let state_store = Arc::new(MemoryStateStoreProvider::new());
let update_tx = test_update_tx();
let context = SourceRuntimeContext::new(
"test-instance",
"test-source",
Some(state_store),
update_tx,
None,
);
assert_eq!(context.instance_id(), "test-instance");
assert_eq!(context.source_id(), "test-source");
assert!(context.state_store().is_some());
}
#[tokio::test]
async fn test_source_runtime_context_without_state_store() {
let update_tx = test_update_tx();
let context =
SourceRuntimeContext::new("test-instance", "test-source", None, update_tx, None);
assert_eq!(context.source_id(), "test-source");
assert!(context.state_store().is_none());
}
#[tokio::test]
async fn test_source_runtime_context_clone() {
let state_store = Arc::new(MemoryStateStoreProvider::new());
let update_tx = test_update_tx();
let context = SourceRuntimeContext::new(
"test-instance",
"test-source",
Some(state_store),
update_tx,
None,
);
let cloned = context.clone();
assert_eq!(cloned.source_id(), context.source_id());
}
#[tokio::test]
async fn test_reaction_runtime_context_creation() {
let state_store = Arc::new(MemoryStateStoreProvider::new());
let update_tx = test_update_tx();
let context = ReactionRuntimeContext::new(
"test-instance",
"test-reaction",
Some(state_store),
update_tx,
None,
);
assert_eq!(context.instance_id(), "test-instance");
assert_eq!(context.reaction_id(), "test-reaction");
assert!(context.state_store().is_some());
}
#[tokio::test]
async fn test_reaction_runtime_context_without_state_store() {
let update_tx = test_update_tx();
let context =
ReactionRuntimeContext::new("test-instance", "test-reaction", None, update_tx, None);
assert_eq!(context.reaction_id(), "test-reaction");
assert!(context.state_store().is_none());
}
#[tokio::test]
async fn test_reaction_runtime_context_clone() {
let state_store = Arc::new(MemoryStateStoreProvider::new());
let update_tx = test_update_tx();
let context = ReactionRuntimeContext::new(
"test-instance",
"test-reaction",
Some(state_store),
update_tx,
None,
);
let cloned = context.clone();
assert_eq!(cloned.reaction_id(), context.reaction_id());
}
#[test]
fn test_source_runtime_context_debug() {
let update_tx = test_update_tx();
let context = SourceRuntimeContext::new("test-instance", "test", None, update_tx, None);
let debug_str = format!("{context:?}");
assert!(debug_str.contains("SourceRuntimeContext"));
assert!(debug_str.contains("test"));
}
#[test]
fn test_reaction_runtime_context_debug() {
let update_tx = test_update_tx();
let context = ReactionRuntimeContext::new("test-instance", "test", None, update_tx, None);
let debug_str = format!("{context:?}");
assert!(debug_str.contains("ReactionRuntimeContext"));
assert!(debug_str.contains("test"));
}
#[tokio::test]
async fn test_query_runtime_context_creation() {
let update_tx = test_update_tx();
let context = QueryRuntimeContext::new("test-instance", "test-query", update_tx);
assert_eq!(context.instance_id(), "test-instance");
assert_eq!(context.query_id(), "test-query");
}
#[tokio::test]
async fn test_query_runtime_context_clone() {
let update_tx = test_update_tx();
let context = QueryRuntimeContext::new("test-instance", "test-query", update_tx);
let cloned = context.clone();
assert_eq!(cloned.query_id(), context.query_id());
assert_eq!(cloned.instance_id(), context.instance_id());
}
#[test]
fn test_query_runtime_context_debug() {
let update_tx = test_update_tx();
let context = QueryRuntimeContext::new("test-instance", "test-query", update_tx);
let debug_str = format!("{context:?}");
assert!(debug_str.contains("QueryRuntimeContext"));
assert!(debug_str.contains("test-query"));
}
}