use std::{fmt::Debug, path::PathBuf, sync::Arc};
use oxinat_derive::uri_builder_alias;
use crate::{UriBuildError, UriBuilder, Version};
uri_builder_alias!(UserAdminUriBuilder);
ImplUserAdminUriBuilder! {
(String),
}
macro_rules! username_is_some {
() => {
|this: &Self| this.parent.as_ref().is_some_and(|p| p.username.is_some())
};
}
macro_rules! username_is_none {
() => {
|this: &Self| this.parent.as_ref().is_some_and(|p| p.username.is_none())
};
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/users")]
#[match_path(path = "{parent}/users/{username}")]
pub struct UserUriBuilder<Parent>
where
Parent: UserAdminUriBuilder,
{
#[param]
username: Option<String>,
#[parent]
parent: Option<Arc<Parent>>
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/active", requires = "username_is_none!()")]
#[match_path(path = "{parent}/active/{username}", requires = "username_is_none!()")]
pub struct ActiveUriBuilder<'a> {
#[param]
username: Option<String>,
#[parent]
parent: Option<&'a UserUriBuilder<String>>
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/access", requires = "username_is_none!()")]
#[match_path(path = "{parent}/access/{username}", requires = "username_is_none!()")]
pub struct AccessUriBuilder<'a> {
#[param]
username: Option<String>,
#[parent]
parent: Option<&'a UserUriBuilder<String>>
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/cache", requires = "username_is_none!()")]
pub struct CacheUriBuilder<'a> {
#[parent]
parent: Option<&'a AccessUriBuilder<'a>>
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/flush")]
#[match_path(path = "{parent}/flush/{username}")]
pub struct CacheFlushUriBuilder<'a> {
#[param]
username: Option<String>,
#[parent]
parent: Option<&'a CacheUriBuilder<'a>>
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "parent/status")]
pub struct CacheStatusUriBuilder<'a> {
#[parent]
parent: Option<&'a CacheUriBuilder<'a>>
}
impl CacheUriBuilder<'_> {
pub fn flush(&self) -> CacheFlushUriBuilder {
CacheFlushUriBuilder::from_parent(self)
}
pub fn status(&self) -> CacheStatusUriBuilder {
CacheStatusUriBuilder::from_parent(self)
}
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/displays")]
#[match_path(path = "{parent}/displays/{display}")]
pub struct DisplaysUriBuilder<'a> {
#[param]
display: Option<String>,
#[parent]
parent: Option<&'a AccessUriBuilder<'a>>
}
impl DisplaysUriBuilder<'_> {
pub fn modified(&self) -> crate::BuildResult {
if self.display.is_none() {
self.build_join("modified")
} else {
Err(UriBuildError::Validation.into())
}
}
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/permissions", requires = "username_is_none!()")]
pub struct PermissionsUriBuilder<'a> {
#[parent]
parent: Option<&'a AccessUriBuilder<'a>>
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/group")]
#[match_path(path = "{parent}/group/{project_id}")]
pub struct GroupPermissionsUriBuilder<'a> {
#[param]
project_id: Option<String>,
#[parent]
parent: Option<&'a PermissionsUriBuilder<'a>>
}
#[derive(Clone, Debug, UriBuilder)]
pub enum IrregularPermission {
Find,
Fix
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/irregular/{irregular_permission}")]
pub struct IrregularPermissionsUriBuilder<'a> {
#[param]
irregular_permission: Option<IrregularPermission>,
#[parent]
parent: Option<&'a PermissionsUriBuilder<'a>>
}
impl PermissionsUriBuilder<'_> {
pub fn group(&self) -> GroupPermissionsUriBuilder {
GroupPermissionsUriBuilder::from_parent(self)
}
pub fn irregular(&self) -> IrregularPermissionsUriBuilder {
IrregularPermissionsUriBuilder::from_parent(self)
}
}
impl AccessUriBuilder<'_> {
pub fn build_projects(&self) -> crate::BuildResult {
self.build_join("projects")
}
pub fn cache(&self) -> CacheUriBuilder {
CacheUriBuilder::from_parent(self)
}
pub fn displays(&self) -> DisplaysUriBuilder {
DisplaysUriBuilder::from_parent(self)
}
pub fn permissions(&self) -> PermissionsUriBuilder {
PermissionsUriBuilder::from_parent(self)
}
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/enabled", requires = "username_is_some!()")]
#[match_path(path = "{parent}/enabled/{flag}", requires = "username_is_some!()")]
pub struct EnabledUriBuilder<'a> {
#[param]
flag: Option<bool>,
#[parent]
parent: Option<&'a UserUriBuilder<String>>
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/groups", requires = "username_is_some!()")]
#[match_path(path = "{parent}/groups/{group}", requires = "username_is_some!()")]
pub struct GroupsUriBuilder<'a>
{
#[param]
group: Option<String>,
#[parent]
parent: Option<&'a UserUriBuilder<String>>
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/profiles", requires = "username_is_none!()")]
#[match_path(path = "{parent}/profile/{username}", requires = "username_is_none!()")]
pub struct ProfilesUriBuilder<'a> {
#[param]
username: Option<String>,
#[parent]
parent: Option<&'a UserUriBuilder<String>>
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/roles", requires = "username_is_some!()")]
#[match_path(path = "{parent}/roles/{role}", requires = "username_is_some!()")]
pub struct RolesUriBuilder<'a> {
#[param]
role: Option<String>,
#[parent]
parent: Option<&'a UserUriBuilder<String>>
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/verified", requires = "username_is_some!()")]
#[match_path(path = "{parent}/verified/{flag}", requires = "username_is_some!()")]
pub struct VerifiedUriBuilder<'a> {
#[param]
flag: Option<bool>,
#[parent]
parent: Option<&'a UserUriBuilder<String>>
}
impl UserUriBuilder<String>
{
pub fn access(&self) -> AccessUriBuilder {
AccessUriBuilder::from_parent(&Arc::new(self))
}
pub fn active(&self) -> ActiveUriBuilder {
ActiveUriBuilder::from_parent(&Arc::new(self))
}
pub fn build_current(&self) -> crate::BuildResult {
self.build_join("current")
}
pub fn build_projects(&self) -> crate::BuildResult {
if self.username.is_none() {
self.build_join("projects")
} else {
Err(UriBuildError::Validation.into())
}
}
pub fn build_username(&self) -> crate::BuildResult {
if self.username.is_none() {
self.build_join("username")
} else {
Err(UriBuildError::Validation.into())
}
}
pub fn enabled(&self) -> EnabledUriBuilder {
EnabledUriBuilder::from_parent(&Arc::new(self))
}
pub fn groups(&self) -> GroupsUriBuilder {
GroupsUriBuilder::from_parent(&Arc::new(self))
}
pub fn profiles(&self) -> ProfilesUriBuilder {
ProfilesUriBuilder::from_parent(&Arc::new(self))
}
pub fn roles(&self) -> RolesUriBuilder {
RolesUriBuilder::from_parent(&Arc::new(self))
}
pub fn verified(&self) -> VerifiedUriBuilder {
VerifiedUriBuilder::from_parent(&Arc::new(self))
}
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/users")]
#[match_path(path = "{parent}/user/{username}")]
pub struct UsersUriLegacyBuilder<Parent>
where
Parent: UserAdminUriBuilder,
{
#[param]
username: Option<String>,
#[parent]
parent: Option<Arc<Parent>>
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/cache", requires = "username_is_none!()")]
pub struct CacheUriLegacyBuilder<'a> {
#[parent]
parent: Option<&'a UsersUriLegacyBuilder<String>>
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/resources")]
#[match_path(path = "{parent}/resources/{folder}")]
#[match_path(path = "{parent}/resources/{folder}/files/{file}")]
pub struct ResourcesUriBuilder<'a> {
#[param(map_from = "|pb: &PathBuf| pb.to_str().unwrap().to_string()")]
file: Option<PathBuf>,
#[param]
folder: Option<String>,
#[parent]
parent: Option<&'a CacheUriLegacyBuilder<'a>>
}
impl ResourcesUriBuilder<'_> {
pub fn build_files(&self) -> crate::BuildResult {
if self.file.is_none() && self.folder.is_some() {
self.build_join("projects")
} else {
Err(UriBuildError::Validation.into())
}
}
}
impl CacheUriLegacyBuilder<'_> {
pub fn resources(&self) -> ResourcesUriBuilder {
ResourcesUriBuilder::from_parent(&Arc::new(self))
}
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/favorites/Project/{project_id}", requires = "username_is_none!()")]
pub struct FavoritesUriBuilder<'a> {
#[param]
project_id: Option<String>,
#[parent]
parent: Option<&'a UsersUriLegacyBuilder<String>>
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/projects/{project_id}/users", requires = "username_is_none!()")]
#[match_path(path = "{parent}/projects/{project_id}/users/{group_display_name}/{username}", requires = "username_is_none!()")]
pub struct ProjectsUriBuilder<'a> {
#[param]
project_id: Option<String>,
#[param]
group_display_name: Option<String>,
#[param]
username: Option<String>,
#[parent]
parent: Option<&'a UsersUriLegacyBuilder<String>>,
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/pars")]
#[match_path(path = "{parent}/pars/{pars_id}")]
#[match_path(path = "{parent}/projects/{project_id}/pars")]
pub struct ProjectAccessUriBuilder<'a> {
#[param]
pars_id: Option<String>,
#[param]
project_id: Option<String>,
#[parent]
parent: Option<&'a ProjectsUriBuilder<'a>>
}
impl ProjectsUriBuilder<'_> {
pub fn pars(&self) -> ProjectAccessUriBuilder {
ProjectAccessUriBuilder::from_parent(&Arc::new(self))
}
}
impl UsersUriLegacyBuilder<String> {
pub fn cache(&self) -> CacheUriLegacyBuilder {
CacheUriLegacyBuilder::from_parent(&Arc::new(self))
}
pub fn favorites(&self) -> FavoritesUriBuilder {
FavoritesUriBuilder::from_parent(&Arc::new(self))
}
pub fn projects(&self) -> ProjectsUriBuilder {
ProjectsUriBuilder::from_parent(&Arc::new(self))
}
}
pub trait UsersUri: Version {
#[inline]
fn users(&self) -> UserUriBuilder<String> {
UserUriBuilder::from_parent(self.root_uri().into())
}
}
pub trait UsersUriLegacy: Version {
#[inline]
fn users_legacy(&self) -> UsersUriLegacyBuilder<String> {
UsersUriLegacyBuilder::from_parent(self.data_uri().into())
}
}