Skip to main content

camel_component_api/
component.rs

1use async_trait::async_trait;
2use camel_api::CamelError;
3
4use crate::component_context::ComponentContext;
5use crate::endpoint::Endpoint;
6
7/// A Component is a factory for Endpoints.
8///
9/// Each component handles a specific URI scheme (e.g. "timer", "log", "direct").
10#[async_trait]
11pub trait Component: Send + Sync {
12    /// The URI scheme this component handles (e.g., "timer", "log").
13    fn scheme(&self) -> &str;
14
15    /// Create an endpoint from a URI string.
16    fn create_endpoint(
17        &self,
18        uri: &str,
19        ctx: &dyn ComponentContext,
20    ) -> Result<Box<dyn Endpoint>, CamelError>;
21
22    /// Start the component (e.g. connect to external systems).
23    ///
24    /// Default: no-op, returns `Ok(())`.
25    async fn start(&self) -> Result<(), CamelError> {
26        Ok(())
27    }
28
29    /// Stop the component (e.g. release resources, close connections).
30    ///
31    /// Default: no-op, returns `Ok(())`.
32    async fn stop(&self) -> Result<(), CamelError> {
33        Ok(())
34    }
35}
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40
41    struct DummyComponent;
42
43    #[async_trait]
44    impl Component for DummyComponent {
45        fn scheme(&self) -> &str {
46            "dummy"
47        }
48
49        fn create_endpoint(
50            &self,
51            _uri: &str,
52            _ctx: &dyn ComponentContext,
53        ) -> Result<Box<dyn Endpoint>, CamelError> {
54            Err(CamelError::EndpointCreationFailed("not implemented".into()))
55        }
56    }
57
58    #[tokio::test]
59    async fn test_component_default_lifecycle() {
60        let c = DummyComponent;
61        assert!(c.start().await.is_ok());
62        assert!(c.stop().await.is_ok());
63    }
64}