81 lines
3.0 KiB
Rust
81 lines
3.0 KiB
Rust
//! Identity and range types — moved from `pmacs::buffer`,
|
|
//! `pmacs::protocol`, and `pmacs::rope` in session 1 of the
|
|
//! `pmacs-gpu` arc. The originals re-export these names so internal
|
|
//! `pmacs` imports (`crate::buffer::BufferId`, `crate::rope::Position`,
|
|
//! etc.) keep working unchanged.
|
|
|
|
use std::sync::atomic::{AtomicU64, Ordering};
|
|
|
|
/// Opaque, per-process identifier for a buffer.
|
|
///
|
|
/// The internal representation is private (R22): callers cannot reach
|
|
/// for `.0`; construction goes through [`BufferId::next`].
|
|
///
|
|
/// T M10.5: `Serialize` / `Deserialize` derived so `BufferId` can be
|
|
/// the routing key on `InstanceMessage::CrdtOp` / `FrontendEvent::CrdtOp`.
|
|
/// The serialized form is the bare `u64` (transparent newtype).
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, serde::Serialize, serde::Deserialize)]
|
|
pub struct BufferId(u64);
|
|
|
|
impl BufferId {
|
|
/// Allocate a fresh [`BufferId`] from the process-wide counter.
|
|
///
|
|
/// Threading: any thread.
|
|
#[must_use]
|
|
pub fn next() -> Self {
|
|
static COUNTER: AtomicU64 = AtomicU64::new(1);
|
|
Self(COUNTER.fetch_add(1, Ordering::Relaxed))
|
|
}
|
|
|
|
/// Inspect the raw value. Useful for logging and FFI.
|
|
#[must_use]
|
|
pub const fn raw(self) -> u64 {
|
|
self.0
|
|
}
|
|
|
|
/// Rebuild an ID from a raw value for crate-internal references that
|
|
/// persist an already-issued buffer identity in generated text.
|
|
///
|
|
/// Was `pub(crate)` before the session-1 crate split; promoted to
|
|
/// `pub` to remain reachable from `pmacs` after the move. Not
|
|
/// stable API for external consumers — external callers should
|
|
/// either round-trip via `serde` or accept that the constructor
|
|
/// may change.
|
|
#[must_use]
|
|
pub const fn from_raw(raw: u64) -> Self {
|
|
Self(raw)
|
|
}
|
|
}
|
|
|
|
/// Opaque identifier for a frontend attached to an instance.
|
|
///
|
|
/// Every input event carries a `FrontendId`. v0.1 uses one ID per
|
|
/// instance ([`FrontendId::LOCAL`]); v0.3 generalizes to multi-frontend
|
|
/// (multi-window, multi-user) without a protocol break.
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, serde::Serialize, serde::Deserialize)]
|
|
pub struct FrontendId(pub u64);
|
|
|
|
impl FrontendId {
|
|
/// The single frontend used in v0.1's local-attach mode.
|
|
///
|
|
/// Future multi-frontend deployments allocate IDs from a counter
|
|
/// starting after this value; the constant is reserved.
|
|
pub const LOCAL: FrontendId = FrontendId(1);
|
|
}
|
|
|
|
/// Byte offset into a rope. Buffer-wide; cursor / selection / span
|
|
/// anchors all use this type. Type alias rather than newtype so
|
|
/// arithmetic on offsets (slice ranges, byte deltas) doesn't need
|
|
/// conversions.
|
|
pub type Position = u64;
|
|
|
|
/// Half-open byte range `[start, end)` into a buffer's rope, matching
|
|
/// the rope's own range convention.
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
|
|
pub struct ByteRange {
|
|
/// Inclusive start byte offset.
|
|
pub start: u64,
|
|
/// Exclusive end byte offset.
|
|
pub end: u64,
|
|
}
|