1use plugin::prelude::*;
2use serde_json::json;
3use std::fs;
4use std::path::PathBuf;
5
6// #[import]
7// fn command(string: String) -> Option<String>;
8
9// TODO: some sort of macro to generate ABI bindings
10extern "C" {
11 pub fn hello(item: u32) -> u32;
12 pub fn bye(item: u32) -> u32;
13}
14
15// #[bind]
16// pub async fn name(u32) -> u32 {
17
18// }
19
20#[bind]
21pub fn name() -> &'static str {
22 let number = unsafe { hello(27) };
23 println!("got: {}", number);
24 let number = unsafe { bye(28) };
25 println!("got: {}", number);
26 "vscode-json-languageserver"
27}
28
29#[bind]
30pub fn server_args() -> Vec<String> {
31 vec!["--stdio".into()]
32}
33
34#[bind]
35pub fn fetch_latest_server_version() -> Option<String> {
36 // #[derive(Deserialize)]
37 // struct NpmInfo {
38 // versions: Vec<String>,
39 // }
40
41 // let output = command("npm info vscode-json-languageserver --json")?;
42 // if !output.status.success() {
43 // return None;
44 // }
45
46 // let mut info: NpmInfo = serde_json::from_slice(&output.stdout)?;
47 // info.versions.pop()
48 println!("fetching server version");
49 Some("1.3.4".into())
50}
51
52#[bind]
53pub fn fetch_server_binary(container_dir: PathBuf, version: String) -> Option<PathBuf> {
54 println!("Fetching server binary");
55 return None;
56 // let version_dir = container_dir.join(version.as_str());
57 // fs::create_dir_all(&version_dir)
58 // .await
59 // .context("failed to create version directory")?;
60 // let binary_path = version_dir.join(Self::BIN_PATH);
61
62 // if fs::metadata(&binary_path).await.is_err() {
63 // let output = smol::process::Command::new("npm")
64 // .current_dir(&version_dir)
65 // .arg("install")
66 // .arg(format!("vscode-json-languageserver@{}", version))
67 // .output()
68 // .await
69 // .context("failed to run npm install")?;
70 // if !output.status.success() {
71 // Err(anyhow!("failed to install vscode-json-languageserver"))?;
72 // }
73
74 // if let Some(mut entries) = fs::read_dir(&container_dir).await.log_err() {
75 // while let Some(entry) = entries.next().await {
76 // if let Some(entry) = entry.log_err() {
77 // let entry_path = entry.path();
78 // if entry_path.as_path() != version_dir {
79 // fs::remove_dir_all(&entry_path).await.log_err();
80 // }
81 // }
82 // }
83 // }
84 // }
85
86 // Ok(binary_path)
87}
88
89const BIN_PATH: &'static str =
90 "node_modules/vscode-json-languageserver/bin/vscode-json-languageserver";
91
92#[bind]
93pub fn cached_server_binary(container_dir: PathBuf) -> Option<PathBuf> {
94 println!("Finding cached server binary...");
95 let mut last_version_dir = None;
96 println!("{}", container_dir.exists());
97 let mut entries = fs::read_dir(&container_dir).ok()?;
98 println!("Read Entries...");
99 while let Some(entry) = entries.next() {
100 let entry = entry.ok()?;
101 if entry.file_type().ok()?.is_dir() {
102 last_version_dir = Some(entry.path());
103 }
104 }
105 let last_version_dir = last_version_dir?;
106 let bin_path = last_version_dir.join(BIN_PATH);
107 if bin_path.exists() {
108 println!("this is the path: {}", bin_path.display());
109 Some(bin_path)
110 } else {
111 None
112 }
113}
114
115#[bind]
116pub fn initialization_options() -> Option<serde_json::Value> {
117 Some(json!({
118 "provideFormatter": true
119 }))
120}
121
122#[bind]
123pub fn id_for_language(name: String) -> Option<String> {
124 if name == "JSON" {
125 Some("jsonc".into())
126 } else {
127 None
128 }
129}