use clap::Parser;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::fmt;
use tracing::info;
use openstack_sdk::AsyncOpenStack;
use crate::Cli;
use crate::OpenStackCliError;
use crate::output::OutputProcessor;
use structable::StructTable;
use structable::StructTableOptions;
#[derive(Parser)]
pub struct ListCommand {}
#[derive(Deserialize, Serialize)]
pub struct VecCatalogEndpoints(pub Vec<CatalogEndpoint>);
#[derive(Deserialize, Serialize, StructTable)]
pub struct Catalog {
#[structable(title = "service_type")]
#[serde(rename = "type")]
service_type: String,
#[structable(title = "service_name")]
name: String,
endpoints: VecCatalogEndpoints,
}
#[derive(Deserialize, Serialize, StructTable)]
pub struct CatalogEndpoint {
id: String,
interface: String,
region: String,
url: String,
}
impl fmt::Display for CatalogEndpoint {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"interface: {}, region: {}, url: {}",
self.interface, self.region, self.url
)
}
}
impl fmt::Display for VecCatalogEndpoints {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}",
self.0
.iter()
.map(|v| v.to_string())
.collect::<Vec<String>>()
.join("\n")
)
}
}
impl ListCommand {
pub async fn take_action(
&self,
parsed_args: &Cli,
client: &mut AsyncOpenStack,
) -> Result<(), OpenStackCliError> {
info!("Show Catalog");
let op = OutputProcessor::from_args(parsed_args, Some("catalog"), Some("list"));
op.validate_args(parsed_args)?;
let data: Vec<Value> = client
.get_token_catalog()
.unwrap_or_default()
.into_iter()
.map(serde_json::to_value)
.collect::<Result<Vec<_>, _>>()?;
op.output_list::<Catalog>(data)?;
op.show_command_hint()?;
Ok(())
}
}