Skip to content

Instantly share code, notes, and snippets.

@colelawrence
Created September 9, 2020 13:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save colelawrence/978bd3722813e55d5dfa684306d75045 to your computer and use it in GitHub Desktop.
Save colelawrence/978bd3722813e55d5dfa684306d75045 to your computer and use it in GitHub Desktop.
Change `Tracked` container for Rust to be used with Shipyard
use std::{fmt, mem, ops::Deref};
pub struct Tracked<T: ?Sized>(InnerTrackedState, T);
#[derive(PartialEq)]
enum InnerTrackedState {
New,
Modified,
NoChanges,
}
impl<T> Tracked<T> {
pub fn new(value: T) -> Self {
Tracked(InnerTrackedState::New, value)
}
pub fn reset_tracking(&mut self) {
self.0 = InnerTrackedState::NoChanges;
}
pub fn is_new_or_modified(&self) -> bool {
return self.0 != InnerTrackedState::NoChanges;
}
pub fn replace(&mut self, mut new_value: T) -> T {
mem::swap(&mut self.1, &mut new_value);
self.0 = InnerTrackedState::Modified;
new_value
}
pub fn get_mut(&mut self) -> &mut T {
self.0 = InnerTrackedState::Modified;
&mut self.1
}
}
impl<T: ?Sized> Tracked<T> {}
impl<T: ?Sized> Deref for Tracked<T> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &T {
&self.1
}
}
impl<T: ?Sized> AsRef<T> for Tracked<T> {
fn as_ref(&self) -> &T {
&**self
}
}
impl<T: ?Sized + fmt::Display> fmt::Display for Tracked<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&**self, f)
}
}
impl<T: ?Sized + fmt::Debug> fmt::Debug for Tracked<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment