use crate::Error;
use crate::proto::v1::{Capability, CredentialData, RunFunctionRequest, credentials};
use crate::resource::{pb_to_json, struct_to_json};
pub const WATCHED_RESOURCE_KEY: &str = "ops.crossplane.io/watched-resource";
pub fn get_input<T: serde::de::DeserializeOwned>(req: &RunFunctionRequest) -> Result<T, Error> {
let input = req.input.as_ref().ok_or(Error::MissingInput)?;
Ok(serde_json::from_value(struct_to_json(input))?)
}
pub fn get_context_key(req: &RunFunctionRequest, key: &str) -> Option<serde_json::Value> {
req.context.as_ref()?.fields.get(key).map(pb_to_json)
}
pub fn get_required_resources(
req: &RunFunctionRequest,
name: &str,
) -> Option<Vec<serde_json::Value>> {
let resources = req.required_resources.get(name)?;
Some(
resources
.items
.iter()
.filter_map(|r| r.resource.as_ref())
.map(struct_to_json)
.collect(),
)
}
pub fn get_required_resource(req: &RunFunctionRequest, name: &str) -> Option<serde_json::Value> {
get_required_resources(req, name)?.into_iter().next()
}
pub fn get_watched_resource(req: &RunFunctionRequest) -> Option<serde_json::Value> {
get_required_resource(req, WATCHED_RESOURCE_KEY)
}
pub fn get_credential_data<'a>(
req: &'a RunFunctionRequest,
name: &str,
) -> Option<&'a CredentialData> {
match req.credentials.get(name)?.source.as_ref()? {
credentials::Source::CredentialData(data) => Some(data),
}
}
pub fn advertises_capabilities(req: &RunFunctionRequest) -> bool {
has_capability(req, Capability::Capabilities)
}
pub fn has_capability(req: &RunFunctionRequest, cap: Capability) -> bool {
req.meta
.as_ref()
.is_some_and(|m| m.capabilities().any(|c| c == cap))
}
pub fn get_required_schema(req: &RunFunctionRequest, name: &str) -> Option<serde_json::Value> {
req.required_schemas
.get(name)?
.openapi_v3
.as_ref()
.map(struct_to_json)
}