use std::str::FromStr;
use snafu::{Snafu, ensure};
use crate::utils::ExampleData;
pub const RECURRENCE_RULE_MAX_LEN: usize = 1024;
#[derive(Debug, Clone, PartialEq, Eq, derive_more::Display)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde_with::DeserializeFromStr)
)]
pub struct RecurrenceRule(String);
#[derive(Debug, Snafu)]
pub enum ParseRecurrenceRuleError {
#[snafu(display(
"Recurrence rule string is too long. Max length: {max_len}, found length: {found_len}"
))]
RecurrenceRuleTooLong {
found_len: usize,
max_len: usize,
},
}
#[cfg(feature = "utoipa")]
mod impl_utoipa {
use serde_json::json;
use utoipa::{
PartialSchema, ToSchema,
openapi::{ObjectBuilder, RefOr, Schema, Type},
};
use super::{RECURRENCE_RULE_MAX_LEN, RecurrenceRule};
use crate::utils::ExampleData as _;
impl PartialSchema for RecurrenceRule {
fn schema() -> RefOr<Schema> {
ObjectBuilder::new()
.schema_type(Type::String)
.max_length(Some(RECURRENCE_RULE_MAX_LEN))
.description(Some("A recurrence rule according to RFC5545"))
.examples([json!(RecurrenceRule::example_data())])
.into()
}
}
impl ToSchema for RecurrenceRule {
fn schemas(schemas: &mut Vec<(String, RefOr<Schema>)>) {
schemas.push((Self::name().into(), Self::schema()));
}
}
}
impl FromStr for RecurrenceRule {
type Err = ParseRecurrenceRuleError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
ensure!(
s.len() <= 1024,
RecurrenceRuleTooLongSnafu {
found_len: s.len(),
max_len: RECURRENCE_RULE_MAX_LEN
}
);
Ok(Self(s.to_string()))
}
}
impl ExampleData for RecurrenceRule {
fn example_data() -> Self {
Self("FREQ=WEEKLY;INTERVAL=1;BYDAY=MO".to_string())
}
}