spaceterm_proto/lib.rs
1//! Terminal Block Protocol (TBP) v1: wire types and codec.
2//!
3//! TBP is an OSC escape sequence carrying a MIME bundle, directly inspired by
4//! Jupyter's `display_data` message. A tool emits a block as one escape; the
5//! terminal selects the richest MIME representation it can render and falls back
6//! toward `text/plain`. Terminals that do not understand TBP ignore the escape.
7//!
8//! The wire form is documented normatively in
9//! `docs/terminal-block-protocol-spec.md`; this crate is its reference codec.
10//! See [`encode`] and [`decode`] for the byte-stream entry points.
11
12mod bundle;
13mod caps;
14mod message;
15mod tier;
16mod wire;
17
18pub use bundle::{BlockMeta, MimeBundle, TEXT_PLAIN};
19pub use caps::Caps;
20pub use message::{EmitBlock, Message, OpenBlock, PatchBlock};
21pub use tier::TrustTier;
22pub use wire::{decode, decode_with_sidechannel, encode, ProtoError};
23
24// ============================================================================
25// Constants
26// ============================================================================
27
28/// Protocol version this crate emits and is the highest it accepts.
29pub const PROTOCOL_VERSION: Version = Version(1);
30
31/// Private-use OSC number that frames every TBP message. Provisional; the final
32/// number is coordinated with other terminals before 1.0.
33pub const OSC_NUMBER: u32 = 9001;
34
35// ============================================================================
36// Data Structures
37// ============================================================================
38
39/// TBP protocol version. Wire form is a bare integer.
40#[derive(
41 Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Deserialize, serde::Serialize,
42)]
43#[serde(transparent)]
44pub struct Version(pub u16);
45
46/// Identifier correlating live-block updates (`open`/`patch`/`close`) and
47/// distinguishing concurrent blocks within one session.
48#[derive(
49 Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, serde::Deserialize, serde::Serialize,
50)]
51#[serde(transparent)]
52pub struct BlockId(pub u64);
53
54// ============================================================================
55// Version
56// ============================================================================
57
58impl Version {
59 /// Whether a bundle declaring this version can be rendered by this crate.
60 /// A terminal accepts any version at or below the one it implements.
61 pub fn is_supported(self) -> bool {
62 self.0 <= PROTOCOL_VERSION.0
63 }
64}
65
66// ============================================================================
67// Tests
68// ============================================================================
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn test_current_version_is_supported() {
76 assert!(PROTOCOL_VERSION.is_supported());
77 }
78
79 #[test]
80 fn test_future_version_is_unsupported() {
81 let future = Version(PROTOCOL_VERSION.0 + 1);
82 assert!(!future.is_supported());
83 }
84}