use crate::client::OrdinaryApiClient;
use anyhow::bail;
use base64::{Engine, engine::general_purpose::URL_SAFE_NO_PAD as b64};
use ordinary_config::OrdinaryConfig;
use ordinary_types::flexbuffer_reader_to_json;
pub async fn items_list(
api_client: &OrdinaryApiClient<'_>,
proj_path: &str,
model_name: &str,
) -> anyhow::Result<String> {
let correlation_id = api_client.correlation_id.map(|id| id.to_string());
let config = OrdinaryConfig::get(proj_path)?;
let mut idx = None;
if let Some(model_configs) = &config.models {
for model_config in model_configs {
if model_config.name == model_name {
idx = Some(model_config.idx);
break;
}
}
}
let access_token = api_client.get_access(None, correlation_id.clone()).await?;
let Some(model_idx) = idx else {
bail!("no model by that name");
};
tracing::info!("fetching...");
let mut req = api_client
.client
.get(format!("{}/v1/models/items", api_client.addr))
.query(&[("d", config.domain), ("i", model_idx.to_string())])
.header(
"Authorization",
format!("Bearer {}", b64.encode(access_token)),
);
if let Some(correlation_id) = correlation_id {
req = req.header("x-correlation-id", correlation_id);
}
let res = req.send().await?.bytes().await?;
if res.is_empty() {
let vec: Vec<u8> = vec![];
Ok(serde_json::to_string(&vec)?)
} else {
let root = flexbuffers::Reader::get_root(&res[..])?;
let mut out = vec![];
if let Some(models) = &config.models
&& let Some(model) = models.iter().find(|m| m.idx == model_idx)
{
for item in &root.as_vector() {
let mut item_out = vec![];
for field in &model.fields {
let json_val = flexbuffer_reader_to_json(
&field.kind,
&item.as_vector().idx(field.idx as usize),
)?;
item_out.push(json_val);
}
out.push(item_out);
}
}
tracing::info!("done.");
Ok(serde_json::to_string(&out)?)
}
}