use warp_util::content_version::ContentVersion; // Re-export from warp_util so existing app-level imports continue to work. pub use warp_util::local_or_remote_path::LocalOrRemotePath; /// Tracks sync state between client and server for a single remote buffer. /// /// Uses a version vector with two components: /// - `server_version`: bumped by the server when the file changes on disk. /// - `client_version`: bumped by the client when the user edits the buffer. /// /// Conflict detection: /// - Server pushes `{S_new, C_expected}`. Client checks `C_expected == local client_version`. /// Match → accept. Mismatch → conflict. /// - Client sends `{S_expected, C_new}`. Server checks `S_expected == local server_version`. /// Match → accept. Mismatch → reject (server pushes its current state). /// /// Both fields use `ContentVersion` internally. At the wire boundary (proto /// encode/decode), convert via `ContentVersion::as_u64()` and /// `ContentVersion::from_raw()`. #[derive(Clone, Debug)] pub struct SyncClock { /// Last version acknowledged from the server (file-watcher side). pub server_version: ContentVersion, /// Last version acknowledged from the client (user-edit side). pub client_version: ContentVersion, } impl SyncClock { #[cfg_attr(not(feature = "local_fs"), allow(dead_code))] pub fn new() -> Self { Self { server_version: ContentVersion::from_raw(0), client_version: ContentVersion::from_raw(0), } } /// Reconstruct a `SyncClock` from wire values (proto deserialization). pub fn from_wire(server_version: u64, client_version: u64) -> Self { Self { server_version: ContentVersion::from_raw(server_version as usize), client_version: ContentVersion::from_raw(client_version as usize), } } /// Bump the server version after a file-watcher change. #[cfg_attr(not(feature = "local_fs"), allow(dead_code))] pub fn bump_server(&mut self) -> ContentVersion { self.server_version = ContentVersion::new(); self.server_version } /// Check whether a server push's expected client version matches our local state. pub fn server_push_matches(&self, expected_client_version: ContentVersion) -> bool { self.client_version == expected_client_version } /// Check whether a client edit's expected server version matches our local state. #[cfg_attr(not(feature = "local_fs"), allow(dead_code))] pub fn client_edit_matches(&self, expected_server_version: ContentVersion) -> bool { self.server_version == expected_server_version } } #[cfg(test)] #[path = "buffer_location_tests.rs"] mod tests;