From b1f36440927c732f65c34f71e26be77019d4c5c7b12668999a9e297568ab8355 Mon Sep 17 00:00:00 2001 From: Kira Date: Mon, 25 May 2026 13:29:42 +0200 Subject: [PATCH] Adding KiraSize struct to handle power of 2 sizes. --- src/kira_size.rs | 143 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 src/kira_size.rs diff --git a/src/kira_size.rs b/src/kira_size.rs new file mode 100644 index 0000000..465296c --- /dev/null +++ b/src/kira_size.rs @@ -0,0 +1,143 @@ +// +// Copyright (C) <2026> + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +/* + KiraSize struct implementation for work with base2 sizes. +*/ + +use std::ops::{Add, Sub}; + +pub fn format_bytes_size(size: u64) -> String { + let suffixs: [&str; 5] = ["KB", "MB", "GB", "TB", "PB"]; + + if size < 1000 { + format!("{}B", size) + } else { + let mut s = size as f64; + let mut idx = 0; + for i in 0..5 { + s = s / 1024.0; + idx = i; + if s < 1000.0 { + break; + } + } + format!("{:.2}{}", s, suffixs[idx]) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct KiraSize { + size_bytes: u64, +} + +impl std::fmt::Display for KiraSize { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.size_bytes < 1000 { + write!(f, "{}B", self.size_bytes) + } else { + let mut s = self.size_bytes as f64; + let mut idx = 0; + for i in 0..5 { + s = s / 1024.0; + idx = i; + if s < 1000.0 { + break; + } + } + write!(f, "{:.2}{}", s, Self::SUFFIXS[idx]) + } + } +} + +impl KiraSize { + pub const SUFFIXS: [&str; 5] = ["KB", "MB", "GB", "TB", "PB"]; + pub fn new(size:u64) -> Self { + Self { size_bytes: size } + } + pub fn new_kb(size:u64) -> Self { + Self { size_bytes: size * 1024 } + } + pub fn new_mb(size:u64) -> Self { + Self { size_bytes: size * 1024u64.pow(2) } + } + pub fn new_gb(size:u64) -> Self { + Self { size_bytes: size * 1024u64.pow(3) } + } + pub fn new_tb(size:u64) -> Self { + Self { size_bytes: size * 1024u64.pow(4) } + } + pub fn new_pb(size:u64) -> Self { + Self { size_bytes: size * 1024u64.pow(5) } + } + + pub fn b(&self) -> u64 { + self.size_bytes + } + pub fn kb(&self) -> u64 { + self.size_bytes / 1024u64 + } + pub fn mb(&self) -> u64 { + self.size_bytes / 1024u64.pow(2) + } + pub fn gb(&self) -> u64 { + self.size_bytes / 1024u64.pow(3) + } + pub fn tb(&self) -> u64 { + self.size_bytes / 1024u64.pow(4) + } + pub fn pb(&self) -> u64 { + self.size_bytes / 1024u64.pow(5) + } + + pub fn from_str_bytes(s: &str) -> Option { + Some(Self::new(u64::from_str_radix(s, 10).ok()?)) + } + + pub fn div_c(self, other: u64) -> Self { + Self { size_bytes: self.size_bytes / other } + } + + /// + /// Panics if overflow accurs. + /// + pub fn mul_c(self, other: u64) -> Self { + Self { size_bytes: self.size_bytes.strict_mul(other) } + } + +} + +impl Add for KiraSize { + type Output = KiraSize; + + fn add(self, other: KiraSize) -> Self::Output { + KiraSize { + size_bytes: self.size_bytes + other.size_bytes, + } + } +} + +impl Sub for KiraSize { + type Output = KiraSize; + + /// Panics if overflow accors. + fn sub(self, other: KiraSize) -> Self::Output { + KiraSize { + size_bytes: self.size_bytes.strict_sub(other.size_bytes), + } + } +} +