pub use agent_skills::AgentSkillHandler;
pub use agents::AgentHandler;
pub use catalogs::CatalogHandler;
pub use credentials::CredentialHandler;
pub use entity_tag_assignments::EntityTagAssignmentHandler;
pub use external_locations::ExternalLocationHandler;
pub use functions::FunctionHandler;
pub use model_versions::ModelVersionHandler;
pub use policies::PolicyHandler;
pub use registered_models::RegisteredModelHandler;
pub use schemas::SchemaHandler;
pub use staging_tables::StagingTableHandler;
pub use tables::TableHandler;
pub use tag_policies::TagPolicyHandler;
pub use temporary_credentials::TemporaryCredentialHandler;
pub use volumes::VolumeHandler;
use crate::policy::{Permission, Principal};
use unitycatalog_common::models::ResourceIdent;
pub mod agent_skills;
pub mod agents;
pub mod catalogs;
pub mod credentials;
pub mod entity_tag_assignments;
pub mod external_locations;
pub mod functions;
pub mod model_versions;
pub mod policies;
pub mod registered_models;
pub mod schemas;
pub mod staging_tables;
pub mod tables;
pub mod tag_policies;
pub mod temporary_credentials;
pub mod volumes;
pub(crate) fn page_size(max_results: Option<i32>) -> crate::Result<Option<usize>> {
match max_results {
Some(v) if v < 0 => Err(crate::Error::invalid_argument(
"max_results must not be negative",
)),
Some(v) if v > 0 => Ok(Some(v as usize)),
_ => Ok(None),
}
}
pub(crate) enum UpdateMask<'a> {
All,
Fields(Vec<&'a str>),
}
impl<'a> UpdateMask<'a> {
pub(crate) fn parse(mask: Option<&'a str>, updatable: &[&str]) -> crate::Result<Self> {
let fields: Vec<&str> = mask
.unwrap_or_default()
.split(',')
.map(str::trim)
.filter(|f| !f.is_empty())
.collect();
if fields.is_empty() || fields == ["*"] {
return Ok(Self::All);
}
if let Some(unknown) = fields.iter().find(|f| !updatable.contains(f)) {
return Err(crate::Error::invalid_argument(format!(
"update_mask names a field that cannot be updated: '{unknown}'"
)));
}
Ok(Self::Fields(fields))
}
pub(crate) fn names(&self, field: &str) -> bool {
matches!(self, Self::Fields(fields) if fields.contains(&field))
}
}
#[derive(Debug, Clone)]
pub struct RequestContext {
pub recipient: Principal,
}
impl RequestContext {
pub fn recipient(&self) -> &Principal {
&self.recipient
}
}
impl AsRef<Principal> for RequestContext {
fn as_ref(&self) -> &Principal {
&self.recipient
}
}
#[cfg(feature = "bin")]
impl unitycatalog_storage_proxy::ForwardedUser for RequestContext {
fn forwarded_user(&self) -> Option<&str> {
match &self.recipient {
Principal::User(name) => Some(name),
Principal::Anonymous => None,
}
}
}
pub trait SecuredAction: Send + Sync {
fn resource(&self) -> ResourceIdent;
fn permission(&self) -> &'static Permission;
}
#[cfg(test)]
mod tests {
use super::page_size;
#[test]
fn test_page_size() {
assert_eq!(page_size(None).unwrap(), None);
assert_eq!(page_size(Some(0)).unwrap(), None);
assert_eq!(page_size(Some(25)).unwrap(), Some(25));
assert!(page_size(Some(-1)).is_err());
}
}