extension_context_server.rs

 1use std::pin::Pin;
 2use std::sync::Arc;
 3
 4use anyhow::{anyhow, Result};
 5use async_trait::async_trait;
 6use context_servers::manager::{NativeContextServer, ServerConfig};
 7use context_servers::protocol::InitializedContextServerProtocol;
 8use context_servers::ContextServer;
 9use extension_host::wasm_host::{WasmExtension, WasmHost};
10use futures::{Future, FutureExt};
11use gpui::AsyncAppContext;
12
13pub struct ExtensionContextServer {
14    #[allow(unused)]
15    pub(crate) extension: WasmExtension,
16    #[allow(unused)]
17    pub(crate) host: Arc<WasmHost>,
18    id: Arc<str>,
19    context_server: Arc<NativeContextServer>,
20}
21
22impl ExtensionContextServer {
23    pub async fn new(extension: WasmExtension, host: Arc<WasmHost>, id: Arc<str>) -> Result<Self> {
24        let command = extension
25            .call({
26                let id = id.clone();
27                |extension, store| {
28                    async move {
29                        let command = extension
30                            .call_context_server_command(store, id.clone())
31                            .await?
32                            .map_err(|e| anyhow!("{}", e))?;
33                        anyhow::Ok(command)
34                    }
35                    .boxed()
36                }
37            })
38            .await?;
39
40        let config = Arc::new(ServerConfig {
41            id: id.to_string(),
42            executable: command.command,
43            args: command.args,
44            env: Some(command.env.into_iter().collect()),
45        });
46
47        anyhow::Ok(Self {
48            extension,
49            host,
50            id,
51            context_server: Arc::new(NativeContextServer::new(config)),
52        })
53    }
54}
55
56#[async_trait(?Send)]
57impl ContextServer for ExtensionContextServer {
58    fn id(&self) -> Arc<str> {
59        self.id.clone()
60    }
61
62    fn config(&self) -> Arc<ServerConfig> {
63        self.context_server.config()
64    }
65
66    fn client(&self) -> Option<Arc<InitializedContextServerProtocol>> {
67        self.context_server.client()
68    }
69
70    fn start<'a>(
71        self: Arc<Self>,
72        cx: &'a AsyncAppContext,
73    ) -> Pin<Box<dyn 'a + Future<Output = Result<()>>>> {
74        self.context_server.clone().start(cx)
75    }
76
77    fn stop(&self) -> Result<()> {
78        self.context_server.stop()
79    }
80}