Skip to main content

pro_plugin/
hooks.rs

1//! Plugin lifecycle hooks
2
3use serde::{Deserialize, Serialize};
4
5/// Available lifecycle hooks
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum Hook {
8    /// Called before dependency resolution
9    PreResolve,
10    /// Called after dependency resolution
11    PostResolve,
12    /// Called before building
13    PreBuild,
14    /// Called after building
15    PostBuild,
16    /// Called before publishing
17    PrePublish,
18}
19
20impl Hook {
21    /// Get the function name to call in the Wasm module
22    pub fn function_name(&self) -> &'static str {
23        match self {
24            Hook::PreResolve => "pre_resolve",
25            Hook::PostResolve => "post_resolve",
26            Hook::PreBuild => "pre_build",
27            Hook::PostBuild => "post_build",
28            Hook::PrePublish => "pre_publish",
29        }
30    }
31}
32
33/// Context passed to hook functions
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct HookContext {
36    /// Project root directory
37    pub project_root: String,
38
39    /// Current operation details
40    pub operation: String,
41
42    /// Additional context data (JSON)
43    #[serde(default)]
44    pub data: serde_json::Value,
45}
46
47impl HookContext {
48    /// Create a new hook context
49    pub fn new(project_root: impl Into<String>, operation: impl Into<String>) -> Self {
50        Self {
51            project_root: project_root.into(),
52            operation: operation.into(),
53            data: serde_json::Value::Null,
54        }
55    }
56
57    /// Add additional data to the context
58    pub fn with_data(mut self, data: serde_json::Value) -> Self {
59        self.data = data;
60        self
61    }
62
63    /// Serialize to bytes for Wasm
64    pub fn to_bytes(&self) -> Vec<u8> {
65        serde_json::to_vec(self).unwrap_or_default()
66    }
67}
68
69/// Result returned from hook execution
70#[derive(Debug, Clone, Default, Serialize, Deserialize)]
71pub struct HookResult {
72    /// Whether to continue with the operation
73    pub continue_operation: bool,
74
75    /// Messages to display to the user
76    #[serde(default)]
77    pub messages: Vec<String>,
78
79    /// Modified data (if any)
80    #[serde(default)]
81    pub data: Option<serde_json::Value>,
82}
83
84impl HookResult {
85    /// Create a successful result
86    pub fn ok() -> Self {
87        Self {
88            continue_operation: true,
89            messages: vec![],
90            data: None,
91        }
92    }
93
94    /// Create a result that stops the operation
95    pub fn stop(message: impl Into<String>) -> Self {
96        Self {
97            continue_operation: false,
98            messages: vec![message.into()],
99            data: None,
100        }
101    }
102
103    /// Deserialize from bytes
104    pub fn from_bytes(bytes: &[u8]) -> Result<Self, serde_json::Error> {
105        serde_json::from_slice(bytes)
106    }
107
108    /// Merge another result into this one
109    pub fn merge(&mut self, other: HookResult) {
110        self.continue_operation = self.continue_operation && other.continue_operation;
111        self.messages.extend(other.messages);
112        if other.data.is_some() {
113            self.data = other.data;
114        }
115    }
116}