[selectors] Improve API usability by removing Arc<Selector>
Also uses `&str` where a `&String` was being required previously.
Tested: existing tests
Change-Id: Ib44689c7b58bffbfdc1ce1efa8d46ef82b2322cd
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/560421
Fuchsia-Auto-Submit: Miguel Flores <miguelfrde@google.com>
Reviewed-by: Chris Phoenix <cphoenix@google.com>
Reviewed-by: Christopher Johnson <crjohns@google.com>
Commit-Queue: Auto-Submit <auto-submit@fuchsia-infra.iam.gserviceaccount.com>
diff --git a/src/diagnostics/archivist/src/inspect/mod.rs b/src/diagnostics/archivist/src/inspect/mod.rs
index bf6392a..a6eac37 100644
--- a/src/diagnostics/archivist/src/inspect/mod.rs
+++ b/src/diagnostics/archivist/src/inspect/mod.rs
@@ -292,7 +292,7 @@
client_selectors = {
let matching_selectors = selectors::match_component_moniker_against_selectors(
&pumped_inspect_data.identity.relative_moniker,
- configured_selectors,
+ configured_selectors.as_slice(),
)
.unwrap_or_else(|err| {
error!(
diff --git a/src/diagnostics/lib/selectors/src/selectors.rs b/src/diagnostics/lib/selectors/src/selectors.rs
index 8ddf5bb..7b7f9b5 100644
--- a/src/diagnostics/lib/selectors/src/selectors.rs
+++ b/src/diagnostics/lib/selectors/src/selectors.rs
@@ -11,10 +11,10 @@
lazy_static::lazy_static,
regex::{Regex, RegexSet},
regex_syntax,
+ std::borrow::Borrow,
std::fs,
std::io::{BufRead, BufReader},
std::path::{Path, PathBuf},
- std::sync::Arc,
};
// Character used to delimit the different sections of an inspect selector,
// the component selector, the tree selector, and the property selector.
@@ -85,7 +85,7 @@
/// are escaping.
/// 4) Require that there are no unescaped selector delimiters, `:`,
/// or unescaped path delimiters, `/`.
-fn validate_string_pattern(string_pattern: &String) -> Result<(), Error> {
+fn validate_string_pattern(string_pattern: &str) -> Result<(), Error> {
lazy_static! {
static ref STRING_PATTERN_VALIDATOR: RegexSet = RegexSet::new(&[
// No glob expressions allowed.
@@ -257,7 +257,7 @@
}
/// Parse a string into a FIDL StringSelector structure.
-fn convert_string_to_string_selector(string_to_convert: &String) -> StringSelector {
+fn convert_string_to_string_selector(string_to_convert: &str) -> StringSelector {
// TODO(fxbug.dev/4601): Expose the ability to parse selectors from string into "exact_match" mode.
StringSelector::StringPattern(string_to_convert.to_string())
}
@@ -323,7 +323,7 @@
/// Converts an unparsed component selector string into a ComponentSelector.
pub fn parse_component_selector(
- unparsed_component_selector: &String,
+ unparsed_component_selector: &str,
) -> Result<ComponentSelector, Error> {
if unparsed_component_selector.is_empty() {
return Err(format_err!("ComponentSelector must have atleast one path node.",));
@@ -349,8 +349,8 @@
/// Converts an unparsed node path selector and an unparsed property selector into
/// a TreeSelector.
fn parse_tree_selector(
- unparsed_node_path: &String,
- unparsed_property_selector: Option<&String>,
+ unparsed_node_path: &str,
+ unparsed_property_selector: Option<&str>,
) -> Result<TreeSelector, Error> {
let node_path_option = if unparsed_node_path.is_empty() {
None
@@ -666,10 +666,13 @@
///
/// Requires: hierarchy_path is not empty.
/// selectors contains valid Selectors.
-pub fn match_component_moniker_against_selector(
- moniker: &[impl AsRef<str> + std::string::ToString],
- selector: &Arc<Selector>,
-) -> Result<bool, Error> {
+pub fn match_component_moniker_against_selector<T>(
+ moniker: &[T],
+ selector: &Selector,
+) -> Result<bool, Error>
+where
+ T: AsRef<str> + std::string::ToString,
+{
validate_selector(selector)?;
if moniker.is_empty() {
@@ -689,32 +692,36 @@
///
/// Requires: hierarchy_path is not empty.
/// selectors contains valid Selectors.
-pub fn match_component_moniker_against_selectors(
+pub fn match_component_moniker_against_selectors<'a, T>(
moniker: &[String],
- selectors: &[Arc<Selector>],
-) -> Result<Vec<Arc<Selector>>, Error> {
+ selectors: &'a [T],
+) -> Result<Vec<&'a Selector>, Error>
+where
+ T: Borrow<Selector>,
+{
if moniker.is_empty() {
return Err(format_err!(
"Cannot have empty monikers, at least the component name is required."
));
}
- let selectors: Result<Vec<Arc<Selector>>, Error> = selectors
+ let selectors = selectors
.iter()
.map(|selector| {
- validate_selector(selector)?;
- Ok(selector.clone())
+ let component_selector = selector.borrow();
+ validate_selector(component_selector)?;
+ Ok(component_selector)
})
- .collect::<Result<Vec<Arc<Selector>>, Error>>();
+ .collect::<Result<Vec<&Selector>, Error>>();
selectors?
.iter()
.filter_map(|selector| {
match_component_moniker_against_selector(moniker, selector)
- .map(|is_match| if is_match { Some(selector.clone()) } else { None })
+ .map(|is_match| if is_match { Some(*selector) } else { None })
.transpose()
})
- .collect::<Result<Vec<Arc<Selector>>, Error>>()
+ .collect::<Result<Vec<&Selector>, Error>>()
}
/// Evaluates a component moniker against a list of component selectors, returning
@@ -722,23 +729,27 @@
///
/// Requires: moniker is not empty.
/// component_selectors contains valid ComponentSelectors.
-pub fn match_moniker_against_component_selectors(
+pub fn match_moniker_against_component_selectors<'a, T>(
moniker: &[String],
- selectors: &[Arc<ComponentSelector>],
-) -> Result<Vec<Arc<ComponentSelector>>, Error> {
+ selectors: &'a [T],
+) -> Result<Vec<&'a ComponentSelector>, Error>
+where
+ T: Borrow<ComponentSelector> + 'a,
+{
if moniker.is_empty() {
return Err(format_err!(
"Cannot have empty monikers, at least the component name is required."
));
}
- let component_selectors: Result<Vec<Arc<ComponentSelector>>, Error> = selectors
+ let component_selectors = selectors
.iter()
.map(|selector| {
- validate_component_selector(selector)?;
- Ok(selector.clone())
+ let component_selector = selector.borrow();
+ validate_component_selector(component_selector)?;
+ Ok(component_selector)
})
- .collect::<Result<Vec<Arc<ComponentSelector>>, Error>>();
+ .collect::<Result<Vec<&ComponentSelector>, Error>>();
component_selectors?
.iter()
@@ -747,7 +758,7 @@
.map(|is_match| if is_match { Some(selector.clone()) } else { None })
.transpose()
})
- .collect::<Result<Vec<Arc<ComponentSelector>>, Error>>()
+ .collect::<Result<Vec<&ComponentSelector>, Error>>()
}
/// Format a |Selector| as a string.
@@ -839,39 +850,39 @@
#[test]
fn canonical_component_selector_test() {
- let test_vector: Vec<(String, StringSelector, StringSelector, StringSelector)> = vec![
+ let test_vector = vec![
(
- "a/b/c".to_string(),
+ "a/b/c",
StringSelector::StringPattern("a".to_string()),
StringSelector::StringPattern("b".to_string()),
StringSelector::StringPattern("c".to_string()),
),
(
- "a/*/c".to_string(),
+ "a/*/c",
StringSelector::StringPattern("a".to_string()),
StringSelector::StringPattern("*".to_string()),
StringSelector::StringPattern("c".to_string()),
),
(
- "a/b*/c".to_string(),
+ "a/b*/c",
StringSelector::StringPattern("a".to_string()),
StringSelector::StringPattern("b*".to_string()),
StringSelector::StringPattern("c".to_string()),
),
(
- r#"a/b\*/c"#.to_string(),
+ r#"a/b\*/c"#,
StringSelector::StringPattern("a".to_string()),
StringSelector::StringPattern(r#"b\*"#.to_string()),
StringSelector::StringPattern("c".to_string()),
),
(
- r#"a/\*/c"#.to_string(),
+ r#"a/\*/c"#,
StringSelector::StringPattern("a".to_string()),
StringSelector::StringPattern(r#"\*"#.to_string()),
StringSelector::StringPattern("c".to_string()),
),
(
- "a/b/**".to_string(),
+ "a/b/**",
StringSelector::StringPattern("a".to_string()),
StringSelector::StringPattern("b".to_string()),
StringSelector::StringPattern("**".to_string()),
@@ -932,36 +943,30 @@
#[test]
fn canonical_tree_selector_test() {
- let test_vector: Vec<(
- String,
- Option<String>,
- StringSelector,
- StringSelector,
- Option<StringSelector>,
- )> = vec![
+ let test_vector = vec![
(
- "a/b".to_string(),
- Some("c".to_string()),
+ "a/b",
+ Some("c"),
StringSelector::StringPattern("a".to_string()),
StringSelector::StringPattern("b".to_string()),
Some(StringSelector::StringPattern("c".to_string())),
),
(
- "a/*".to_string(),
- Some("c".to_string()),
+ "a/*",
+ Some("c"),
StringSelector::StringPattern("a".to_string()),
StringSelector::StringPattern("*".to_string()),
Some(StringSelector::StringPattern("c".to_string())),
),
(
- "a/b".to_string(),
- Some("*".to_string()),
+ "a/b",
+ Some("*"),
StringSelector::StringPattern("a".to_string()),
StringSelector::StringPattern("b".to_string()),
Some(StringSelector::StringPattern("*".to_string())),
),
(
- "a/b".to_string(),
+ "a/b",
None,
StringSelector::StringPattern("a".to_string()),
StringSelector::StringPattern("b".to_string()),
@@ -977,8 +982,7 @@
parsed_property,
) in test_vector
{
- let tree_selector =
- parse_tree_selector(&test_node_path, test_target_property.as_ref()).unwrap();
+ let tree_selector = parse_tree_selector(test_node_path, test_target_property).unwrap();
match tree_selector {
TreeSelector::SubtreeSelector(tree_selector) => {
match tree_selector.node_path.as_slice() {
@@ -1006,25 +1010,24 @@
#[test]
fn errorful_tree_selector_test() {
- let test_vector: Vec<(String, Option<String>)> = vec![
+ let test_vector = vec![
// Not allowed due to empty property selector.
- ("a/b".to_string(), Some("".to_string())),
+ ("a/b", Some("")),
// Not allowed due to glob property selector.
- ("a/b".to_string(), Some("**".to_string())),
+ ("a/b", Some("**")),
// Not allowed due to escape-char without a thing to escape.
- (r#"a/b\"#.to_string(), Some("c".to_string())),
+ (r#"a/b\"#, Some("c")),
// String literals can't have globs.
- (r#"a/b**"#.to_string(), Some("c".to_string())),
+ (r#"a/b**"#, Some("c")),
// Property selector string literals cant have globs.
- (r#"a/b"#.to_string(), Some("c**".to_string())),
- ("a/b".to_string(), Some("**".to_string())),
+ (r#"a/b"#, Some("c**")),
+ ("a/b", Some("**")),
// Node path cant have globs.
- ("a/**".to_string(), Some("c".to_string())),
- ("".to_string(), Some("c".to_string())),
+ ("a/**", Some("c")),
+ ("", Some("c")),
];
for (test_nodepath, test_target_property) in test_vector {
- let tree_selector_result =
- parse_tree_selector(&test_nodepath, test_target_property.as_ref());
+ let tree_selector_result = parse_tree_selector(test_nodepath, test_target_property);
assert!(tree_selector_result.is_err());
}
}
@@ -1379,7 +1382,7 @@
];
for (selector, moniker) in passing_test_cases {
- let parsed_selector = Arc::new(parse_selector(selector).unwrap());
+ let parsed_selector = parse_selector(selector).unwrap();
assert!(
match_component_moniker_against_selector(&moniker, &parsed_selector).unwrap(),
"Selector {:?} failed to match {:?}",
@@ -1398,7 +1401,7 @@
];
for (selector, moniker) in failing_test_cases {
- let parsed_selector = Arc::new(parse_selector(selector).unwrap());
+ let parsed_selector = parse_selector(selector).unwrap();
assert!(
!match_component_moniker_against_selector(&moniker, &parsed_selector).unwrap(),
"Selector {:?} matched {:?}, but was expected to fail",
@@ -1413,13 +1416,13 @@
let selectors = vec![r#"*/echo.cmx"#, r#"ab*/echo.cmx"#, r#"abc/m*"#];
let moniker = vec!["abc".to_string(), "echo.cmx".to_string()];
- let component_selectors: Vec<Arc<ComponentSelector>> = selectors
+ let component_selectors = selectors
.into_iter()
- .map(|selector| Arc::new(parse_component_selector(&selector.to_string()).unwrap()))
- .collect();
+ .map(|selector| parse_component_selector(&selector.to_string()).unwrap())
+ .collect::<Vec<_>>();
let match_res =
- match_moniker_against_component_selectors(moniker.as_slice(), &component_selectors);
+ match_moniker_against_component_selectors(moniker.as_slice(), &component_selectors[..]);
assert!(match_res.is_ok());
assert_eq!(match_res.unwrap().len(), 2);
}
diff --git a/src/diagnostics/tool/src/main.rs b/src/diagnostics/tool/src/main.rs
index 01d82b2..3908c5a 100644
--- a/src/diagnostics/tool/src/main.rs
+++ b/src/diagnostics/tool/src/main.rs
@@ -17,7 +17,6 @@
std::fs::read_to_string,
std::io::{stdin, stdout, Write},
std::path::PathBuf,
- std::sync::Arc,
structopt::StructOpt,
termion::{
cursor,
@@ -181,7 +180,7 @@
fn filter_json_schema_by_selectors(
mut schema: InspectData,
- selector_vec: &Vec<Arc<Selector>>,
+ selector_vec: &Vec<Selector>,
) -> Option<InspectData> {
// A failure here implies a malformed snapshot. We want to panic.
let moniker = selectors::parse_path_to_moniker(&schema.moniker)
@@ -197,7 +196,7 @@
}
let hierarchy = schema.payload.unwrap();
- match selectors::match_component_moniker_against_selectors(&moniker, &selector_vec) {
+ match selectors::match_component_moniker_against_selectors(&moniker, selector_vec.as_slice()) {
Ok(matched_selectors) => {
if matched_selectors.is_empty() {
return None;
@@ -252,11 +251,8 @@
data: &[InspectData],
requested_name_opt: &Option<String>,
) -> Result<Vec<Line>, Error> {
- let selector_vec: Vec<Arc<Selector>> =
- selectors::parse_selector_file(&PathBuf::from(selector_file))?
- .into_iter()
- .map(Arc::new)
- .collect();
+ let selector_vec: Vec<Selector> =
+ selectors::parse_selector_file(&PathBuf::from(selector_file))?.into_iter().collect();
// Filter the source data that we diff against to only contain the component
// of interest.
diff --git a/src/lib/diagnostics/hierarchy/rust/src/lib.rs b/src/lib/diagnostics/hierarchy/rust/src/lib.rs
index 119939c..e9ee19c 100644
--- a/src/lib/diagnostics/hierarchy/rust/src/lib.rs
+++ b/src/lib/diagnostics/hierarchy/rust/src/lib.rs
@@ -19,6 +19,7 @@
selectors,
serde::Deserialize,
std::{
+ borrow::Borrow,
cmp::Ordering,
collections::HashMap,
convert::{TryFrom, TryInto},
@@ -694,25 +695,26 @@
pub node_property_selectors: Vec<String>,
}
-impl TryFrom<&Vec<Arc<Selector>>> for InspectHierarchyMatcher {
+impl<T: Borrow<Selector>> TryFrom<&Vec<T>> for InspectHierarchyMatcher {
type Error = Error;
- fn try_from(selectors: &Vec<Arc<Selector>>) -> Result<Self, Self::Error> {
+ fn try_from(selectors: &Vec<T>) -> Result<Self, Self::Error> {
selectors[..].try_into()
}
}
-impl TryFrom<&[Arc<Selector>]> for InspectHierarchyMatcher {
+impl<T: Borrow<Selector>> TryFrom<&[T]> for InspectHierarchyMatcher {
type Error = Error;
- fn try_from(selectors: &[Arc<Selector>]) -> Result<Self, Self::Error> {
+ fn try_from(selectors: &[T]) -> Result<Self, Self::Error> {
let (node_path_regexes, property_regexes): (Vec<_>, Vec<_>) = selectors
.iter()
.map(|selector| {
- selectors::validate_selector(selector).map_err(Error::Selectors)?;
+ let component_selector = selector.borrow();
+ selectors::validate_selector(component_selector).map_err(Error::Selectors)?;
// Unwrapping is safe here since we validate the selector above.
- match selector.tree_selector.as_ref().unwrap() {
+ match component_selector.tree_selector.as_ref().unwrap() {
TreeSelector::SubtreeSelector(subtree_selector) => {
Ok((
selectors::convert_path_selector_to_regex(