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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use async_trait::async_trait;
use aws_sdk_dynamodb as dynamodb;
use aws_sdk_dynamodb::types;
use clap::{Args, Subcommand};

use config::Config;
use error::RawsError;

mod table;

type DynamoResult<T = Box<dyn show::Show>> = std::result::Result<T, aws_sdk_dynamodb::Error>;

#[async_trait]
pub trait Execute {
    async fn execute(self: Box<Self>, config: &Config) -> DynamoResult;
}

trait ClientExt {
    fn client(&self) -> dynamodb::Client;
}

impl ClientExt for Config {
    fn client(&self) -> dynamodb::Client {
        dynamodb::Client::new(self.config())
    }
}

/// Amazon DynamoDB is a fully managed NoSQL database service
///
/// Amazon DynamoDB is a fully managed NoSQL database service that provides
/// fast and predictable performance with seamless scalability. DynamoDB
/// lets you offload the administrative burdens of operating and scaling a
/// distributed database, so that you don't have to worry about hardware
/// provisioning, setup and configuration, replication, software patching,
/// or cluster scaling.
///
/// With DynamoDB, you can create database tables that can store and
/// retrieve any amount of data, and serve any level of request traffic.
/// You can scale up or scale down your tables' throughput capacity without
/// downtime or performance degradation, and use the Amazon Web Services
/// Management Console to monitor resource utilization and performance
/// metrics.
///
/// DynamoDB automatically spreads the data and traffic for your tables
/// over a sufficient number of servers to handle your throughput and
/// storage requirements, while maintaining consistent and fast
/// performance. All of your data is stored on solid state disks (SSDs) and
/// automatically replicated across multiple Availability Zones in an
/// Amazon Web Services Region, providing built-in high availability and
/// data durability.
#[derive(Debug, Subcommand)]
#[command(verbatim_doc_comment)]
pub enum DynamoDb {
    CreateTable(table::CreateTable),
    DeleteTable(table::DeleteTable),
    DescribeTable(table::DescribeTable),
    ListTables(table::ListTables),
}

impl DynamoDb {
    fn boxed(self) -> Box<dyn Execute> {
        match self {
            Self::CreateTable(create_table) => Box::new(create_table),
            Self::DeleteTable(delete_table) => Box::new(delete_table),
            Self::DescribeTable(describe_table) => Box::new(describe_table),
            Self::ListTables(list_tables) => Box::new(list_tables),
        }
    }

    pub async fn dispatch(self, config: Config) -> Result<(), RawsError<aws_sdk_dynamodb::Error>> {
        self.boxed()
            .execute(&config)
            .await
            .map(|output| config.show(output))?;
        Ok(())
    }
}