Skip to content

Instantly share code, notes, and snippets.

@MasWag
Created January 4, 2025 06:42
Show Gist options
  • Save MasWag/09511cddaef9f7974f1bc12047718095 to your computer and use it in GitHub Desktop.
Save MasWag/09511cddaef9f7974f1bc12047718095 to your computer and use it in GitHub Desktop.
Sequence with dynamic update in Rust
use std::rc::Rc;
use std::cell::{Ref, RefCell};
struct AppendOnlySequence<T> {
data: Rc<RefCell<Vec<T>>>,
}
impl<T> AppendOnlySequence<T> {
pub fn new() -> Self {
Self {
data: Rc::new(RefCell::new(Vec::new())),
}
}
pub fn append(&mut self, value: T) {
self.data.borrow_mut().push(value);
}
pub fn clear(&mut self) {
self.data.borrow_mut().clear();
}
pub fn readable_view(&self) -> ReadableView<T> {
ReadableView::new(Rc::clone(&self.data))
}
}
pub struct ReadableView<T> {
data: Rc<RefCell<Vec<T>>>, // Shared ownership of the sequence
start: usize, // Start index of the readable range
}
impl<T> ReadableView<T> {
pub fn new(data: Rc<RefCell<Vec<T>>>) -> Self {
Self { data, start: 0 }
}
pub fn advance_readable(&mut self, count: usize) {
let len = self.data.borrow().len();
self.start = usize::min(self.start + count, len);
}
pub fn readable_slice(&self) -> Ref<'_, [T]> {
Ref::map(self.data.borrow(), |vec| &vec[self.start..])
}
}
fn main() {
let mut sequence = AppendOnlySequence::new();
// Append some data
sequence.append(1);
sequence.append(2);
sequence.append(3);
// Create a readable view
let mut part = sequence.readable_view();
println!("Readable: {:?}", part.readable_slice()); // [1, 2, 3]
// Advance the readable portion
part.advance_readable(1);
println!("Readable: {:?}", part.readable_slice()); // [2, 3]
// Append more data
sequence.append(4);
sequence.append(5);
// The readable view reflects the new data
println!("Readable: {:?}", part.readable_slice()); // [2, 3, 4, 5]
// Advance the readable portion again
part.advance_readable(2);
println!("Readable: {:?}", part.readable_slice()); // [4, 5]
// Clear the sequence
sequence.clear();
let mut part = sequence.readable_view(); // Create a new view since the old data is invalid
println!("Readable after clearing: {:?}", part.readable_slice()); // []
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment