component_debug/cli/
route.rs

1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::query::get_cml_moniker_from_query;
6use crate::route::{self, RouteReport};
7use anyhow::{format_err, Result};
8use fidl_fuchsia_sys2 as fsys;
9
10pub async fn route_cmd_print<W: std::io::Write>(
11    target_moniker: String,
12    filter: Option<String>,
13    route_validator: fsys::RouteValidatorProxy,
14    realm_query: fsys::RealmQueryProxy,
15    mut writer: W,
16) -> Result<()> {
17    let moniker = get_cml_moniker_from_query(&target_moniker, &realm_query).await?;
18
19    writeln!(writer, "Moniker: {}", &moniker)?;
20
21    let targets = route_targets_from_filter(filter)?;
22    let reports = route::route(&route_validator, moniker, targets).await?;
23
24    let table = route::create_table(reports);
25    table.print(&mut writer)?;
26    writeln!(writer, "")?;
27
28    Ok(())
29}
30
31pub async fn route_cmd_serialized(
32    target_moniker: String,
33    filter: Option<String>,
34    route_validator: fsys::RouteValidatorProxy,
35    realm_query: fsys::RealmQueryProxy,
36) -> Result<Vec<RouteReport>> {
37    let moniker = get_cml_moniker_from_query(&target_moniker, &realm_query).await?;
38    let targets = route_targets_from_filter(filter)?;
39    route::route(&route_validator, moniker, targets).await
40}
41
42fn route_targets_from_filter(filter: Option<String>) -> Result<Vec<fsys::RouteTarget>> {
43    if filter.is_none() {
44        return Ok(vec![]);
45    }
46    let filter = filter.unwrap();
47    filter
48        .split(',')
49        .into_iter()
50        .map(|entry| {
51            let parts: Vec<_> = entry.split(':').collect();
52            match parts.len() {
53                2 => {
54                    let decl_type = match parts[0] {
55                        "use" => fsys::DeclType::Use,
56                        "expose" => fsys::DeclType::Expose,
57                        _ => {
58                            return Err(invalid_filter_err(&entry));
59                        }
60                    };
61                    Ok(fsys::RouteTarget { name: parts[1].into(), decl_type })
62                }
63                1 => {
64                    Ok(fsys::RouteTarget { name: parts[0].into(), decl_type: fsys::DeclType::Any })
65                }
66                _ => Err(invalid_filter_err(&entry)),
67            }
68        })
69        .collect()
70}
71
72fn invalid_filter_err(filter: &str) -> anyhow::Error {
73    format_err!(
74        "Invalid filter: {}. Format must match <capability>, \
75        use:<capability>, or expose:<capability>.",
76        filter
77    )
78}