Mountain/Environment/LanguageFeatureProvider/
ProviderLookup.rs1use CommonLibrary::{Error::CommonError::CommonError, LanguageFeature::DTO::ProviderType::ProviderType};
4use url::Url;
5
6use crate::{
7 ApplicationState::DTO::ProviderRegistrationDTO::ProviderRegistrationDTO,
8 Environment::Utility::ErrorMapping::MapApplicationStateLockErrorToCommonError,
9 dev_log,
10};
11
12pub(super) async fn get_matching_provider(
13 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
14 document_uri:&Url,
15 feature_type:ProviderType,
16) -> Result<Option<ProviderRegistrationDTO>, CommonError> {
17 let providers = environment
18 .ApplicationState
19 .Extension
20 .ProviderRegistration
21 .LanguageProviders
22 .lock()
23 .map_err(MapApplicationStateLockErrorToCommonError)?;
24 let open_documents = environment
25 .ApplicationState
26 .Feature
27 .Documents
28 .OpenDocuments
29 .lock()
30 .map_err(MapApplicationStateLockErrorToCommonError)?;
31
32 let LanguageId:String = if let Some(Document) = open_documents.get(document_uri.as_str()) {
34 Document.LanguageIdentifier.clone()
35 } else {
36 document_uri
38 .path()
39 .split('.')
40 .next_back()
41 .map(|Ext| {
42 match Ext {
43 "rs" => "rust",
44 "ts" | "tsx" => "typescript",
45 "js" | "jsx" | "mjs" | "cjs" => "javascript",
46 "json" | "jsonc" => "json",
47 "toml" => "toml",
48 "yaml" | "yml" => "yaml",
49 "md" => "markdown",
50 "py" => "python",
51 "go" => "go",
52 "c" | "h" => "c",
53 "cpp" | "cc" | "cxx" | "hpp" => "cpp",
54 Other => Other,
55 }
56 })
57 .unwrap_or("plaintext")
58 .to_string()
59 };
60
61 for Provider in providers.values() {
62 if Provider.ProviderType != feature_type {
63 continue;
64 }
65 let Matched = if let Some(SelectorArray) = Provider.Selector.as_array() {
71 SelectorArray.iter().any(|S| {
72 match S.get("language") {
73 Some(L) if L.as_str() == Some(&LanguageId) => true,
74 Some(L) if L.as_str() == Some("*") => true,
75 Some(L) => {
76 L.as_array()
77 .map(|Arr| {
78 Arr.iter()
79 .any(|Item| Item.as_str() == Some(&LanguageId) || Item.as_str() == Some("*"))
80 })
81 .unwrap_or(false)
82 },
83 None => false,
84 }
85 })
86 } else if let Some(LangValue) = Provider.Selector.get("language") {
87 LangValue.as_str() == Some(&LanguageId)
88 || LangValue.as_str() == Some("*")
89 || LangValue
90 .as_array()
91 .map(|Arr| {
92 Arr.iter()
93 .any(|Item| Item.as_str() == Some(&LanguageId) || Item.as_str() == Some("*"))
94 })
95 .unwrap_or(false)
96 } else if let Some(LangStr) = Provider.Selector.as_str() {
97 LangStr == &LanguageId || LangStr == "*"
98 } else {
99 false
100 };
101
102 if Matched {
103 return Ok(Some(Provider.clone()));
104 }
105 }
106
107 dev_log!(
108 "extensions",
109 "warn: [ProviderLookup] No {:?} provider for language '{}' (uri={})",
110 feature_type,
111 LanguageId,
112 document_uri
113 );
114 Ok(None)
115}