component_debug/
explore.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 anyhow::{format_err, Result};
6use futures::prelude::*;
7use moniker::Moniker;
8use std::str::FromStr;
9
10use flex_client::Socket;
11use flex_fuchsia_dash as fdash;
12
13#[derive(Debug, PartialEq)]
14pub enum DashNamespaceLayout {
15    NestAllInstanceDirs,
16    InstanceNamespaceIsRoot,
17}
18
19impl FromStr for DashNamespaceLayout {
20    type Err = anyhow::Error;
21
22    fn from_str(s: &str) -> Result<Self> {
23        match s {
24            "namespace" => Ok(Self::InstanceNamespaceIsRoot),
25            "nested" => Ok(Self::NestAllInstanceDirs),
26            _ => Err(format_err!("unknown layout (expected 'namespace' or 'nested')")),
27        }
28    }
29}
30
31impl Into<fdash::DashNamespaceLayout> for DashNamespaceLayout {
32    fn into(self) -> fdash::DashNamespaceLayout {
33        match self {
34            Self::NestAllInstanceDirs => fdash::DashNamespaceLayout::NestAllInstanceDirs,
35            Self::InstanceNamespaceIsRoot => fdash::DashNamespaceLayout::InstanceNamespaceIsRoot,
36        }
37    }
38}
39
40pub async fn explore_over_socket(
41    moniker: Moniker,
42    pty_server: Socket,
43    tools_urls: Vec<String>,
44    command: Option<String>,
45    ns_layout: DashNamespaceLayout,
46    launcher_proxy: &fdash::LauncherProxy,
47) -> Result<()> {
48    launcher_proxy
49        .explore_component_over_socket(
50            &moniker.to_string(),
51            pty_server,
52            &tools_urls,
53            command.as_deref(),
54            ns_layout.into(),
55        )
56        .await
57        .map_err(|e| format_err!("fidl error launching dash: {}", e))?
58        .map_err(|e| match e {
59            fdash::LauncherError::InstanceNotFound => {
60                format_err!("No instance was found matching the moniker '{}'.", moniker)
61            }
62            fdash::LauncherError::InstanceNotResolved => format_err!(
63                "{} is not resolved. Resolve the instance and retry this command",
64                moniker
65            ),
66            e => format_err!("Unexpected error launching dash: {:?}", e),
67        })?;
68    Ok(())
69}
70
71pub async fn wait_for_shell_exit(launcher_proxy: &fdash::LauncherProxy) -> Result<i32> {
72    // Report process errors and return the exit status.
73    let mut event_stream = launcher_proxy.take_event_stream();
74    match event_stream.next().await {
75        Some(Ok(fdash::LauncherEvent::OnTerminated { return_code })) => Ok(return_code),
76        Some(Err(e)) => Err(format_err!("OnTerminated event error: {:?}", e)),
77        None => Err(format_err!("didn't receive an expected OnTerminated event")),
78    }
79}