use std::fmt;
pub const MAX_WINDOW_SIZE: u32 = 0x7fffffff;
#[test]
fn test_max_window_size_is_i32_max() {
use std::i32;
assert_eq!(i32::max_value(), MAX_WINDOW_SIZE as i32);
}
pub const MIN_WINDOW_SIZE: i32 = 0 - MAX_WINDOW_SIZE as i32;
pub const MAX_WINDOW_SIZE_INC: u32 = 0x7fffffff;
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct WindowSize(i32);
impl WindowSize {
pub fn try_add(&mut self, delta: i32) -> Result<(), ()> {
self.0 = match self.0.checked_add(delta) {
Some(r) if r < MIN_WINDOW_SIZE => return Err(()),
Some(r) => r,
None => return Err(()),
};
Ok(())
}
pub fn try_increase(&mut self, delta: u32) -> Result<(), ()> {
if delta > MAX_WINDOW_SIZE_INC || delta == 0 {
return Err(());
}
self.try_add(delta as i32)
}
pub fn try_decrease(&mut self, delta: i32) -> Result<(), ()> {
match self.0.checked_sub(delta) {
Some(new) => {
self.0 = new;
Ok(())
}
None => Err(()),
}
}
pub fn try_decrease_to_non_negative(&mut self, delta: i32) -> Result<(), ()> {
match self.0.checked_sub(delta) {
Some(new) if new >= 0 => {
self.0 = new;
Ok(())
}
_ => Err(()),
}
}
pub fn new(size: i32) -> WindowSize {
WindowSize(size)
}
pub fn size(&self) -> i32 {
self.0
}
pub fn unsigned(&self) -> u32 {
let r = self.0 as u32;
assert_eq!(r as i32, self.0);
r
}
}
impl fmt::Display for WindowSize {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
pub(crate) struct NonNegativeWindowSize(WindowSize);
impl NonNegativeWindowSize {
pub fn new(size: i32) -> NonNegativeWindowSize {
assert!(size >= 0);
NonNegativeWindowSize(WindowSize::new(size))
}
pub fn size(&self) -> i32 {
self.0.size()
}
pub fn try_decrease_to_non_negative(&mut self, delta: i32) -> Result<(), ()> {
self.0.try_decrease_to_non_negative(delta)
}
pub fn try_increase(&mut self, delta: u32) -> Result<(), ()> {
self.0.try_increase(delta)
}
}