mod chunks;
mod decode;
mod encode;
mod messages;
pub(super) use decode::decode_request;
pub(super) use encode::encode_response;
use serde_json::{Map, Value};
use super::IngressError;
fn err(message: impl std::fmt::Display) -> IngressError {
IngressError {
message: format!("openai_chat ingress: {message}"),
}
}
fn bad(path: &str, want: &str) -> IngressError {
err(format!("`{path}` must be {want}"))
}
fn str_of<'a>(v: Option<&'a Value>, path: &str) -> Result<&'a str, IngressError> {
v.and_then(Value::as_str)
.ok_or_else(|| bad(path, "a string"))
}
fn obj_of<'a>(v: Option<&'a Value>, path: &str) -> Result<&'a Map<String, Value>, IngressError> {
v.and_then(Value::as_object)
.ok_or_else(|| bad(path, "an object"))
}
fn arr_of<'a>(v: Option<&'a Value>, path: &str) -> Result<&'a [Value], IngressError> {
v.and_then(Value::as_array)
.map(Vec::as_slice)
.ok_or_else(|| bad(path, "an array"))
}
fn opt_str(v: Option<&Value>, path: &str) -> Result<Option<String>, IngressError> {
match v {
None | Some(Value::Null) => Ok(None),
Some(Value::String(s)) => Ok(Some(s.clone())),
Some(_) => Err(bad(path, "a string")),
}
}
fn opt_bool(v: Option<&Value>, path: &str) -> Result<Option<bool>, IngressError> {
match v {
None | Some(Value::Null) => Ok(None),
Some(Value::Bool(b)) => Ok(Some(*b)),
Some(_) => Err(bad(path, "a boolean")),
}
}