From 2c4f0b569d8d68482dae3df132cacdbde378b194 Mon Sep 17 00:00:00 2001 From: Elvis Pranskevichus Date: Wed, 7 Feb 2024 12:13:22 -0800 Subject: [PATCH] Accept fractional units as input to `--compute-size` and `--storage-size` (#1206) Also, recognize that `units_default` can be `null`. --- src/cloud/ops.rs | 4 ++-- src/portable/create.rs | 13 +++++++++---- src/portable/options.rs | 18 ++++++++++++++---- src/portable/resize.rs | 8 +++++--- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/cloud/ops.rs b/src/cloud/ops.rs index 8f274d249..566e6f598 100644 --- a/src/cloud/ops.rs +++ b/src/cloud/ops.rs @@ -102,8 +102,8 @@ pub struct Version { pub struct Price { pub billable: String, pub unit_price_cents: String, - pub units_bundled: String, - pub units_default: String, + pub units_bundled: Option, + pub units_default: Option, } pub type Prices = HashMap>>; diff --git a/src/portable/create.rs b/src/portable/create.rs index feed21a5f..3806a6f90 100644 --- a/src/portable/create.rs +++ b/src/portable/create.rs @@ -257,20 +257,25 @@ fn create_cloud( .context(format!("could not download pricing information for the {} region", region))?; let default_compute = region_prices.into_iter() .find(|&price| price.billable == "compute") - .context("could not download pricing information for compute")?; + .context("could not download pricing information for compute")? + .units_default.clone() + .context("could not find default value for compute")?; + let default_storage = region_prices.into_iter() .find(|&price| price.billable == "storage") - .context("could not download pricing information for compute")?; + .context("could not download pricing information for storage")? + .units_default.clone() + .context("could not find default value for storage")?; let mut req_resources: Vec = vec![]; let compute_size_v = match compute_size { - None => default_compute.units_default.clone(), + None => default_compute, Some(v) => v.clone(), }; let storage_size_v = match storage_size { - None => default_storage.units_default.clone(), + None => default_storage, Some(v) => v.clone(), }; diff --git a/src/portable/options.rs b/src/portable/options.rs index 79b3b58d7..aea9422e2 100644 --- a/src/portable/options.rs +++ b/src/portable/options.rs @@ -147,11 +147,21 @@ pub enum InstanceName { } fn billable_unit(s: &str) -> Result { - let unit: usize = s + let (numerator, denominator) = match s.split_once("/") { + Some(v) => v, + None => (s, "1"), + }; + + let n: u64 = numerator + .parse() + .map_err(|_| format!("`{s}` is not a positive number or valid fraction"))?; + + let d: u64 = denominator .parse() - .map_err(|_| format!("`{s}` is not a positive number"))?; - if unit <= 0 { - Err(String::from("`{s}` is not a positive number")) + .map_err(|_| format!("`{s}` is not a positive number or valid fraction"))?; + + if n <= 0 || d <= 0 { + Err(String::from("`{s}` is not a positive number or valid fraction")) } else { Ok(s.to_string()) } diff --git a/src/portable/resize.rs b/src/portable/resize.rs index 143945847..5acc973f6 100644 --- a/src/portable/resize.rs +++ b/src/portable/resize.rs @@ -97,13 +97,15 @@ fn resize_cloud_cmd( compute_size = Some(region_prices.into_iter() .find(|&price| price.billable == "compute") .context("could not download pricing information for compute")? - .units_default.clone()); + .units_default.clone() + .context("could not find default value for compute")?); } if storage_size.is_none() { storage_size = Some(region_prices.into_iter() .find(|&price| price.billable == "storage") - .context("could not download pricing information for compute")? - .units_default.clone()); + .context("could not download pricing information for storage")? + .units_default.clone() + .context("could not find default value for storage")?); } } }