use {
crate::mm::{Buffer, BufferId, Position, Rope},
std::time::SystemTime,
};
#[derive(Debug, Clone)]
pub struct Snapshot {
text: Rope,
cursor: Position,
buffer_id: BufferId,
timestamp: SystemTime,
}
impl Snapshot {
#[must_use]
pub fn capture(buffer: &Buffer, cursor: Position) -> Self {
Self {
text: buffer.clone_rope(),
cursor,
buffer_id: buffer.id(),
timestamp: SystemTime::now(),
}
}
#[must_use]
pub fn from_parts(
lines: &[String],
cursor: Position,
buffer_id: BufferId,
timestamp: SystemTime,
) -> Self {
let content = lines.join("\n");
let text = if content.is_empty() {
Rope::new()
} else {
Rope::from_str(&content)
};
Self {
text,
cursor,
buffer_id,
timestamp,
}
}
pub fn restore(&self, buffer: &mut Buffer) -> Position {
buffer.set_rope(self.text.clone());
self.cursor
}
#[must_use]
pub const fn cursor(&self) -> Position {
self.cursor
}
#[must_use]
pub fn lines(&self) -> Vec<String> {
(0..self.text.line_count())
.filter_map(|i| self.text.line(i).map(String::from))
.collect()
}
#[must_use]
pub const fn buffer_id(&self) -> BufferId {
self.buffer_id
}
#[must_use]
pub const fn timestamp(&self) -> SystemTime {
self.timestamp
}
#[must_use]
pub fn matches_buffer(&self, buffer: &Buffer) -> bool {
self.buffer_id == buffer.id()
}
#[must_use]
pub fn char_count(&self) -> usize {
self.text.char_len()
}
#[must_use]
pub fn line_count(&self) -> usize {
self.text.line_count()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.text.is_empty()
}
}