#![allow(clippy::needless_pass_by_value)]
use anyhow::{bail, Result};
#[cfg(feature = "base64url-builtins")]
pub mod base64url;
pub mod crypto;
pub mod glob;
pub mod graph;
pub mod graphql;
#[cfg(feature = "hex-builtins")]
pub mod hex;
pub mod http;
pub mod io;
#[cfg(feature = "json-builtins")]
pub mod json;
pub mod net;
pub mod object;
pub mod opa;
#[cfg(feature = "rng")]
pub mod rand;
pub mod regex;
pub mod rego;
#[cfg(feature = "semver-builtins")]
pub mod semver;
#[cfg(feature = "time-builtins")]
pub mod time;
#[cfg(feature = "units-builtins")]
pub mod units;
#[cfg(feature = "urlquery-builtins")]
pub mod urlquery;
pub mod uuid;
#[cfg(feature = "yaml-builtins")]
pub mod yaml;
#[tracing::instrument(err)]
pub fn indexof_n(string: String, search: String) -> Result<Vec<u32>> {
bail!("not implemented");
}
#[cfg(feature = "sprintf-builtins")]
#[tracing::instrument(err)]
pub fn sprintf(format: String, values: Vec<serde_json::Value>) -> Result<String> {
use sprintf::{vsprintf, Printf};
let values: Result<Vec<Box<dyn Printf>>, _> = values
.into_iter()
.map(|v| -> Result<Box<dyn Printf>, _> {
match v {
serde_json::Value::Null => Err(anyhow::anyhow!("can't format null")),
serde_json::Value::Bool(_) => Err(anyhow::anyhow!("can't format a boolean")),
serde_json::Value::Number(n) => {
if let Some(n) = n.as_u64() {
Ok(Box::new(n))
} else if let Some(n) = n.as_i64() {
Ok(Box::new(n))
} else if let Some(n) = n.as_f64() {
Ok(Box::new(n))
} else {
Err(anyhow::anyhow!("unreachable"))
}
}
serde_json::Value::String(s) => Ok(Box::new(s)),
serde_json::Value::Array(_) => Err(anyhow::anyhow!("can't format array")),
serde_json::Value::Object(_) => Err(anyhow::anyhow!("can't format object")),
}
})
.collect();
let values = values?;
let values: Vec<&dyn Printf> = values.iter().map(std::convert::AsRef::as_ref).collect();
vsprintf(&format, &values).map_err(|_| anyhow::anyhow!("failed to call printf"))
}
#[tracing::instrument(err)]
pub fn trace(note: String) -> Result<bool> {
bail!("not implemented");
}