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/// Idempotency-Key based request de-duplication plugin.
66pub mod idempotency;
67
68/// Trait for implementing Tako framework plugins.
69///
70/// Plugins extend the framework's functionality by implementing this trait. They can
71/// add middleware, modify routing behavior, register handlers, or integrate external
72/// services. All plugins must be thread-safe and have a static lifetime.
73///
74/// Plugins can be applied at both router and route levels:
75/// - **Router-level**: Use `router.plugin()` to apply globally
76/// - **Route-level**: Use `route.plugin()` to apply to specific routes
77///
78/// # Examples
79///
80/// ```rust
81/// use tako::plugins::TakoPlugin;
82/// use tako::router::Router;
83/// use tako::Method;
84/// use anyhow::Result;
85///
86/// struct CachePlugin {
87/// ttl_seconds: u64,
88/// }
89///
90/// impl TakoPlugin for CachePlugin {
91/// fn name(&self) -> &'static str {
92/// "cache"
93/// }
94///
95/// fn setup(&self, router: &Router) -> Result<()> {
96/// // Add middleware to the router
97/// router.middleware(|req, next| async move {
98/// // Cache logic here
99/// next.run(req).await
100/// });
101/// Ok(())
102/// }
103/// }
104///
105/// async fn handler(_req: tako::types::Request) -> &'static str {
106/// "Hello"
107/// }
108///
109/// // Router-level usage
110/// let mut router = Router::new();
111/// router.plugin(CachePlugin { ttl_seconds: 300 });
112///
113/// // Route-level usage
114/// let route = router.route(Method::GET, "/api/data", handler);
115/// route.plugin(CachePlugin { ttl_seconds: 600 });
116/// ```
117pub trait TakoPlugin: Send + Sync + 'static {
118 /// Returns the unique name identifier for this plugin.
119 fn name(&self) -> &'static str;
120
121 /// Configures and initializes the plugin with the given router.
122 fn setup(&self, router: &Router) -> Result<()>;
123}