pub struct Context<F: crate::SequenceFactory = crate::TimeSequenceFactory> {
sequence_factory: F,
sequence: F::Sequence,
session: Session,
}
impl Default for Context<crate::TimeSequenceFactory> {
fn default() -> Self {
Self::new()
}
}
impl<SequenceFactory: crate::SequenceFactory + Default> Context<SequenceFactory> {
pub fn new() -> Self {
Context {
sequence_factory: Default::default(),
sequence: SequenceFactory::base(),
session: Session::new(),
}
}
}
impl<SequenceFactory: crate::SequenceFactory> Context<SequenceFactory> {
pub fn next_sequence(&mut self) -> Sequence<SequenceFactory> {
let next = self.sequence_factory.acquire(self.sequence.clone());
assert!(next > self.sequence);
self.sequence = next.clone();
Sequence {
value: next,
session: self.session.clone(),
undo: 0,
}
}
pub fn new_session(&mut self) {
self.session = Session::new();
}
pub fn session(&self) -> Session {
self.session.clone()
}
}
pub struct Sequence<SequenceFactory: crate::SequenceFactory> {
value: SequenceFactory::Sequence,
session: Session,
undo: u8,
}
impl<SequenceFactory: crate::SequenceFactory> Sequence<SequenceFactory> {
pub fn zero() -> Self {
Sequence {
value: SequenceFactory::base(),
session: Session(u64::min_value()),
undo: 0,
}
}
pub fn undo(&self) -> Result<Self, crate::RevertError> {
let mut r = self.clone();
r.undo = self.undo.checked_add(1)
.ok_or(crate::RevertError::TooManyRedos)?;
Ok(r)
}
}
impl<T: crate::SequenceFactory> std::fmt::Debug for Sequence<T>
where T::Sequence: std::fmt::Debug
{
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let Sequence{value, session, undo} = self;
write!(f, "Sequence({:?}, {:?}, {:?})", value, session, undo)
}
}
impl<SequenceFactory: crate::SequenceFactory> Clone for Sequence<SequenceFactory> {
fn clone(&self) -> Self {
Sequence {
value: self.value.clone(),
session: self.session.clone(),
undo: self.undo,
}
}
}
impl<SequenceFactory: crate::SequenceFactory> std::cmp::PartialEq for Sequence<SequenceFactory> {
fn eq(&self, that: &Self) -> bool {
let Sequence{value, session, undo} = self;
(value, session, undo) == (&that.value, &that.session, &that.undo)
}
}
impl<SequenceFactory: crate::SequenceFactory> std::cmp::Eq for Sequence<SequenceFactory> {
}
impl<SequenceFactory: crate::SequenceFactory> std::cmp::PartialOrd for Sequence<SequenceFactory> {
fn partial_cmp(&self, that: &Self) -> Option<std::cmp::Ordering> {
let Sequence{value, session, undo} = self;
std::cmp::PartialOrd::partial_cmp(
&(value, session, undo),
&(&that.value, &that.session, &that.undo))
}
}
impl<SequenceFactory: crate::SequenceFactory> std::cmp::Ord for Sequence<SequenceFactory> {
fn cmp(&self, that: &Self) -> std::cmp::Ordering {
let Sequence{value, session, undo} = self;
(value, session, undo).cmp(&(&that.value, &that.session, &that.undo))
}
}
impl<SequenceFactory: crate::SequenceFactory> std::hash::Hash for Sequence<SequenceFactory> {
fn hash<H: std::hash::Hasher>(&self, h: &mut H) {
let Sequence{value, session, undo} = self;
value.hash(h);
session.hash(h);
undo.hash(h);
}
}
#[derive(Clone,Eq,PartialEq,Hash,Ord,PartialOrd)]
pub struct Session(u64);
impl Session {
pub fn new() -> Self {
Self::unsafe_from_u64(rand::Rng::gen(&mut rand::thread_rng()))
}
pub fn unsafe_from_u64(session: u64) -> Self {
Session(session)
}
}
impl std::fmt::Debug for Session {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Session({:x})", self.0)
}
}