use serde::Serialize;
use super::error::ForumApiError;
#[derive(Debug, Serialize)]
pub struct GetForumTopicDetail {
#[serde(skip_serializing)]
pub(crate) topic_id: u32,
limit: u16,
offset: u32,
}
impl GetForumTopicDetail {
pub fn new(
topic_id: u32,
limit: Option<u16>,
offset: Option<u32>,
) -> Result<Self, ForumApiError> {
let limit = limit.map(|l| l.clamp(1, 100));
Ok(Self {
topic_id,
limit: limit.unwrap_or(100),
offset: offset.unwrap_or(0),
})
}
pub fn builder(topic_id: u32) -> GetForumTopicDetailBuilder {
GetForumTopicDetailBuilder::new(topic_id)
}
}
pub struct GetForumTopicDetailBuilder {
topic_id: u32,
limit: Option<u16>,
offset: Option<u32>,
}
impl GetForumTopicDetailBuilder {
pub fn new(topic_id: u32) -> Self {
Self {
topic_id,
limit: None,
offset: None,
}
}
pub fn topic_id(mut self, value: u32) -> Self {
self.topic_id = value;
self
}
pub fn limit(mut self, value: u16) -> Self {
self.limit = Some(value);
self
}
pub fn offset(mut self, value: u32) -> Self {
self.offset = Some(value);
self
}
pub fn build(self) -> Result<GetForumTopicDetail, ForumApiError> {
GetForumTopicDetail::new(self.topic_id, self.limit, self.offset)
}
}
#[derive(Debug, Serialize)]
pub struct GetForumTopics {
nsfw: bool,
#[serde(skip_serializing_if = "Option::is_none")]
q: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
board_id: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
subboard_id: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
topic_user_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
user_name: Option<String>,
limit: u16,
offset: u32,
sort: String,
}
impl GetForumTopics {
pub fn new(
nsfw: bool,
q: Option<String>,
board_id: Option<u32>,
subboard_id: Option<u32>,
topic_user_name: Option<String>,
user_name: Option<String>,
limit: Option<u16>,
offset: Option<u32>,
) -> Result<Self, ForumApiError> {
let limit = limit.map(|l| l.clamp(1, 100));
if !(q.is_some()
|| board_id.is_some()
|| subboard_id.is_some()
|| topic_user_name.is_some()
|| user_name.is_some())
{
return Err(ForumApiError::new(
"At least one of the optional arguments must be Some, excluding limit and offset"
.to_string(),
));
}
Ok(Self {
nsfw,
board_id,
subboard_id,
limit: limit.unwrap_or(100),
offset: offset.unwrap_or(0),
q,
topic_user_name,
user_name,
sort: "recent".to_string(),
})
}
pub fn builder() -> GetForumTopicsBuilder {
GetForumTopicsBuilder::new()
}
}
pub struct GetForumTopicsBuilder {
nsfw: bool,
q: Option<String>,
board_id: Option<u32>,
subboard_id: Option<u32>,
topic_user_name: Option<String>,
user_name: Option<String>,
limit: Option<u16>,
offset: Option<u32>,
}
impl GetForumTopicsBuilder {
pub fn new() -> Self {
Self {
nsfw: false,
q: None,
board_id: None,
subboard_id: None,
topic_user_name: None,
user_name: None,
limit: None,
offset: None,
}
}
pub fn enable_nsfw(mut self) -> Self {
self.nsfw = true;
self
}
pub fn q(mut self, value: &str) -> Self {
self.q = Some(value.to_string());
self
}
pub fn board_id(mut self, value: u32) -> Self {
self.board_id = Some(value);
self
}
pub fn subboard_id(mut self, value: u32) -> Self {
self.subboard_id = Some(value);
self
}
pub fn topic_user_name(mut self, value: &str) -> Self {
self.topic_user_name = Some(value.to_string());
self
}
pub fn user_name(mut self, value: &str) -> Self {
self.user_name = Some(value.to_string());
self
}
pub fn limit(mut self, value: u16) -> Self {
self.limit = Some(value);
self
}
pub fn offset(mut self, value: u32) -> Self {
self.offset = Some(value);
self
}
pub fn build(self) -> Result<GetForumTopics, ForumApiError> {
GetForumTopics::new(
self.nsfw,
self.q,
self.board_id,
self.subboard_id,
self.topic_user_name,
self.user_name,
self.limit,
self.offset,
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_forum_topic_detail() {
let query = GetForumTopicDetail::new(1234, Some(101), None);
assert_eq!(query.unwrap().limit, 100);
let query = GetForumTopicDetail::new(1234, Some(0), None);
assert_eq!(query.unwrap().limit, 1);
let query = GetForumTopicDetail::new(1234, Some(1), None);
assert_eq!(query.unwrap().limit, 1);
let query = GetForumTopicDetail::new(1234, None, None);
assert_eq!(query.unwrap().limit, 100);
}
#[test]
fn test_get_forum_topics() {
let query = GetForumTopics::new(false, None, None, None, None, None, None, None);
assert!(query.is_err());
let query = GetForumTopics::new(
false,
Some("hello".to_string()),
None,
None,
None,
None,
Some(101),
None,
);
assert_eq!(query.unwrap().limit, 100);
let query = GetForumTopics::new(
false,
Some("hello".to_string()),
None,
None,
None,
None,
Some(0),
None,
);
assert_eq!(query.unwrap().limit, 1);
let query = GetForumTopics::new(
false,
Some("hello".to_string()),
None,
None,
None,
None,
Some(100),
None,
);
assert_eq!(query.unwrap().limit, 100);
let query = GetForumTopics::new(
false,
Some("hello".to_string()),
None,
None,
None,
None,
None,
None,
);
assert_eq!(query.unwrap().limit, 100);
}
}