use std::collections::BTreeMap;
use crate::error::Error;
use crate::http::HttpClient;
use crate::types::common::RequestOptions;
use crate::types::optimize::{LinearProgramDefinition, OptimizationResult, SolveOptions};
#[derive(Debug, Clone)]
pub struct OptimizeClient {
http: HttpClient,
}
impl OptimizeClient {
pub(crate) fn new(http: HttpClient) -> Self {
Self { http }
}
pub async fn solve(
&self,
problem: &LinearProgramDefinition,
_opts: &SolveOptions,
options: Option<&RequestOptions>,
) -> Result<OptimizationResult, Error> {
let raw: serde_json::Value = self
.http
.post("/optimize/production", problem, options)
.await?;
let status = raw.get("status").and_then(|v| v.as_str()).unwrap_or("");
let solve_time_ms = raw
.get("solve_time_ms")
.and_then(|v| v.as_u64())
.unwrap_or(0);
match status {
"optimal" => {
let variables: BTreeMap<String, f64> = raw
.get("variables")
.and_then(|v| serde_json::from_value(v.clone()).ok())
.unwrap_or_default();
let objective_value = raw
.get("objective_value")
.and_then(|v| v.as_f64())
.unwrap_or(0.0);
Ok(OptimizationResult::Optimal {
variables,
objective_value,
solve_time_ms,
})
}
"infeasible" => Ok(OptimizationResult::Infeasible { solve_time_ms }),
other => Err(Error::validation_msg(format!(
"unexpected optimization status: {other}"
))),
}
}
pub async fn solve_raw(
&self,
payload: &serde_json::Value,
options: Option<&RequestOptions>,
) -> Result<serde_json::Value, Error> {
self.http
.post("/optimize/production", payload, options)
.await
}
}