use serde_json::{Map, Value};
use crate::config::errors::ConfigError;
use crate::config::partial::PartialProvider;
use crate::config::provider::{AuthId, Provider};
use super::bad;
pub(crate) fn complete(name: String, row: PartialProvider) -> Result<Provider, ConfigError> {
let need = |field| ConfigError::IncompleteProvider {
name: name.clone(),
field,
};
let base_url = match (row.base_url, row.exec.is_some()) {
(Some(url), _) => url,
(None, true) => String::new(),
(None, false) => return Err(need("base_url")),
};
if row.exec.is_some() && row.transport.is_some() {
return Err(bad(
"transport",
"cannot ride a row that also sets `exec` (that row's child IS the \
provider); drop one",
));
}
let protocol = row.protocol.ok_or_else(|| need("protocol"))?;
let auth = row.auth.ok_or_else(|| need("auth"))?;
let api_header = row.api_header;
if auth != AuthId::None && api_header.is_none() {
return Err(need("api_header"));
}
if auth == AuthId::OAuth2 && row.oauth.is_none() {
return Err(need("oauth"));
}
Ok(Provider {
base_url,
exec: row.exec,
transport: row.transport,
protocol,
auth,
api_header,
beta_headers: row.beta_headers.unwrap_or_default(),
generation_query: row.generation_query.unwrap_or_default(),
model_aliases: row.model_aliases.unwrap_or_default(),
unsupported_body_keys: row.unsupported_body_keys.unwrap_or_default(),
models: row.models,
oauth: row.oauth,
ambient: row.ambient,
name,
})
}
pub(super) fn take_u32(bd: &mut Map<String, Value>, key: &str) -> Result<Option<u32>, ConfigError> {
match bd.remove(key) {
None => Ok(None),
Some(v) => v
.as_u64()
.filter(|n| *n > 0 && *n <= u64::from(u32::MAX))
.map(|n| Some(n as u32))
.ok_or_else(|| bad(key, "must be a positive integer")),
}
}
pub(super) fn take_f32(bd: &mut Map<String, Value>, key: &str) -> Result<Option<f32>, ConfigError> {
match bd.remove(key) {
None => Ok(None),
Some(v) => v
.as_f64()
.map(|f| Some(f as f32))
.ok_or_else(|| bad(key, "must be a number")),
}
}
pub(super) fn take_bool(
bd: &mut Map<String, Value>,
key: &str,
) -> Result<Option<bool>, ConfigError> {
match bd.remove(key) {
None => Ok(None),
Some(v) => v
.as_bool()
.map(Some)
.ok_or_else(|| bad(key, "must be a boolean")),
}
}