tako/
plugins.rs

1#![cfg_attr(docsrs, doc(cfg(feature = "plugins")))]
2//! Plugin system for extending framework functionality with composable modules.
3//!
4//! This module provides the core plugin infrastructure for Tako, allowing developers
5//! to extend the framework with reusable components. Plugins can add middleware,
6//! modify routing behavior, or integrate external services. The `TakoPlugin` trait
7//! defines the interface all plugins must implement for registration and setup.
8//!
9//! Plugins can be applied at two levels:
10//! - **Router-level**: Applied globally to all routes using `router.plugin()`
11//! - **Route-level**: Applied to specific routes using `route.plugin()`
12//!
13//! # Examples
14//!
15//! ```rust
16//! use tako::plugins::TakoPlugin;
17//! use tako::router::Router;
18//! use tako::Method;
19//! use anyhow::Result;
20//!
21//! struct LoggingPlugin {
22//!     level: String,
23//! }
24//!
25//! impl TakoPlugin for LoggingPlugin {
26//!     fn name(&self) -> &'static str {
27//!         "logging"
28//!     }
29//!
30//!     fn setup(&self, _router: &Router) -> Result<()> {
31//!         println!("Setting up logging plugin with level: {}", self.level);
32//!         Ok(())
33//!     }
34//! }
35//!
36//! async fn handler(_req: tako::types::Request) -> &'static str {
37//!     "Hello"
38//! }
39//!
40//! // Router-level plugin (applied to all routes)
41//! let mut router = Router::new();
42//! router.plugin(LoggingPlugin { level: "info".to_string() });
43//!
44//! // Route-level plugin (applied to specific route only)
45//! let route = router.route(Method::GET, "/api/data", handler);
46//! route.plugin(LoggingPlugin { level: "debug".to_string() });
47//! ```
48
49use anyhow::Result;
50
51use crate::router::Router;
52
53/// Compression plugin for automatic response compression.
54pub mod compression;
55
56/// CORS (Cross-Origin Resource Sharing) plugin for handling cross-origin requests.
57pub mod cors;
58
59/// Rate limiting plugin for controlling request frequency.
60pub mod rate_limiter;
61
62/// Metrics/tracing plugin for integrating with systems like Prometheus or OpenTelemetry.
63pub mod metrics;
64
65/// Trait for implementing Tako framework plugins.
66///
67/// Plugins extend the framework's functionality by implementing this trait. They can
68/// add middleware, modify routing behavior, register handlers, or integrate external
69/// services. All plugins must be thread-safe and have a static lifetime.
70///
71/// Plugins can be applied at both router and route levels:
72/// - **Router-level**: Use `router.plugin()` to apply globally
73/// - **Route-level**: Use `route.plugin()` to apply to specific routes
74///
75/// # Examples
76///
77/// ```rust
78/// use tako::plugins::TakoPlugin;
79/// use tako::router::Router;
80/// use tako::Method;
81/// use anyhow::Result;
82///
83/// struct CachePlugin {
84///     ttl_seconds: u64,
85/// }
86///
87/// impl TakoPlugin for CachePlugin {
88///     fn name(&self) -> &'static str {
89///         "cache"
90///     }
91///
92///     fn setup(&self, router: &Router) -> Result<()> {
93///         // Add middleware to the router
94///         router.middleware(|req, next| async move {
95///             // Cache logic here
96///             next.run(req).await
97///         });
98///         Ok(())
99///     }
100/// }
101///
102/// async fn handler(_req: tako::types::Request) -> &'static str {
103///     "Hello"
104/// }
105///
106/// // Router-level usage
107/// let mut router = Router::new();
108/// router.plugin(CachePlugin { ttl_seconds: 300 });
109///
110/// // Route-level usage
111/// let route = router.route(Method::GET, "/api/data", handler);
112/// route.plugin(CachePlugin { ttl_seconds: 600 });
113/// ```
114pub trait TakoPlugin: Send + Sync + 'static {
115  /// Returns the unique name identifier for this plugin.
116  fn name(&self) -> &'static str;
117
118  /// Configures and initializes the plugin with the given router.
119  fn setup(&self, router: &Router) -> Result<()>;
120}