use hcloud::apis::configuration::Configuration;
use hcloud::apis::server_types_api;
use hcloud::models::ServerType;
use std::env;
#[tokio::main]
async fn main() -> Result<(), String> {
let api_token = env::args()
.nth(1)
.ok_or("Please provide API token as command line parameter.")?;
let mut configuration = Configuration::new();
configuration.bearer_access_token = Some(api_token);
let server_types = server_types_api::list_server_types(&configuration, Default::default())
.await
.map_err(|err| format!("API call to list_server_types failed: {:?}", err))?
.server_types;
let cheapest_server_type = server_types
.into_iter()
.flat_map(map_server_type)
.min_by(compare_prices)
.ok_or("Could not find cheapest server type")?;
println!("Cheapest server type:");
println!(" Server type name: {}", cheapest_server_type.name);
println!(" Location: {}", cheapest_server_type.location);
println!(" Hourly gross price: {}", cheapest_server_type.gross_price);
Ok(())
}
struct ServerTypePriceInfo {
name: String,
location: String,
gross_price: f32,
}
fn map_server_type(server_type: ServerType) -> impl Iterator<Item = ServerTypePriceInfo> {
let name = server_type.name;
server_type
.prices
.into_iter()
.filter_map(move |price_per_time| {
price_per_time
.price_hourly
.gross
.parse::<f32>()
.ok()
.map(|gross_price| ServerTypePriceInfo {
name: name.clone(),
location: price_per_time.location,
gross_price,
})
})
}
fn compare_prices(x: &ServerTypePriceInfo, y: &ServerTypePriceInfo) -> std::cmp::Ordering {
x.gross_price
.partial_cmp(&y.gross_price)
.unwrap_or(std::cmp::Ordering::Equal)
}