use std::borrow::Cow;
use derive_builder::Builder;
use crate::api::common::NameOrId;
use crate::api::endpoint_prelude::*;
#[derive(Debug, Builder, Clone)]
#[builder(setter(strip_option), build_fn(validate = "Self::validate"))]
pub struct DeleteProject<'a> {
#[builder(setter(into))]
project: NameOrId<'a>,
#[builder(setter(into), default)]
full_path: Option<Cow<'a, str>>,
#[builder(default)]
permanently_remove: Option<bool>,
}
impl<'a> DeleteProject<'a> {
pub fn builder() -> DeleteProjectBuilder<'a> {
DeleteProjectBuilder::default()
}
}
static PERMANENT_REMOVAL_REQUIRES_FULL_PATH: &str = "`permanently_remove` requires `full_path`";
#[non_exhaustive]
enum DeleteProjectValidationError {
PermanentRemovalRequiresFullPath,
}
impl From<DeleteProjectValidationError> for DeleteProjectBuilderError {
fn from(validation_error: DeleteProjectValidationError) -> Self {
match validation_error {
DeleteProjectValidationError::PermanentRemovalRequiresFullPath => {
DeleteProjectBuilderError::ValidationError(
PERMANENT_REMOVAL_REQUIRES_FULL_PATH.into(),
)
},
}
}
}
impl DeleteProjectBuilder<'_> {
fn validate(&self) -> Result<(), DeleteProjectValidationError> {
if self.permanently_remove.and_then(|p| p).unwrap_or(false) && self.full_path.is_none() {
return Err(DeleteProjectValidationError::PermanentRemovalRequiresFullPath);
}
Ok(())
}
}
impl Endpoint for DeleteProject<'_> {
fn method(&self) -> Method {
Method::DELETE
}
fn endpoint(&self) -> Cow<'static, str> {
format!("projects/{}", self.project).into()
}
fn parameters(&self) -> QueryParams<'_> {
let mut params = QueryParams::default();
params
.push_opt("full_path", self.full_path.as_ref())
.push_opt("permanently_remove", self.permanently_remove);
params
}
}
#[cfg(test)]
mod tests {
use http::Method;
use crate::api::projects::{DeleteProject, DeleteProjectBuilderError};
use crate::api::{self, Query};
use crate::test::client::{ExpectedUrl, SingleTestClient};
use super::PERMANENT_REMOVAL_REQUIRES_FULL_PATH;
#[test]
fn project_is_necessary() {
let err = DeleteProject::builder().build().unwrap_err();
crate::test::assert_missing_field!(err, DeleteProjectBuilderError, "project");
}
#[test]
fn project_is_sufficient() {
DeleteProject::builder().project("project").build().unwrap();
}
#[test]
fn permanently_remove_requires_full_path() {
let err = DeleteProject::builder()
.project("project")
.permanently_remove(true)
.build()
.unwrap_err();
assert_eq!(err.to_string(), PERMANENT_REMOVAL_REQUIRES_FULL_PATH);
}
#[test]
fn permanently_with_full_path() {
DeleteProject::builder()
.project("project")
.permanently_remove(true)
.full_path("full/path")
.build()
.unwrap();
}
#[test]
fn endpoint() {
let endpoint = ExpectedUrl::builder()
.method(Method::DELETE)
.endpoint("projects/1337")
.build()
.unwrap();
let client = SingleTestClient::new_raw(endpoint, "");
let endpoint = DeleteProject::builder().project(1337).build().unwrap();
api::ignore(endpoint).query(&client).unwrap();
}
#[test]
fn endpoint_full_path() {
let endpoint = ExpectedUrl::builder()
.method(Method::DELETE)
.endpoint("projects/1337")
.add_query_params(&[("full_path", "foo/bar")])
.build()
.unwrap();
let client = SingleTestClient::new_raw(endpoint, "");
let endpoint = DeleteProject::builder()
.project(1337)
.full_path("foo/bar")
.build()
.unwrap();
api::ignore(endpoint).query(&client).unwrap();
}
#[test]
fn endpoint_permanently_remove() {
let endpoint = ExpectedUrl::builder()
.method(Method::DELETE)
.endpoint("projects/1337")
.add_query_params(&[("full_path", "foo/bar"), ("permanently_remove", "true")])
.build()
.unwrap();
let client = SingleTestClient::new_raw(endpoint, "");
let endpoint = DeleteProject::builder()
.project(1337)
.full_path("foo/bar")
.permanently_remove(true)
.build()
.unwrap();
api::ignore(endpoint).query(&client).unwrap();
}
}