22//! Protocol. This module specifically handles requests.
33
44use std:: {
5+ fs,
56 io:: Write as _,
67 process:: { self , Stdio } ,
78 sync:: Arc ,
@@ -29,7 +30,7 @@ use project_model::{ManifestPath, ProjectWorkspace, TargetKind};
2930use serde_json:: json;
3031use stdx:: { format_to, never} ;
3132use syntax:: { algo, ast, AstNode , TextRange , TextSize } ;
32- use vfs:: { AbsPath , AbsPathBuf } ;
33+ use vfs:: { AbsPath , AbsPathBuf , VfsPath } ;
3334
3435use crate :: {
3536 cargo_target_spec:: CargoTargetSpec ,
@@ -38,7 +39,10 @@ use crate::{
3839 from_proto,
3940 global_state:: { GlobalState , GlobalStateSnapshot } ,
4041 line_index:: LineEndings ,
41- lsp_ext:: { self , PositionOrRange , ViewCrateGraphParams , WorkspaceSymbolParams } ,
42+ lsp_ext:: {
43+ self , CrateInfoResult , FetchDependencyListParams , FetchDependencyListResult ,
44+ PositionOrRange , ViewCrateGraphParams , WorkspaceSymbolParams ,
45+ } ,
4246 lsp_utils:: { all_edits_are_disjoint, invalid_params_error} ,
4347 to_proto, LspError , Result ,
4448} ;
@@ -1881,3 +1885,52 @@ fn run_rustfmt(
18811885 Ok ( Some ( to_proto:: text_edit_vec ( & line_index, diff ( & file, & new_text) ) ) )
18821886 }
18831887}
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