use std::str::FromStr;
use crate::error::Error;
use crate::generated::types::{
MoveStickyRequestContent, Sticky, StickyPayload, StickyRequestContent,
};
pub use crate::generated::services::stickies::*;
pub const MAX_STICKIES_LIMIT: u32 = 100;
pub const MAX_STICKY_POSITION: i64 = i32::MAX as i64;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum StickySize {
Small,
Medium,
Large,
}
impl StickySize {
pub fn as_str(&self) -> &'static str {
match self {
StickySize::Small => "small",
StickySize::Medium => "medium",
StickySize::Large => "large",
}
}
}
impl Stickies<'_> {
pub async fn list_up_to(&self, limit: u32) -> Result<Vec<Sticky>, Error> {
let params = ListStickiesParams {
limit: page_limit(limit),
};
self.list(¶ms).await
}
pub async fn create_sticky(
&self,
body: &str,
size: Option<StickySize>,
) -> Result<Sticky, Error> {
self.create(&sticky_body(body, size)).await
}
pub async fn update_sticky(
&self,
sticky_id: i64,
body: &str,
size: Option<StickySize>,
) -> Result<Sticky, Error> {
self.update(sticky_id, &sticky_body(body, size)).await
}
pub async fn move_to(&self, sticky_id: i64, position: i64) -> Result<(), Error> {
let position = match i32::try_from(position) {
Ok(position) if position >= 0 => position,
_ => {
return Err(Error::usage(format!(
"sticky position must be between 0 and {MAX_STICKY_POSITION}, got {position}"
)));
}
};
let body = MoveStickyRequestContent {
id: sticky_id,
position,
};
self.move_sticky(&body).await
}
}
fn page_limit(limit: u32) -> Option<i32> {
match limit {
0 => None,
limit => i32::try_from(limit.min(MAX_STICKIES_LIMIT)).ok(),
}
}
fn sticky_body(body: &str, size: Option<StickySize>) -> StickyRequestContent {
let body = if body.is_empty() {
None
} else {
Some(body.to_string())
};
StickyRequestContent {
sticky: StickyPayload {
body,
size: size.map(|size| size.as_str().to_string()),
},
}
}
impl FromStr for StickySize {
type Err = Error;
fn from_str(source: &str) -> Result<StickySize, Error> {
match source {
"small" => Ok(StickySize::Small),
"medium" => Ok(StickySize::Medium),
"large" => Ok(StickySize::Large),
_ => Err(Error::usage(format!(
"sticky size {source:?} is none of \"small\", \"medium\" or \"large\""
))),
}
}
}