Skip to main content

Mountain/RPC/CocoonService/Provider/
ProvideHover.rs

1#![allow(non_snake_case)]
2
3//! Look up a hover from the registered provider. Joins multiple content
4//! pieces with a Markdown horizontal-rule separator.
5
6use tonic::{Response, Status};
7use url::Url;
8use CommonLibrary::LanguageFeature::{
9	DTO::PositionDTO::PositionDTO,
10	LanguageFeatureProviderRegistry::LanguageFeatureProviderRegistry,
11};
12
13use crate::{
14	RPC::CocoonService::CocoonServiceImpl,
15	Vine::Generated::{Position, ProvideHoverRequest, ProvideHoverResponse, Range},
16	dev_log,
17};
18
19pub async fn Fn(
20	Service:&CocoonServiceImpl,
21	Request:ProvideHoverRequest,
22) -> Result<Response<ProvideHoverResponse>, Status> {
23	let URI = Request.uri.as_ref().map(|U| U.value.as_str()).unwrap_or("");
24	let Position_ = Request.position.as_ref();
25	let Line = Position_.map(|P| P.line).unwrap_or(0);
26	let Character = Position_.map(|P| P.character).unwrap_or(0);
27	dev_log!(
28		"provider",
29		"ProvideHover entry handle={} uri={} line={} char={}",
30		Request.provider_handle,
31		URI,
32		Line,
33		Character
34	);
35
36	let DocumentURI = Url::parse(URI).map_err(|E| Status::invalid_argument(format!("Invalid URI: {}", E)))?;
37	let PositionDTO_ = PositionDTO { LineNumber:Line, Column:Character };
38
39	match Service.environment.ProvideHover(DocumentURI, PositionDTO_).await {
40		Ok(Some(Hover)) => {
41			let Markdown = Hover
42				.Contents
43				.iter()
44				.map(|C| C.Value.as_str())
45				.collect::<Vec<_>>()
46				.join("\n---\n");
47			let RangeOption = Hover.Range.map(|R| {
48				Range {
49					start:Some(Position { line:R.StartLineNumber, character:R.StartColumn }),
50					end:Some(Position { line:R.EndLineNumber, character:R.EndColumn }),
51				}
52			});
53			dev_log!(
54				"provider",
55				"ProvideHover result handle={} contents_len={} hasRange={}",
56				Request.provider_handle,
57				Markdown.len(),
58				RangeOption.is_some()
59			);
60			Ok(Response::new(ProvideHoverResponse { markdown:Markdown, range:RangeOption }))
61		},
62		Ok(None) => {
63			dev_log!(
64				"provider",
65				"ProvideHover result handle={} (no provider)",
66				Request.provider_handle
67			);
68			Ok(Response::new(ProvideHoverResponse { markdown:String::new(), range:None }))
69		},
70		Err(Error) => {
71			dev_log!(
72				"provider",
73				"warn: ProvideHover failed handle={} err={}",
74				Request.provider_handle,
75				Error
76			);
77			Err(Status::internal(format!("Hover failed: {}", Error)))
78		},
79	}
80}