1use crate::util::{get_stack_status, load_config};
2use aws_sdk_cloudformation::types::StackStatus;
3use aws_sdk_cloudformation::Client;
4use rusty_cdk_core::wrappers::StringWithOnlyAlphaNumericsAndHyphens;
5use std::error::Error;
6use std::fmt::{Display, Formatter};
7use std::process::exit;
8use std::time::Duration;
9use tokio::time::sleep;
10
11#[derive(Debug)]
12pub enum DestroyError {
13 StackDeleteError(String),
14 UnknownError(String),
15}
16
17impl Error for DestroyError {}
18
19impl Display for DestroyError {
20 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
21 match self {
22 DestroyError::StackDeleteError(_) => f.write_str("unable to delete stack"),
23 DestroyError::UnknownError(_) => f.write_str("unknown error"),
24 }
25 }
26}
27
28pub async fn destroy(name: StringWithOnlyAlphaNumericsAndHyphens) {
30 match destroy_with_result(name, true).await {
31 Ok(()) => println!("destroy completed successfully!"),
32 Err(e) => {
33 eprintln!("{:?}", e);
34 exit(1);
35 }
36 }
37}
38
39pub async fn destroy_with_result(name: StringWithOnlyAlphaNumericsAndHyphens, print_progress: bool) -> Result<(), DestroyError> {
43 let name = name.0;
44 let config = load_config(false).await;
45 let cloudformation_client = Client::new(&config);
46
47 destroy_stack(&name, &cloudformation_client).await?;
48
49 loop {
50 let status = get_stack_status(&name, &cloudformation_client).await;
51
52 if let Some(status) = status {
53 match status {
54 StackStatus::DeleteComplete => return Ok(()),
55 StackStatus::DeleteInProgress => {
56 if print_progress {
57 println!("destroying...");
58 }
59 }
60 StackStatus::DeleteFailed => {
61 return Err(DestroyError::StackDeleteError(format!("{status}")));
62 }
63 _ => {
64 return Err(DestroyError::UnknownError(format!("{status}")));
65 }
66 }
67 } else {
68 return Ok(());
70 }
71
72 sleep(Duration::from_secs(10)).await;
73 }
74}
75
76async fn destroy_stack(name: &String, cloudformation_client: &Client) -> Result<(), DestroyError> {
77 let delete_result = cloudformation_client.delete_stack().stack_name(name).send().await;
78 match delete_result {
79 Ok(_) => Ok(()),
80 Err(e) => Err(DestroyError::StackDeleteError(e.to_string())),
81 }
82}