use crate::pagination::{ListOptions, QueryEncode};
use crate::{Deserialize, Serialize};
#[derive(Debug, Clone, Default)]
pub struct ListReleasesOptions {
pub list_options: ListOptions,
pub is_draft: Option<bool>,
pub is_pre_release: Option<bool>,
}
impl QueryEncode for ListReleasesOptions {
fn query_encode(&self) -> String {
let mut out = self.list_options.query_encode();
if let Some(draft) = self.is_draft {
out.push_str(&format!("&draft={draft}"));
}
if let Some(pre) = self.is_pre_release {
out.push_str(&format!("&pre-release={pre}"));
}
out
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateReleaseOption {
#[serde(rename = "tag_name")]
pub tag_name: String,
#[serde(rename = "target_commitish", skip_serializing_if = "Option::is_none")]
pub target: Option<String>,
#[serde(rename = "name", skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
#[serde(rename = "body", skip_serializing_if = "Option::is_none")]
pub note: Option<String>,
#[serde(default)]
pub is_draft: bool,
#[serde(default)]
pub is_prerelease: bool,
}
impl CreateReleaseOption {
pub fn validate(&self) -> crate::Result<()> {
if self.tag_name.trim().is_empty() {
return Err(crate::Error::Validation("tag_name is required".to_string()));
}
if let Some(ref title) = self.title
&& title.trim().is_empty()
{
return Err(crate::Error::Validation("title is empty".to_string()));
}
Ok(())
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct EditReleaseOption {
#[serde(rename = "tag_name", skip_serializing_if = "Option::is_none")]
pub tag_name: Option<String>,
#[serde(rename = "target_commitish", skip_serializing_if = "Option::is_none")]
pub target: Option<String>,
#[serde(rename = "name", skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
#[serde(rename = "body", skip_serializing_if = "Option::is_none")]
pub note: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_draft: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_prerelease: Option<bool>,
}
#[derive(Debug, Clone, Default)]
pub struct ListReleaseAttachmentsOptions {
pub list_options: ListOptions,
}
impl QueryEncode for ListReleaseAttachmentsOptions {
fn query_encode(&self) -> String {
self.list_options.query_encode()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EditAttachmentOption {
pub name: String,
}
impl EditAttachmentOption {
pub fn validate(&self) -> crate::Result<()> {
if self.name.trim().is_empty() {
return Err(crate::Error::Validation("name is required".to_string()));
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_release_option_validate_success() {
let opt = CreateReleaseOption {
tag_name: "v1.0.0".to_string(),
target: None,
title: None,
note: None,
is_draft: false,
is_prerelease: false,
};
assert!(opt.validate().is_ok());
}
#[test]
fn test_create_release_option_validate_empty_tag_name() {
let opt = CreateReleaseOption {
tag_name: String::new(),
target: None,
title: None,
note: None,
is_draft: false,
is_prerelease: false,
};
assert!(opt.validate().is_err());
}
#[test]
fn test_create_release_option_validate_empty_title() {
let opt = CreateReleaseOption {
tag_name: "v1.0.0".to_string(),
target: None,
title: Some(" ".to_string()),
note: None,
is_draft: false,
is_prerelease: false,
};
assert!(opt.validate().is_err());
}
#[test]
fn test_edit_attachment_option_validate_success() {
let opt = EditAttachmentOption {
name: "file.zip".to_string(),
};
assert!(opt.validate().is_ok());
}
#[test]
fn test_edit_attachment_option_validate_empty_name() {
let opt = EditAttachmentOption {
name: String::new(),
};
assert!(opt.validate().is_err());
}
}