lsp_proxy/
hooks.rs

1use async_trait::async_trait;
2use std::fmt::Display;
3
4use crate::{
5    Message, Notification, Request, Response, message::Direction,
6    processed_message::ProcessedMessage,
7};
8
9#[derive(Debug)]
10pub enum HookError {
11    ProcessingFailed(String),
12}
13
14impl Display for HookError {
15    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16        match self {
17            HookError::ProcessingFailed(msg) => write!(f, "Hook processing failed: {}", msg),
18        }
19    }
20}
21
22impl std::error::Error for HookError {}
23
24#[derive(Debug)]
25pub struct HookOutput {
26    pub message: Message,
27    pub generated_messages: Vec<(Direction, Message)>,
28}
29
30impl HookOutput {
31    pub fn new(message: Message) -> Self {
32        Self {
33            message: message,
34            generated_messages: Vec::new(),
35        }
36    }
37
38    pub fn with_message(mut self, direction: Direction, message: Message) -> Self {
39        self.generated_messages.push((direction, message));
40        self
41    }
42
43    pub fn with_messages(mut self, messages: Vec<(Direction, Message)>) -> Self {
44        self.generated_messages.extend(messages);
45        self
46    }
47
48    pub fn as_processed(self) -> ProcessedMessage {
49        ProcessedMessage::WithMessages {
50            message: self.message,
51            generated_messages: self.generated_messages,
52        }
53    }
54}
55
56pub type HookResult = Result<HookOutput, HookError>;
57
58#[async_trait]
59pub trait Hook: Send + Sync {
60    async fn on_request(&self, request: Request) -> HookResult {
61        Ok(HookOutput::new(Message::Request(request)))
62    }
63
64    async fn on_response(&self, response: Response) -> HookResult {
65        Ok(HookOutput::new(Message::Response(response)))
66    }
67
68    async fn on_notification(&self, notification: Notification) -> HookResult {
69        Ok(HookOutput::new(Message::Notification(notification)))
70    }
71}