Skip to main content

claude_stream/
lib.rs

1//! Parse Anthropic's Server-Sent Events stream into typed events.
2//!
3//! No SDK dependency. Build it into whatever HTTP client / async runtime
4//! you already have: feed [`EventParser::feed`] bytes as they arrive,
5//! drain ready events with [`EventParser::next_event`].
6//!
7//! # Quick start
8//!
9//! ```
10//! use claude_stream::{EventParser, Event};
11//!
12//! // Wire bytes Anthropic sent us:
13//! let chunk = b"event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"id\":\"msg_1\",\"role\":\"assistant\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Hello\"}}\n\n";
14//!
15//! let mut parser = EventParser::new();
16//! parser.feed(chunk);
17//!
18//! // Drain everything ready:
19//! while let Some(event) = parser.next_event().unwrap() {
20//!     match event {
21//!         Event::MessageStart { message } => println!("started: {}", message.id),
22//!         Event::ContentBlockDelta { delta, .. } => {
23//!             if let claude_stream::Delta::TextDelta { text } = delta {
24//!                 print!("{text}");
25//!             }
26//!         }
27//!         _ => {}
28//!     }
29//! }
30//! ```
31#![forbid(unsafe_code)]
32#![warn(missing_docs)]
33#![warn(rust_2018_idioms)]
34
35mod event;
36mod parser;
37
38pub use crate::event::{ContentBlock, Delta, Event, Message, MessageDelta, ParseError, Usage};
39pub use crate::parser::EventParser;