human byte: make proper proxmox API type

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Thomas Lamprecht 2021-11-20 18:21:53 +01:00
parent ab1c07a622
commit 42ba4cd399
1 changed files with 22 additions and 0 deletions

View File

@ -1,5 +1,7 @@
use anyhow::{bail, Error}; use anyhow::{bail, Error};
use proxmox_schema::{ApiStringFormat, ApiType, Schema, StringSchema, UpdaterType};
/// Size units for byte sizes /// Size units for byte sizes
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
pub enum SizeUnit { pub enum SizeUnit {
@ -118,6 +120,7 @@ fn strip_unit(v: &str) -> (&str, SizeUnit) {
} }
/// Byte size which can be displayed in a human friendly way /// Byte size which can be displayed in a human friendly way
#[derive(Debug, Copy, Clone, UpdaterType)]
pub struct HumanByte { pub struct HumanByte {
/// The siginficant value, it does not includes any factor of the `unit` /// The siginficant value, it does not includes any factor of the `unit`
size: f64, size: f64,
@ -125,6 +128,22 @@ pub struct HumanByte {
unit: SizeUnit, unit: SizeUnit,
} }
fn verify_human_byte(s: &str) -> Result<(), Error> {
match s.parse::<HumanByte>() {
Ok(_) => Ok(()),
Err(err) => bail!("byte-size parse error for '{}': {}", s, err),
}
}
impl ApiType for HumanByte {
const API_SCHEMA: Schema = StringSchema::new(
"Byte size with optional unit (B, KB (base 10), MB, GB, ..., KiB (base 2), MiB, Gib, ...).",
)
.format(&ApiStringFormat::VerifyFn(verify_human_byte))
.min_length(1)
.max_length(64)
.schema();
}
impl HumanByte { impl HumanByte {
/// Create instance with size and unit (size must be positive) /// Create instance with size and unit (size must be positive)
pub fn with_unit(size: f64, unit: SizeUnit) -> Result<Self, Error> { pub fn with_unit(size: f64, unit: SizeUnit) -> Result<Self, Error> {
@ -197,6 +216,9 @@ impl std::str::FromStr for HumanByte {
} }
} }
proxmox::forward_deserialize_to_from_str!(HumanByte);
proxmox::forward_serialize_to_display!(HumanByte);
#[test] #[test]
fn test_human_byte_parser() -> Result<(), Error> { fn test_human_byte_parser() -> Result<(), Error> {
assert!("-10".parse::<HumanByte>().is_err()); // negative size assert!("-10".parse::<HumanByte>().is_err()); // negative size