perfection

This commit is contained in:
Quaternions 2024-07-31 14:35:43 -07:00
parent 78db4168a5
commit ccadc934ac

@ -92,27 +92,7 @@ pub struct TimerFixed<T:TimerState,P:PauseState>{
_paused:P, _paused:P,
} }
pub enum Timer{ //constructors are generic across PauseState
Paused(TimerFixed<Realtime,Paused>),
Unpaused(TimerFixed<Realtime,Unpaused>),
}
pub enum TimerScaled{
Paused(TimerFixed<Scaled,Paused>),
Unpaused(TimerFixed<Scaled,Unpaused>),
}
#[derive(Debug)]
pub enum Error{
AlreadyPaused,
AlreadyUnpaused,
}
impl std::fmt::Display for Error{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
write!(f,"{self:?}")
}
}
impl std::error::Error for Error{}
impl<P:PauseState> TimerFixed<Realtime,P>{ impl<P:PauseState> TimerFixed<Realtime,P>{
pub fn new(time:Time,new_time:Time)->Self{ pub fn new(time:Time,new_time:Time)->Self{
let mut timer=Self{ let mut timer=Self{
@ -137,6 +117,31 @@ impl<P:PauseState> TimerFixed<Scaled,P>{
} }
} }
//pause and unpause is generic across TimerState
impl<T:TimerState> TimerFixed<T,Paused>{
pub fn unpause(self,time:Time)->TimerFixed<T,Unpaused>{
let new_time=self.time(time);
let mut timer=TimerFixed{
state:self.state,
_paused:Unpaused,
};
timer.set_time(time,new_time);
timer
}
}
impl<T:TimerState> TimerFixed<T,Unpaused>{
pub fn pause(self,time:Time)->TimerFixed<T,Paused>{
let new_time=self.time(time);
let mut timer=TimerFixed{
state:self.state,
_paused:Paused,
};
timer.set_time(time,new_time);
timer
}
}
//time queries are generic across both
impl<T:TimerState,P:PauseState> TimerFixed<T,P>{ impl<T:TimerState,P:PauseState> TimerFixed<T,P>{
pub fn time(&self,time:Time)->Time{ pub fn time(&self,time:Time)->Time{
match P::IS_PAUSED{ match P::IS_PAUSED{
@ -150,32 +155,48 @@ impl<T:TimerState,P:PauseState> TimerFixed<T,P>{
false=>self.state.set_time(time,new_time), false=>self.state.set_time(time,new_time),
} }
} }
}
#[derive(Debug)]
pub enum Error{
AlreadyPaused,
AlreadyUnpaused,
}
impl std::fmt::Display for Error{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
write!(f,"{self:?}")
}
}
impl std::error::Error for Error{}
//wrapper types which hold type state internally
pub enum Timer<T:TimerState>{
Paused(TimerFixed<T,Paused>),
Unpaused(TimerFixed<T,Unpaused>),
}
impl<T:TimerState> Timer<T>{
pub fn time(&self,time:Time)->Time{
match self{
Self::Paused(timer)=>timer.time(time),
Self::Unpaused(timer)=>timer.time(time),
}
}
pub fn set_time(&mut self,time:Time,new_time:Time){
match self{
Self::Paused(timer)=>timer.set_time(time,new_time),
Self::Unpaused(timer)=>timer.set_time(time,new_time),
}
}
pub fn pause(self,time:Time)->Result<TimerFixed<T,Paused>,Error>{ pub fn pause(self,time:Time)->Result<TimerFixed<T,Paused>,Error>{
match P::IS_PAUSED{ match self{
true=>Err(Error::AlreadyPaused), Self::Paused(_)=>Err(Error::AlreadyPaused),
false=>{ Self::Unpaused(timer)=>Ok(timer.pause(time)),
let new_time=self.time(time);
let mut timer=TimerFixed{
state:self.state,
_paused:Paused,
};
timer.set_time(time,new_time);
Ok(timer)
},
} }
} }
pub fn unpause(self,time:Time)->Result<TimerFixed<T,Unpaused>,Error>{ pub fn unpause(self,time:Time)->Result<TimerFixed<T,Unpaused>,Error>{
match P::IS_PAUSED{ match self{
true=>{ Self::Paused(timer)=>Ok(timer.unpause(time)),
let new_time=self.time(time); Self::Unpaused(_)=>Err(Error::AlreadyUnpaused),
let mut timer=TimerFixed{
state:self.state,
_paused:Unpaused,
};
timer.set_time(time,new_time);
Ok(timer)
},
false=>Err(Error::AlreadyUnpaused),
} }
} }
} }