Skip to main content

Mountain/RPC/CocoonService/Provider/
ProvideHover.rs

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