use std::fmt::Display;
#[derive(Debug, Clone, PartialEq)]
pub enum MemoryNum {
B(u32),
Kb(u32),
Mb(u32),
Gb(u32),
}
impl MemoryNum {
pub fn parse(string: &str) -> Option<Self> {
Some(match string.chars().last()? {
'k' | 'K' => Self::Kb(string[..string.len() - 1].parse().ok()?),
'm' | 'M' => Self::Mb(string[..string.len() - 1].parse().ok()?),
'g' | 'G' => Self::Gb(string[..string.len() - 1].parse().ok()?),
_ => Self::B(string.parse().ok()?),
})
}
pub fn to_bytes(&self) -> u32 {
match self {
Self::B(n) => *n,
Self::Kb(n) => *n * 1024,
Self::Mb(n) => *n * 1024 * 1024,
Self::Gb(n) => *n * 1024 * 1024 * 1024,
}
}
pub fn avg(left: Self, right: Self) -> Self {
Self::B((left.to_bytes() + right.to_bytes()) / 2)
}
}
impl Display for MemoryNum {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::B(n) => n.to_string(),
Self::Kb(n) => n.to_string() + "k",
Self::Mb(n) => n.to_string() + "m",
Self::Gb(n) => n.to_string() + "g",
}
)
}
}
pub enum MemoryArg {
Min,
Max,
}
impl MemoryArg {
pub fn to_string(&self, n: &MemoryNum) -> String {
let arg = match self {
Self::Min => "-Xms".to_string(),
Self::Max => "-Xmx".to_string(),
};
arg + &n.to_string()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_mem_parse() {
assert_eq!(MemoryNum::parse("2358"), Some(MemoryNum::B(2358)));
assert_eq!(MemoryNum::parse("0798m"), Some(MemoryNum::Mb(798)));
assert_eq!(MemoryNum::parse("1G"), Some(MemoryNum::Gb(1)));
assert_eq!(MemoryNum::parse("5a"), None);
assert_eq!(MemoryNum::parse("fooG"), None);
assert_eq!(MemoryNum::parse(""), None);
}
#[test]
fn test_mem_arg_output() {
assert_eq!(
MemoryArg::Max.to_string(&MemoryNum::Gb(4)),
"-Xmx4g".to_string()
);
assert_eq!(
MemoryArg::Min.to_string(&MemoryNum::B(128)),
"-Xms128".to_string()
);
}
}