Mountain/RPC/CocoonService/Provider/
ProvideInlineCompletionItems.rs1
2use tonic::{Response, Status};
14use url::Url;
15use CommonLibrary::LanguageFeature::{
16 DTO::PositionDTO::PositionDTO,
17 LanguageFeatureProviderRegistry::LanguageFeatureProviderRegistry,
18};
19use serde_json::json;
20
21use crate::{
22 RPC::CocoonService::CocoonServiceImpl,
23 Vine::Generated::{InlineCompletionItem, ProvideInlineCompletionRequest, ProvideInlineCompletionResponse},
24 dev_log,
25};
26
27pub async fn Fn(
28 Service:&CocoonServiceImpl,
29
30 Request:ProvideInlineCompletionRequest,
31) -> Result<Response<ProvideInlineCompletionResponse>, Status> {
32 let URI = Request.uri.as_ref().map(|U| U.value.as_str()).unwrap_or("");
33
34 let Position_ = Request.position.as_ref();
35
36 let Line = Position_.map(|P| P.line).unwrap_or(0);
37
38 let Character = Position_.map(|P| P.character).unwrap_or(0);
39
40 dev_log!(
41 "provider",
42 "ProvideInlineCompletionItems handle={} uri={} line={} char={}",
43 Request.provider_handle,
44 URI,
45 Line,
46 Character
47 );
48
49 let DocumentURI = Url::parse(URI).map_err(|E| Status::invalid_argument(format!("Invalid URI: {}", E)))?;
50
51 let PositionDTO_ = PositionDTO { LineNumber:Line, Column:Character };
52
53 let Context = json!({
54 "triggerKind": Request.context.as_ref().map(|C| C.trigger_kind).unwrap_or(0),
55 "selectedCompletionInfo": Request.context.as_ref()
56 .map(|C| C.selected_completion_info.as_str())
57 .unwrap_or(""),
58 });
59
60 match Service
61 .environment
62 .ProvideInlineCompletionItems(DocumentURI, PositionDTO_, Context)
63 .await
64 {
65 Ok(Some(Raw)) => {
66 let ItemsArr = Raw
70 .get("items")
71 .and_then(|V| V.as_array())
72 .cloned()
73 .or_else(|| Raw.as_array().cloned())
74 .unwrap_or_default();
75
76 let Items:Vec<InlineCompletionItem> = ItemsArr
77 .iter()
78 .filter_map(|Item| {
79 let InsertText = Item
80 .get("insertText")
81 .and_then(|V| V.as_str())
82 .or_else(|| Item.get("text").and_then(|V| V.as_str()))
83 .unwrap_or("");
84
85 if InsertText.is_empty() {
86 return None;
87 }
88
89 let IsSnippet = Item.get("isSnippet").and_then(|V| V.as_bool()).unwrap_or(false);
90
91 let Command = Item
92 .get("command")
93 .and_then(|V| V.get("command"))
94 .and_then(|V| V.as_str())
95 .or_else(|| Item.get("command").and_then(|V| V.as_str()))
96 .unwrap_or("")
97 .to_string();
98
99 Some(InlineCompletionItem {
101 insert_text:InsertText.to_string(),
102 range:None, command:Command,
104 is_snippet:IsSnippet,
105 })
106 })
107 .collect();
108
109 Ok(Response::new(ProvideInlineCompletionResponse { items:Items }))
110 },
111
112 Ok(None) => Ok(Response::new(ProvideInlineCompletionResponse::default())),
113
114 Err(Error) => {
115 dev_log!("provider", "warn: [ProvideInlineCompletionItems] provider error: {}", Error);
116 Ok(Response::new(ProvideInlineCompletionResponse::default()))
117 },
118 }
119}