openai_sdk_rs/
sse.rs

1use serde::de::DeserializeOwned;
2
3// Extract "data: ..." lines from SSE bytes (excluding comments and [DONE])
4pub fn extract_data_lines_from_bytes(bytes: &[u8]) -> Vec<String> {
5    let mut out = Vec::new();
6    for line in bytes.split(|b| *b == b'\n') {
7        if line.is_empty() { continue; }
8        let mut l = line;
9        if let Some(last) = l.last() { if *last == b'\r' { l = &l[..l.len()-1]; } }
10        if l.is_empty() || l[0] == b':' { continue; }
11        if let Some(rest) = l.strip_prefix(b"data: ") {
12            if rest == b"[DONE]" { continue; }
13            out.push(String::from_utf8(rest.to_vec()).unwrap_or_default());
14        }
15    }
16    out
17}
18
19// Parse JSON values from SSE bytes. Invalid JSON lines are skipped.
20pub fn extract_json_values_from_bytes(bytes: &[u8]) -> Vec<serde_json::Value> {
21    extract_data_lines_from_bytes(bytes)
22        .into_iter()
23        .filter_map(|s| serde_json::from_str::<serde_json::Value>(&s).ok())
24        .collect()
25}
26
27// Deserialize typed items from SSE bytes. Invalid lines are skipped.
28pub fn extract_typed_from_bytes<T: DeserializeOwned>(bytes: &[u8]) -> Vec<T> {
29    extract_data_lines_from_bytes(bytes)
30        .into_iter()
31        .filter_map(|s| serde_json::from_str::<T>(&s).ok())
32        .collect()
33}
34
35// String variants
36pub fn extract_data_lines_from_str(text: &str) -> Vec<&str> {
37    text.lines()
38        .filter_map(|l| {
39            let l = l.trim_end_matches('\r');
40            if l.is_empty() || l.starts_with(':') { return None; }
41            l.strip_prefix("data: ")
42        })
43        .filter(|rest| *rest != "[DONE]")
44        .collect()
45}
46
47pub fn extract_json_values_from_str(text: &str) -> Vec<serde_json::Value> {
48    extract_data_lines_from_str(text)
49        .into_iter()
50        .filter_map(|s| serde_json::from_str::<serde_json::Value>(s).ok())
51        .collect()
52}
53
54pub fn extract_typed_from_str<T: DeserializeOwned>(text: &str) -> Vec<T> {
55    extract_data_lines_from_str(text)
56        .into_iter()
57        .filter_map(|s| serde_json::from_str::<T>(s).ok())
58        .collect()
59}
60
61// Result variants (fail on first invalid JSON)
62pub fn try_extract_json_values_from_str(text: &str) -> Result<Vec<serde_json::Value>, serde_json::Error> {
63    let mut out = Vec::new();
64    for s in extract_data_lines_from_str(text) { out.push(serde_json::from_str::<serde_json::Value>(s)?); }
65    Ok(out)
66}
67
68pub fn try_extract_typed_from_str<T: DeserializeOwned>(text: &str) -> Result<Vec<T>, serde_json::Error> {
69    let mut out = Vec::new();
70    for s in extract_data_lines_from_str(text) { out.push(serde_json::from_str::<T>(s)?); }
71    Ok(out)
72}