Skip to main content

Mountain/RPC/CocoonService/Provider/
ProvideHover.rs

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