(input: &str)
| 8 | use crate::util::{matches_wildcard, WildcardFilterable}; |
| 9 | |
| 10 | pub fn handle_export(input: &str) -> Result<String, String> { |
| 11 | let filters: Vec<OptionalFeatureInfo> = if input.trim().is_empty() { |
| 12 | vec![OptionalFeatureInfo::default()] |
| 13 | } else { |
| 14 | let list: OptionalFeatureList = serde_json::from_str(input) |
| 15 | .map_err(|e| t!("export.failedParseInput", err = e.to_string()).to_string())?; |
| 16 | list.features |
| 17 | }; |
| 18 | |
| 19 | let session = DismSessionHandle::open()?; |
| 20 | let all_basics = session.get_all_feature_basics()?; |
| 21 | |
| 22 | // Check if any filter requires full info (displayName or description) |
| 23 | let needs_full_info = filters |
| 24 | .iter() |
| 25 | .any(|f| f.display_name.is_some() || f.description.is_some()); |
| 26 | |
| 27 | let mut results = Vec::new(); |
| 28 | |
| 29 | // When full info is needed, pre-partition filters by whether they specify a feature_name. |
| 30 | // This lets us skip get_feature_info() for features that cannot match any name-constrained filter. |
| 31 | let (filters_with_name, filters_without_name): (Vec<&OptionalFeatureInfo>, Vec<&OptionalFeatureInfo>) = |
| 32 | if needs_full_info { |
| 33 | filters.iter().partition(|f| f.feature_name.is_some()) |
| 34 | } else { |
| 35 | (Vec::new(), Vec::new()) |
| 36 | }; |
| 37 | |
| 38 | for (name, state_val) in &all_basics { |
| 39 | let state = FeatureState::from_dism(*state_val); |
| 40 | |
| 41 | if needs_full_info { |
| 42 | // Decide whether this feature could possibly match any filter based on its name. |
| 43 | // If any filter does not constrain feature_name, we must consider every feature, |
| 44 | // since such filters may match on displayName/description alone. |
| 45 | let mut should_get_full = !filters_without_name.is_empty(); |
| 46 | if !should_get_full { |
| 47 | for f in &filters_with_name { |
| 48 | if let Some(ref filter_name) = f.feature_name |
| 49 | && matches_wildcard(name, filter_name) { |
| 50 | should_get_full = true; |
| 51 | break; |
| 52 | } |
| 53 | } |
| 54 | } |
| 55 | if !should_get_full { |
| 56 | // This feature cannot satisfy any name-constrained filter, and there are |
| 57 | // no filters without a feature_name, so skip the expensive get_feature_info(). |
| 58 | continue; |
| 59 | } |
| 60 | // Get full info so we can filter on displayName/description and other fields. |
| 61 | let info = match session.get_feature_info(name) { |
| 62 | Ok(info) => info, |
| 63 | Err(_) => OptionalFeatureInfo { |
| 64 | feature_name: Some(name.clone()), |
| 65 | exist: None, |
| 66 | state, |
| 67 | display_name: None, |
nothing calls this directly
no test coverage detected