2
2
//! Protocol. This module specifically handles requests.
3
3
4
4
use std:: {
5
+ fs,
5
6
io:: Write as _,
6
7
process:: { self , Stdio } ,
7
8
sync:: Arc ,
@@ -29,7 +30,7 @@ use project_model::{ManifestPath, ProjectWorkspace, TargetKind};
29
30
use serde_json:: json;
30
31
use stdx:: { format_to, never} ;
31
32
use syntax:: { algo, ast, AstNode , TextRange , TextSize } ;
32
- use vfs:: { AbsPath , AbsPathBuf } ;
33
+ use vfs:: { AbsPath , AbsPathBuf , VfsPath } ;
33
34
34
35
use crate :: {
35
36
cargo_target_spec:: CargoTargetSpec ,
@@ -38,7 +39,10 @@ use crate::{
38
39
from_proto,
39
40
global_state:: { GlobalState , GlobalStateSnapshot } ,
40
41
line_index:: LineEndings ,
41
- lsp_ext:: { self , PositionOrRange , ViewCrateGraphParams , WorkspaceSymbolParams } ,
42
+ lsp_ext:: {
43
+ self , CrateInfoResult , FetchDependencyListParams , FetchDependencyListResult ,
44
+ PositionOrRange , ViewCrateGraphParams , WorkspaceSymbolParams ,
45
+ } ,
42
46
lsp_utils:: { all_edits_are_disjoint, invalid_params_error} ,
43
47
to_proto, LspError , Result ,
44
48
} ;
@@ -1881,3 +1885,52 @@ fn run_rustfmt(
1881
1885
Ok ( Some ( to_proto:: text_edit_vec ( & line_index, diff ( & file, & new_text) ) ) )
1882
1886
}
1883
1887
}
1888
+
1889
+ pub ( crate ) fn fetch_dependency_list (
1890
+ state : GlobalStateSnapshot ,
1891
+ _params : FetchDependencyListParams ,
1892
+ ) -> Result < FetchDependencyListResult > {
1893
+ let crates = state. analysis . fetch_crates ( ) ?;
1894
+ let crate_infos = crates
1895
+ . into_iter ( )
1896
+ . filter_map ( |it| {
1897
+ let root_file_path = state. file_id_to_file_path ( it. root_file_id ) ;
1898
+ crate_path ( root_file_path) . and_then ( to_url) . map ( |path| CrateInfoResult {
1899
+ name : it. name ,
1900
+ version : it. version ,
1901
+ path,
1902
+ } )
1903
+ } )
1904
+ . collect ( ) ;
1905
+ Ok ( FetchDependencyListResult { crates : crate_infos } )
1906
+ }
1907
+
1908
+ /// Searches for the directory of a Rust crate given this crate's root file path.
1909
+ ///
1910
+ /// # Arguments
1911
+ ///
1912
+ /// * `root_file_path`: The path to the root file of the crate.
1913
+ ///
1914
+ /// # Returns
1915
+ ///
1916
+ /// An `Option` value representing the path to the directory of the crate with the given
1917
+ /// name, if such a crate is found. If no crate with the given name is found, this function
1918
+ /// returns `None`.
1919
+ fn crate_path ( root_file_path : VfsPath ) -> Option < VfsPath > {
1920
+ let mut current_dir = root_file_path. parent ( ) ;
1921
+ while let Some ( path) = current_dir {
1922
+ let cargo_toml_path = path. join ( "../Cargo.toml" ) ?;
1923
+ if fs:: metadata ( cargo_toml_path. as_path ( ) ?) . is_ok ( ) {
1924
+ let crate_path = cargo_toml_path. parent ( ) ?;
1925
+ return Some ( crate_path) ;
1926
+ }
1927
+ current_dir = path. parent ( ) ;
1928
+ }
1929
+ None
1930
+ }
1931
+
1932
+ fn to_url ( path : VfsPath ) -> Option < Url > {
1933
+ let path = path. as_path ( ) ?;
1934
+ let str_path = path. as_os_str ( ) . to_str ( ) ?;
1935
+ Url :: from_file_path ( str_path) . ok ( )
1936
+ }
0 commit comments