Change underlying type of BufferId to NonZeroU64.

Piotr Osiewicz created

Change summary

crates/collab/src/db/tests/buffer_tests.rs |  4 ++--
crates/project/src/project.rs              |  2 +-
crates/text/src/text.rs                    | 12 +++++++-----
3 files changed, 10 insertions(+), 8 deletions(-)

Detailed changes

crates/collab/src/db/tests/buffer_tests.rs 🔗

@@ -67,7 +67,7 @@ async fn test_channel_buffers(db: &Arc<Database>) {
         .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<Database>) {
 
     let mut buffer_b = Buffer::new(
         0,
-        text::BufferId::new(0).unwrap(),
+        text::BufferId::new(1).unwrap(),
         buffer_response_b.base_text,
     );
     buffer_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(),

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<Self> {
+        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<BufferId> for u64 {
     fn from(id: BufferId) -> Self {
-        id.0
+        id.0.get()
     }
 }