use thiserror::Error;
#[derive(Error, Debug)]
pub enum Error {
#[error("HTTP error: {0}")]
Http(#[from] reqwest::Error),
#[error("JSON deserialization error: {0}")]
Deserialization(#[from] serde_json::Error),
#[error("JSON deserialization failed: {source}\nSnippet:\n{snippet}")]
DeserializationWithSnippet {
source: serde_json::Error,
snippet: String,
},
#[error("SSE event did not include an event type")]
MissingSseEventType,
#[error("SSE event did not include data")]
MissingSseData,
#[error("Unknown SSE event type: {0}")]
UnknownSseEventType(String),
#[error("Too many retries")]
TooManyRetry(Vec<Error>),
}
pub type Result<T> = core::result::Result<T, Error>;
pub fn snippet_around(
full: &str,
line: usize,
column: usize,
context: usize,
) -> String {
let mut current_line = 1;
let mut idx = 0;
let bytes = full.as_bytes();
while current_line < line && idx < bytes.len() {
if bytes[idx] == b'\n' {
current_line += 1;
}
idx += 1;
}
let mut error_byte = idx.saturating_add(column.saturating_sub(1));
if error_byte > bytes.len() {
error_byte = bytes.len();
}
let start = error_byte.saturating_sub(context);
let end = (error_byte + context).min(full.len());
let mut result = String::new();
if start > 0 {
result.push('…');
}
result.push_str(&full[start..end]);
if end < full.len() {
result.push('…');
}
result
}