#[must_use]
pub fn stream_error_frame(data: &str) -> Option<a2a_protocol_types::A2aError> {
crate::transport::rest::error_frame::decode_stream_error_frame(data)
}
#[must_use]
pub fn aip193_error(body: &[u8]) -> Option<a2a_protocol_types::A2aError> {
crate::transport::rest::request::parse_aip193_error(body)
}
#[must_use]
pub fn retry_after(value: &[u8]) -> Option<std::time::Duration> {
let value = hyper::header::HeaderValue::from_bytes(value).ok()?;
let mut headers = hyper::HeaderMap::new();
headers.insert(hyper::header::RETRY_AFTER, value);
crate::error::parse_retry_after(&headers)
}
#[cfg(feature = "websocket")]
#[must_use]
pub fn websocket_frame_id(text: &str) -> Option<String> {
crate::transport::websocket::extract_jsonrpc_id(text)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn forwards_the_stream_error_frame() {
let err = stream_error_frame(r#"{"code":-32001,"message":"gone"}"#).expect("error frame");
assert_eq!(err.message, "gone");
assert!(stream_error_frame(r#"{"statusUpdate":{}}"#).is_none());
}
#[test]
fn forwards_the_aip193_body() {
let body = br#"{"error":{"message":"m","details":[{"@type":"type.googleapis.com/google.rpc.ErrorInfo","reason":"TASK_NOT_FOUND"}]}}"#;
assert_eq!(
aip193_error(body).expect("aip-193").code,
a2a_protocol_types::ErrorCode::TaskNotFound
);
}
#[test]
fn forwards_the_retry_after_header() {
assert_eq!(retry_after(b"7"), Some(std::time::Duration::from_secs(7)));
assert_eq!(
retry_after(b"999999"),
Some(std::time::Duration::from_secs(3600))
);
assert_eq!(retry_after(b"Wed, 21 Oct 2015 07:28:00 GMT"), None);
}
#[cfg(feature = "websocket")]
#[test]
fn forwards_the_websocket_frame_id() {
assert_eq!(websocket_frame_id(r#"{"id":"a"}"#).as_deref(), Some("a"));
assert_eq!(websocket_frame_id(r#"{"id":7}"#).as_deref(), Some("7"));
}
}