camel_component_api/
component.rs1use async_trait::async_trait;
2use camel_api::CamelError;
3use camel_api::component_metadata::ComponentMetadata;
4
5use crate::component_context::ComponentContext;
6use crate::endpoint::Endpoint;
7
8#[async_trait]
12pub trait Component: Send + Sync {
13 fn scheme(&self) -> &str;
15
16 fn metadata(&self) -> ComponentMetadata {
22 ComponentMetadata::minimal(self.scheme())
23 }
24
25 fn create_endpoint(
27 &self,
28 uri: &str,
29 ctx: &dyn ComponentContext,
30 ) -> Result<Box<dyn Endpoint>, CamelError>;
31
32 async fn start(&self) -> Result<(), CamelError> {
36 Ok(())
37 }
38
39 async fn stop(&self) -> Result<(), CamelError> {
43 Ok(())
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50
51 struct DummyComponent;
52
53 #[async_trait]
54 impl Component for DummyComponent {
55 fn scheme(&self) -> &str {
56 "dummy"
57 }
58
59 fn create_endpoint(
60 &self,
61 _uri: &str,
62 _ctx: &dyn ComponentContext,
63 ) -> Result<Box<dyn Endpoint>, CamelError> {
64 Err(CamelError::EndpointCreationFailed("not implemented".into()))
65 }
66 }
67
68 #[test]
69 fn test_component_default_metadata() {
70 let c = DummyComponent;
71 let meta = c.metadata();
72 assert_eq!(meta.scheme, "dummy");
73 assert_eq!(meta.schema_version, ComponentMetadata::SCHEMA_VERSION);
74 assert!(meta.uri_options.is_empty());
75 }
76
77 #[tokio::test]
78 async fn test_component_default_lifecycle() {
79 let c = DummyComponent;
80 assert!(c.start().await.is_ok());
81 assert!(c.stop().await.is_ok());
82 }
83}