use serde::{Deserialize, Serialize};
use super::Buffer;
use crate::history::History;
use crate::id::BufferRevision;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BufferSeed {
pub text: String,
pub revision: BufferRevision,
pub history: History,
#[serde(with = "crate::path_serde::option")]
pub path: Option<std::path::PathBuf>,
pub name: Option<String>,
pub dirty: bool,
pub readonly: bool,
pub disk_stamp: Option<std::time::SystemTime>,
#[serde(with = "crate::path_serde::option")]
pub file_identity: Option<std::path::PathBuf>,
}
impl Buffer {
pub fn seed(&self) -> BufferSeed {
BufferSeed {
text: self.rope.to_string(),
revision: self.revision(),
history: self.history.clone(),
path: self.path.clone(),
name: self.name.clone(),
dirty: self.dirty,
readonly: self.readonly,
disk_stamp: self.disk_stamp,
file_identity: self.file_identity.clone(),
}
}
}
impl BufferSeed {
pub fn into_buffer(self) -> Result<Buffer, crate::history::HistoryError> {
let mut buffer = Buffer::from_text(&self.text);
buffer.restore_history(self.history)?;
buffer.epoch = self.revision.get();
buffer.path = self.path;
buffer.name = self.name;
buffer.dirty = self.dirty;
buffer.readonly = self.readonly;
buffer.disk_stamp = self.disk_stamp;
buffer.file_identity = self.file_identity;
Ok(buffer)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn seed_round_trips_content_history_and_disk_baseline() {
let mut buffer = Buffer::from_text("line\nline two\n");
buffer.begin_undo_group();
buffer
.edit()
.replace(crate::Range::charwise(5, 8), "XY")
.unwrap();
buffer.commit_undo_group();
buffer.dirty = true;
buffer.disk_stamp = Some(std::time::UNIX_EPOCH);
let seed = buffer.seed();
let mut restored = seed.into_buffer().unwrap();
assert_eq!(restored.text().to_string(), "line\nXYe two\n");
restored.undo().unwrap();
assert_eq!(restored.text().to_string(), "line\nline two\n");
}
#[test]
fn history_that_disagrees_with_text_is_rejected() {
let mut buffer = Buffer::from_text("abc\n");
buffer.begin_undo_group();
buffer
.edit()
.replace(crate::Range::charwise(0, 1), "z")
.unwrap();
buffer.commit_undo_group();
let mut seed = buffer.seed();
seed.text = "different bytes\n".into();
assert!(seed.into_buffer().is_err());
}
}