diff --git a/crates/collab/src/db/tests/buffer_tests.rs b/crates/collab/src/db/tests/buffer_tests.rs index 0d7438b517..de02c2b7b0 100644 --- a/crates/collab/src/db/tests/buffer_tests.rs +++ b/crates/collab/src/db/tests/buffer_tests.rs @@ -67,7 +67,7 @@ async fn test_channel_buffers(db: &Arc) { .await .unwrap(); - let mut buffer_a = Buffer::new(0, text::BufferId::new(0).unwrap(), "".to_string()); + let mut buffer_a = Buffer::new(0, text::BufferId::new(1).unwrap(), "".to_string()); let mut operations = Vec::new(); operations.push(buffer_a.edit([(0..0, "hello world")])); operations.push(buffer_a.edit([(5..5, ", cruel")])); @@ -92,7 +92,7 @@ async fn test_channel_buffers(db: &Arc) { let mut buffer_b = Buffer::new( 0, - text::BufferId::new(0).unwrap(), + text::BufferId::new(1).unwrap(), buffer_response_b.base_text, ); buffer_b diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 9b1a59ce85..50b886e44b 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -722,7 +722,7 @@ impl Project { worktrees: Vec::new(), buffer_ordered_messages_tx: tx, loading_buffers_by_path: Default::default(), - next_buffer_id: BufferId::default(), + next_buffer_id: BufferId::new(1).unwrap(), opened_buffer: watch::channel(), shared_buffers: Default::default(), incomplete_remote_buffers: Default::default(), diff --git a/crates/text/src/text.rs b/crates/text/src/text.rs index 9ce9efe7e0..fc2cf3b753 100644 --- a/crates/text/src/text.rs +++ b/crates/text/src/text.rs @@ -11,7 +11,7 @@ mod tests; mod undo_map; pub use anchor::*; -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Context as _, Result}; pub use clock::ReplicaId; use collections::{HashMap, HashSet}; use locator::Locator; @@ -29,6 +29,7 @@ use std::{ fmt::Display, future::Future, iter::Iterator, + num::NonZeroU64, ops::{self, Deref, Range, Sub}, str, sync::Arc, @@ -61,8 +62,8 @@ pub struct Buffer { } #[repr(transparent)] -#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, PartialOrd, Ord, Eq)] -pub struct BufferId(u64); +#[derive(Clone, Copy, Debug, Hash, PartialEq, PartialOrd, Ord, Eq)] +pub struct BufferId(NonZeroU64); impl Display for BufferId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -73,19 +74,20 @@ impl Display for BufferId { impl BufferId { /// Returns Err if `id` is outside of BufferId domain. pub fn new(id: u64) -> anyhow::Result { + let id = NonZeroU64::new(id).context("Buffer id cannot be 0.")?; Ok(Self(id)) } /// Increments this buffer id, returning the old value. /// So that's a post-increment operator in disguise. pub fn next(&mut self) -> Self { let old = *self; - self.0 += 1; + self.0 = self.0.saturating_add(1); old } } impl From for u64 { fn from(id: BufferId) -> Self { - id.0 + id.0.get() } }