#[derive(Debug, Clone, Default)]
pub struct Filters {
pub statuses: Option<Vec<String>>,
pub priority: Option<u32>,
pub priority_lte: Option<u32>,
pub priority_gte: Option<u32>,
pub tags_any: Option<Vec<String>>,
pub tags_all: Option<Vec<String>>,
pub include_deleted: bool,
pub limit: Option<usize>,
pub offset: Option<usize>,
}
impl Filters {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn with_status(self, status: impl Into<String>) -> Self {
self.with_statuses(vec![status.into()])
}
#[must_use]
pub fn with_statuses(mut self, statuses: Vec<String>) -> Self {
self.statuses = Some(statuses);
self
}
#[must_use]
pub fn with_priority(mut self, priority: u32) -> Self {
self.priority = Some(priority);
self
}
#[must_use]
pub fn with_priority_lte(mut self, priority: u32) -> Self {
self.priority_lte = Some(priority);
self
}
#[must_use]
pub fn with_priority_gte(mut self, priority: u32) -> Self {
self.priority_gte = Some(priority);
self
}
#[must_use]
pub fn with_tags_any(mut self, tags: Vec<String>) -> Self {
self.tags_any = Some(tags);
self
}
#[must_use]
pub fn with_tags_all(mut self, tags: Vec<String>) -> Self {
self.tags_all = Some(tags);
self
}
#[must_use]
pub fn include_deleted(mut self) -> Self {
self.include_deleted = true;
self
}
#[must_use]
pub fn with_limit(mut self, limit: usize) -> Self {
self.limit = Some(limit);
self
}
#[must_use]
pub fn with_offset(mut self, offset: usize) -> Self {
self.offset = Some(offset);
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_filters_default() {
let filters = Filters::default();
assert!(filters.statuses.is_none());
assert!(filters.priority.is_none());
assert!(filters.priority_lte.is_none());
assert!(filters.priority_gte.is_none());
assert!(filters.tags_any.is_none());
assert!(filters.tags_all.is_none());
assert!(!filters.include_deleted);
assert!(filters.limit.is_none());
assert!(filters.offset.is_none());
}
#[test]
fn test_filters_new() {
let filters = Filters::new();
assert!(filters.statuses.is_none());
assert!(filters.priority.is_none());
assert!(!filters.include_deleted);
assert!(filters.limit.is_none());
assert!(filters.offset.is_none());
}
#[test]
fn test_filters_with_status() {
let filters = Filters::new().with_status("open");
assert_eq!(filters.statuses, Some(vec!["open".to_string()]));
}
#[test]
fn test_filters_with_status_string() {
let filters = Filters::new().with_status("in-progress".to_string());
assert_eq!(filters.statuses, Some(vec!["in-progress".to_string()]));
}
#[test]
fn test_filters_with_statuses() {
let filters =
Filters::new().with_statuses(vec!["open".to_string(), "in-progress".to_string()]);
assert_eq!(
filters.statuses,
Some(vec!["open".to_string(), "in-progress".to_string()])
);
}
#[test]
fn test_filters_with_priority() {
let filters = Filters::new().with_priority(1);
assert_eq!(filters.priority, Some(1));
}
#[test]
fn test_filters_with_priority_lte() {
let filters = Filters::new().with_priority_lte(2);
assert_eq!(filters.priority_lte, Some(2));
}
#[test]
fn test_filters_with_priority_gte() {
let filters = Filters::new().with_priority_gte(1);
assert_eq!(filters.priority_gte, Some(1));
}
#[test]
fn test_filters_include_deleted() {
let filters = Filters::new().include_deleted();
assert!(filters.include_deleted);
}
#[test]
fn test_filters_with_limit() {
let filters = Filters::new().with_limit(10);
assert_eq!(filters.limit, Some(10));
}
#[test]
fn test_filters_with_offset() {
let filters = Filters::new().with_offset(5);
assert_eq!(filters.offset, Some(5));
}
#[test]
fn test_filters_chained() {
let filters = Filters::new()
.with_status("open")
.with_priority(2)
.include_deleted()
.with_limit(20)
.with_offset(10);
assert_eq!(filters.statuses, Some(vec!["open".to_string()]));
assert_eq!(filters.priority, Some(2));
assert!(filters.include_deleted);
assert_eq!(filters.limit, Some(20));
assert_eq!(filters.offset, Some(10));
}
#[test]
fn test_filters_clone() {
let filters = Filters::new().with_status("open").with_priority(1);
let cloned = filters.clone();
assert_eq!(cloned.statuses, Some(vec!["open".to_string()]));
assert_eq!(cloned.priority, Some(1));
}
#[test]
fn test_filters_debug() {
let filters = Filters::new().with_status("open");
let debug = format!("{filters:?}");
assert!(debug.contains("Filters"));
assert!(debug.contains("open"));
}
#[test]
fn test_filters_with_tags_any() {
let filters = Filters::new().with_tags_any(vec!["bug".to_string(), "frontend".to_string()]);
assert_eq!(
filters.tags_any,
Some(vec!["bug".to_string(), "frontend".to_string()])
);
assert!(filters.tags_all.is_none());
}
#[test]
fn test_filters_with_tags_all() {
let filters = Filters::new().with_tags_all(vec!["bug".to_string(), "urgent".to_string()]);
assert_eq!(
filters.tags_all,
Some(vec!["bug".to_string(), "urgent".to_string()])
);
assert!(filters.tags_any.is_none());
}
}