use std::borrow::Cow;
use crate::prepared::PendingWarnings;
use crate::{
Degradations, EmbeddingProvider, EmbeddingRequest, EmbeddingResponse, EmbeddingValidation,
Result, Validation, ValidationCoverage,
};
#[must_use = "a prepared request reports its warnings through `finish` or `into_validation`"]
#[derive(Debug)]
pub struct Prepared<'a> {
request: Cow<'a, EmbeddingRequest>,
pending: PendingWarnings,
}
pub fn prepare<'a, P: EmbeddingProvider + ?Sized>(
provider: &P,
request: &'a EmbeddingRequest,
) -> Result<Prepared<'a>> {
Prepared::new(provider, request, false)
}
pub fn prepare_dry_run<'a, P: EmbeddingProvider + ?Sized>(
provider: &P,
request: &'a EmbeddingRequest,
) -> Result<Prepared<'a>> {
Prepared::new(provider, request, true)
}
impl<'a> Prepared<'a> {
fn new<P: EmbeddingProvider + ?Sized>(
provider: &P,
request: &'a EmbeddingRequest,
dry_run: bool,
) -> Result<Self> {
let degradations = Degradations::new(
provider.provider_name().to_owned(),
request.unsupported_policy.unwrap_or_default(),
);
let mut prepared = Self {
request: Cow::Borrowed(request),
pending: PendingWarnings::new(request.model.clone(), degradations, dry_run),
};
crate::adapter::embedding::preflight(
provider,
&mut prepared.request,
prepared.pending.degradations_mut(),
)?;
Ok(prepared)
}
#[must_use]
pub fn request(&self) -> &EmbeddingRequest {
&self.request
}
pub fn degradations_mut(&mut self) -> &mut Degradations {
self.pending.degradations_mut()
}
pub fn parts_mut(&mut self) -> (&EmbeddingRequest, &mut Degradations) {
(&self.request, self.pending.degradations_mut())
}
#[must_use]
pub fn is_dry_run(&self) -> bool {
self.pending.is_dry_run()
}
pub fn preflight_with<P: EmbeddingProvider + ?Sized>(&mut self, other: &P) -> Result<()> {
let degradations = self.pending.degradations_mut();
let recorded = degradations.unknown_len();
let result = crate::adapter::embedding::preflight(other, &mut self.request, degradations);
degradations.truncate_unknown(recorded);
result
}
pub fn mark_sent(&mut self) {
self.pending.mark_sent();
}
pub fn finish(self, mut response: EmbeddingResponse) -> EmbeddingResponse {
let inner = std::mem::take(&mut response.warnings);
let taken = self.pending.take();
if response.provider.is_none() {
response.provider = Some(Cow::Owned(taken.degradations.provider().to_owned()));
}
response.warnings = taken.merge(inner);
response
}
pub fn finish_validation(self, inner: EmbeddingValidation) -> EmbeddingValidation {
self.pending.take().merge_validation(inner)
}
pub fn into_validation(self, coverage: ValidationCoverage) -> EmbeddingValidation {
let (warnings, unknown) = self.pending.take().into_validation_parts();
Validation::from_parts(warnings, unknown, coverage)
}
}