From 3e29e3a9012198c1e0545b2b6261779efaa82580 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Sat, 1 Jun 2024 16:00:55 +0100 Subject: [PATCH] Add validation of message length in builder --- src/types/calls.rs | 62 ++++++++++++++++++++++++++++++++++++++++++++++ src/types/news.rs | 59 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) diff --git a/src/types/calls.rs b/src/types/calls.rs index df54d84..ed14abc 100644 --- a/src/types/calls.rs +++ b/src/types/calls.rs @@ -3,6 +3,7 @@ use derive_builder::Builder; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Builder)] +#[builder(build_fn(validate = "Self::validate"))] pub struct OutgoingCall { /// Message text of the call pub(crate) text: String, @@ -20,6 +21,21 @@ pub struct OutgoingCall { pub(crate) emergency: bool, } +impl OutgoingCallBuilder { + fn validate(&self) -> Result<(), String> { + match &self.text { + Some(text) => { + if text.len() > 80 { + Err("Text must be 80 characters or less".to_string()) + } else { + Ok(()) + } + } + None => Err("Text must be set".to_string()), + } + } +} + #[derive(Debug, Deserialize)] pub struct Call { /// Message text of the call @@ -43,3 +59,49 @@ pub struct Call { /// Flag indicating if this call was sent with high priority pub emergency: bool, } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn build_80_char() { + let text = + "01234567890123456789012345678901234567890123456789012345678901234567890123456789"; + assert_eq!(text.len(), 80); + + let call = OutgoingCallBuilder::default() + .recipients(vec!["m0nxn".to_string()]) + .transmitter_groups(vec!["all".to_string()]) + .text(text.to_string()) + .build() + .unwrap(); + + assert_eq!(call.text, text); + } + + #[test] + #[should_panic] + fn build_81_char() { + let text = + "012345678901234567890123456789012345678901234567890123456789012345678901234567890"; + assert_eq!(text.len(), 81); + + let _ = OutgoingCallBuilder::default() + .recipients(vec!["m0nxn".to_string()]) + .transmitter_groups(vec!["all".to_string()]) + .text(text.to_string()) + .build() + .unwrap(); + } + + #[test] + #[should_panic] + fn build_no_text() { + let _ = OutgoingCallBuilder::default() + .recipients(vec!["m0nxn".to_string()]) + .transmitter_groups(vec!["all".to_string()]) + .build() + .unwrap(); + } +} diff --git a/src/types/news.rs b/src/types/news.rs index 0b1bce2..8ef2e4c 100644 --- a/src/types/news.rs +++ b/src/types/news.rs @@ -3,6 +3,7 @@ use derive_builder::Builder; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Builder)] +#[builder(build_fn(validate = "Self::validate"))] pub struct OutgoingNews { /// Name of the rubric to send to #[serde(rename = "rubricName")] @@ -16,6 +17,21 @@ pub struct OutgoingNews { pub(crate) number: i8, } +impl OutgoingNewsBuilder { + fn validate(&self) -> Result<(), String> { + match &self.text { + Some(text) => { + if text.len() > 80 { + Err("Text must be 80 characters or less".to_string()) + } else { + Ok(()) + } + } + None => Err("Text must be set".to_string()), + } + } +} + #[derive(Debug, Deserialize)] pub struct News { /// Name of the rubric to send to @@ -35,3 +51,46 @@ pub struct News { #[serde(rename = "ownerName")] pub sender: String, } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn build_80_char() { + let text = + "01234567890123456789012345678901234567890123456789012345678901234567890123456789"; + assert_eq!(text.len(), 80); + + let news = OutgoingNewsBuilder::default() + .rubric("test".to_string()) + .text(text.to_string()) + .build() + .unwrap(); + + assert_eq!(news.text, text); + } + + #[test] + #[should_panic] + fn build_81_char() { + let text = + "012345678901234567890123456789012345678901234567890123456789012345678901234567890"; + assert_eq!(text.len(), 81); + + let _ = OutgoingNewsBuilder::default() + .rubric("test".to_string()) + .text(text.to_string()) + .build() + .unwrap(); + } + + #[test] + #[should_panic] + fn build_no_text() { + let _ = OutgoingNewsBuilder::default() + .rubric("test".to_string()) + .build() + .unwrap(); + } +}