Created
January 4, 2025 06:42
-
-
Save MasWag/09511cddaef9f7974f1bc12047718095 to your computer and use it in GitHub Desktop.
Sequence with dynamic update in Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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