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