use std::any::Any;
use std::collections::BTreeMap;
use std::sync::Arc;
use crate::context::CamelContext;
use crate::error::{CamelError, Result};
use crate::message::Exchange;
use crate::util::Parameters;
use crate::value::Value;
pub trait Processor: Send + Sync {
fn process(&self, exchange: &mut Exchange) -> Result<()>;
fn process_timed(&self, exchange: &mut Exchange, _start: u64) -> (Result<()>, u64) {
(self.process(exchange), 0)
}
}
impl<F> Processor for F
where
F: Fn(&mut Exchange) -> Result<()> + Send + Sync,
{
fn process(&self, exchange: &mut Exchange) -> Result<()> {
self(exchange)
}
}
impl Processor for Arc<dyn Processor> {
fn process(&self, exchange: &mut Exchange) -> Result<()> {
(**self).process(exchange)
}
fn process_timed(&self, exchange: &mut Exchange, start: u64) -> (Result<()>, u64) {
(**self).process_timed(exchange, start)
}
}
pub trait Service: Send + Sync {
fn start(&self) -> Result<()> {
Ok(())
}
fn stop(&self) -> Result<()> {
Ok(())
}
fn as_suspendable(&self) -> Option<&dyn SuspendableService> {
None
}
}
pub trait SuspendableService: Send + Sync {
fn suspend(&self) -> Result<()>;
fn resume(&self) -> Result<()>;
fn is_suspended(&self) -> bool;
}
pub trait Expression: Send + Sync {
fn evaluate(&self, exchange: &Exchange) -> Result<Value>;
}
impl<F> Expression for F
where
F: Fn(&Exchange) -> Result<Value> + Send + Sync,
{
fn evaluate(&self, exchange: &Exchange) -> Result<Value> {
self(exchange)
}
}
pub trait Predicate: Send + Sync {
fn matches(&self, exchange: &Exchange) -> Result<bool>;
}
pub struct FnPredicate<F>(pub F);
impl<F> Predicate for FnPredicate<F>
where
F: Fn(&Exchange) -> Result<bool> + Send + Sync,
{
fn matches(&self, exchange: &Exchange) -> Result<bool> {
(self.0)(exchange)
}
}
pub struct ExpressionPredicate(pub Arc<dyn Expression>);
impl Predicate for ExpressionPredicate {
fn matches(&self, exchange: &Exchange) -> Result<bool> {
Ok(self.0.evaluate(exchange)?.is_predicate_true())
}
}
pub struct PredicateExpression(pub Arc<dyn Predicate>);
impl Expression for PredicateExpression {
fn evaluate(&self, exchange: &Exchange) -> Result<Value> {
Ok(Value::Bool(self.0.matches(exchange)?))
}
}
pub trait Language: Send + Sync {
fn name(&self) -> &str;
fn create_expression(&self, text: &str, options: &BTreeMap<String, String>) -> Result<Arc<dyn Expression>>;
fn create_predicate(&self, text: &str, options: &BTreeMap<String, String>) -> Result<Arc<dyn Predicate>> {
Ok(Arc::new(ExpressionPredicate(self.create_expression(text, options)?)))
}
}
pub trait Producer: Processor + Service {}
impl<T: Processor + Service> Producer for T {}
pub trait Consumer: Service {}
impl<T: Service> Consumer for T {}
pub trait PollingConsumer: Service {
fn receive(&self, timeout: Option<std::time::Duration>) -> Result<Option<Exchange>>;
}
pub trait Endpoint: Send + Sync + Any {
fn uri(&self) -> &str;
fn create_producer(&self) -> Result<Arc<dyn Producer>> {
Err(CamelError::new(
crate::error::kinds::UNSUPPORTED_OPERATION,
format!("Endpoint {} does not support producers", self.uri()),
))
}
fn create_consumer(&self, _processor: Arc<dyn Processor>) -> Result<Arc<dyn Consumer>> {
Err(CamelError::new(
crate::error::kinds::UNSUPPORTED_OPERATION,
format!("Endpoint {} does not support consumers", self.uri()),
))
}
#[cfg(feature = "agent")]
fn chat_model(&self) -> Option<Arc<dyn crate::ai::ChatModel>> {
None
}
fn create_polling_consumer(&self) -> Result<Arc<dyn PollingConsumer>> {
Err(CamelError::new(
crate::error::kinds::UNSUPPORTED_OPERATION,
format!("Endpoint {} does not support polling consumers", self.uri()),
))
}
fn is_singleton(&self) -> bool {
true
}
fn start(&self) -> Result<()> {
Ok(())
}
fn stop(&self) -> Result<()> {
Ok(())
}
fn as_any(&self) -> &dyn Any;
}
pub trait Component: Send + Sync {
fn create_endpoint(
&self,
context: &CamelContext,
uri: &str,
remaining: &str,
params: &mut Parameters,
) -> Result<Arc<dyn Endpoint>>;
fn lenient_properties(&self) -> bool {
false
}
fn start(&self) -> Result<()> {
Ok(())
}
fn stop(&self) -> Result<()> {
Ok(())
}
fn as_any(&self) -> &dyn Any;
}
pub trait AggregationStrategy: Send + Sync {
fn aggregate(&self, old: Option<Exchange>, new: Exchange) -> Result<Exchange>;
fn timeout(&self, _old: &Exchange, _index: usize, _total: usize, _timeout_ms: u64) {}
fn on_completion(&self, _exchange: &mut Exchange) {}
fn never_fails(&self) -> bool {
false
}
fn aggregate_into(&self, group: &mut Option<Exchange>, new: Exchange) -> Result<()> {
let old = group.take();
*group = Some(self.aggregate(old, new)?);
Ok(())
}
}
impl<F> AggregationStrategy for F
where
F: Fn(Option<Exchange>, Exchange) -> Result<Exchange> + Send + Sync,
{
fn aggregate(&self, old: Option<Exchange>, new: Exchange) -> Result<Exchange> {
self(old, new)
}
}
pub trait EventNotifier: Send + Sync {
fn notify(&self, event: &crate::context::CamelEvent);
}