cloud_disk_sync/plugins/
manager.rs1use crate::error::Result;
2use crate::plugins::hooks::{HookContext, HookHandler, HookPriority, PluginHook};
3use async_trait::async_trait;
4use std::collections::HashMap;
6
7pub struct HookManager {
8 handlers: HashMap<String, Vec<Box<dyn HookHandler>>>,
9 hooks_by_priority: HashMap<PluginHook, Vec<Box<dyn HookHandler>>>,
10}
11
12impl HookManager {
13 pub fn new() -> Self {
14 Self {
15 handlers: HashMap::new(),
16 hooks_by_priority: HashMap::new(),
17 }
18 }
19
20 pub fn register_handler(&mut self, handler: Box<dyn HookHandler>) {
21 let handlers = self
22 .handlers
23 .entry("all".to_string())
24 .or_insert_with(Vec::new);
25 handlers.push(handler);
26 }
27
28 pub async fn execute_hook(&self, hook: PluginHook, context: &mut HookContext) -> Result<()> {
29 if let Some(handlers) = self.handlers.get("all") {
30 let mut sorted_handlers: Vec<_> = handlers
32 .iter()
33 .map(|h| (h.get_priority(&hook), h.as_ref()))
34 .collect();
35
36 sorted_handlers.sort_by(|a, b| b.0.cmp(&a.0)); for (_, handler) in sorted_handlers {
39 if handler.supports_hook(&hook) {
40 handler.handle_hook(hook.clone(), context).await?;
41 }
42 }
43 }
44
45 Ok(())
46 }
47
48 fn all_hook_types() -> Vec<&'static str> {
49 vec!["all"]
50 }
51}
52
53#[derive(Clone)]
55pub struct LoggingPlugin {
56 name: String,
57 version: String,
58 enabled: bool,
59}
60
61impl LoggingPlugin {
62 pub fn new() -> Self {
63 Self {
64 name: "LoggingPlugin".to_string(),
65 version: "1.0.0".to_string(),
66 enabled: true,
67 }
68 }
69}
70
71#[async_trait]
72impl crate::core::traits::Plugin for LoggingPlugin {
73 fn name(&self) -> &str {
74 &self.name
75 }
76
77 fn version(&self) -> &str {
78 &self.version
79 }
80
81 fn description(&self) -> &str {
82 "A plugin that logs all synchronization events"
83 }
84
85 async fn initialize(&self) -> Result<()> {
86 log::info!("LoggingPlugin initialized");
87 Ok(())
88 }
89
90 async fn shutdown(&self) -> Result<()> {
91 log::info!("LoggingPlugin shutting down");
92 Ok(())
93 }
94
95 fn hooks(&self) -> Vec<PluginHook> {
96 vec![
97 PluginHook::PreSync {
98 task_id: "*".to_string(),
99 priority: HookPriority::Normal,
100 },
101 PluginHook::PostSync {
102 task_id: "*".to_string(),
103 priority: HookPriority::Normal,
104 },
105 PluginHook::OnError {
106 priority: HookPriority::Normal,
107 },
108 ]
109 }
110}
111
112#[async_trait]
113impl HookHandler for LoggingPlugin {
114 async fn handle_hook(&self, hook: PluginHook, context: &mut HookContext) -> Result<()> {
115 if !self.enabled {
116 return Ok(());
117 }
118
119 match &hook {
120 PluginHook::PreSync { task_id, .. } => {
121 log::info!("Starting sync for task: {}", task_id);
122 if let Some(task) = &context.task {
123 log::debug!("Task config: {:?}", task);
124 }
125 }
126 PluginHook::PostSync { task_id, .. } => {
127 log::info!("Completed sync for task: {}", task_id);
128 if let Some(report) = &context.report {
129 log::debug!("Sync report: {:?}", report.statistics);
130 }
131 }
132 PluginHook::OnError { .. } => {
133 if let Some(error) = &context.error {
134 log::error!("Sync error: {}", error);
135 }
136 }
137 _ => {
138 }
140 }
141
142 Ok(())
143 }
144
145 fn supports_hook(&self, hook: &PluginHook) -> bool {
146 match hook {
147 PluginHook::PreSync { .. } => true,
148 PluginHook::PostSync { .. } => true,
149 PluginHook::OnError { .. } => true,
150 _ => false,
151 }
152 }
153
154 fn get_priority(&self, _hook: &PluginHook) -> HookPriority {
155 HookPriority::Normal
156 }
157}
158
159