polyc-llm 0.1.3

Provider-agnostic LLM trait + wire types for polychrome.
Documentation
//! Shared Server-Sent Events framing helpers for streaming providers.
//!
//! Both the Vertex and OpenAI-compatible backends read SSE: `data:` lines
//! grouped into events separated by a blank line. This module owns the one
//! load-bearing primitive — finding the next event boundary in a byte buffer —
//! so the providers don't each carry (and drift on) their own copy.

/// Locate the **earliest** SSE event separator in `buf`, returning
/// `(offset_of_first_separator_byte, separator_len)`.
///
/// SSE events end with a blank line: `\n\n` (LF, the spec form) or `\r\n\r\n`
/// (CRLF, what many HTTP servers — including Google's — emit). A buffer can
/// hold a mix, so this returns whichever boundary comes **first** rather than
/// always preferring one kind; preferring CRLF unconditionally would merge
/// `a\n\nb\r\n\r\n` into a single event. Returns `None` when no complete event
/// is buffered yet.
#[must_use]
pub fn next_event_boundary(buf: &[u8]) -> Option<(usize, usize)> {
    let crlf = buf.windows(4).position(|w| w == b"\r\n\r\n");
    let lf = buf.windows(2).position(|w| w == b"\n\n");
    match (crlf, lf) {
        // The LF scan also matches the trailing `\n\n` *inside* a `\r\n\r\n`
        // (one byte later), so on a tie / overlap the CRLF boundary is the
        // real one and must win.
        (Some(c), Some(l)) if c <= l => Some((c, 4)),
        (_, Some(l)) => Some((l, 2)),
        (Some(c), None) => Some((c, 4)),
        (None, None) => None,
    }
}

#[cfg(test)]
mod tests {
    #![allow(clippy::pedantic, clippy::nursery, missing_docs)]
    use super::next_event_boundary;

    #[test]
    fn finds_lf_boundary() {
        assert_eq!(next_event_boundary(b"data: x\n\nmore"), Some((7, 2)));
    }

    #[test]
    fn finds_crlf_boundary() {
        assert_eq!(next_event_boundary(b"data: x\r\n\r\nmore"), Some((7, 4)));
    }

    #[test]
    fn returns_none_when_no_separator() {
        assert_eq!(next_event_boundary(b"data: partial"), None);
    }

    #[test]
    fn returns_the_earliest_of_mixed_delimiters() {
        // `a\n\nb\r\n\r\n`: the LF boundary at 1 comes before the CRLF at 4;
        // returning the CRLF first would conflate the two events.
        assert_eq!(next_event_boundary(b"a\n\nb\r\n\r\n"), Some((1, 2)));
    }
}