1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use {
    crate::{commands::*, types::*},
    argh::FromArgs,
    async_trait::async_trait,
};

#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand)]
pub enum SubCommand {
    List(ListCommand),
    ListAccessors(ListAccessorsCommand),
    Selectors(SelectorsCommand),
    Show(ShowCommand),
}

#[derive(FromArgs, PartialEq, Debug)]
/// Top-level command.
pub struct CommandLine {
    #[argh(option, default = "Format::Text", short = 'f')]
    /// the format to be used to display the results (json, text).
    pub format: Format,

    #[argh(subcommand)]
    pub command: SubCommand,
}

// Once Generic Associated types are implemented we could have something along the lines of
// `type Result = Box<T: Serialize>` and not rely on this macro.
macro_rules! execute_and_format {
    ($self:ident, $provider:ident, [$($command:ident),*]) => {
        match &$self.command {
            $(
                SubCommand::$command(command) => {
                    let result = command.execute($provider).await?;
                    match $self.format {
                        Format::Json => {
                            serde_json::to_string_pretty(&result)
                                .map_err(|e| Error::InvalidCommandResponse(e))
                        }
                        Format::Text => {
                            Ok(result.to_string())
                        }
                    }
                }
            )*
        }
    }
}

#[async_trait]
impl Command for CommandLine {
    type Result = String;

    async fn execute<P: DiagnosticsProvider>(&self, provider: &P) -> Result<Self::Result, Error> {
        execute_and_format!(self, provider, [List, ListAccessors, Selectors, Show])
    }
}