Skip to content
Snippets Groups Projects
Select Git revision
  • 5165d3816f419db4fcf6e741d85a6acbfa34c37c
  • main default protected
2 results

sms.rs

Blame
  • sms.rs 6.73 KiB
    use std::{
        io::Write,
        hash::{Hash, Hasher},
        collections::hash_map::DefaultHasher,
        fs::File,
        path::PathBuf,
    };
    
    use regex::Regex;
    
    use crate::{
        SmsError,
        VALID_CHARACTERS,
        CONFIG,
        validate_and_normalize_phonenumber,
    
    };
    
    use serde::{Deserialize, Serialize};
    use chrono::prelude::*;
    use lazy_static::lazy_static;
    
    pub use log::{info, warn, debug, error};
    
    
    
    
    /// Represents an SMS that is to be sent to a phone number
    #[derive(Deserialize, Serialize, PartialEq, Debug)]
    pub struct Sms {
        pub number: String,
        pub text: String,
    }
    
    impl Sms {
        /// Try to create a Sms from the provided number and text
        /// Return an Error if the text was too long, too short, has
        /// invalid characters or if the phonenumber format is invalid
        pub fn try_from(number: &str, text: &str) -> Result<Self, SmsError> {
            if text.len() < CONFIG.sms.min_length {
                warn!("SMS-text was too short: {} character(s)", text.len());
                return Err(SmsError::TooShort);
            }
            if text.len() > CONFIG.sms.max_length {
                warn!("SMS-text was too long: {} characters", text.len());
                return Err(SmsError::TooLong);
            }
            if text.chars().any(|c| !VALID_CHARACTERS.contains(&c)) {
                warn!("SMS-text contained illegal characters: \"{}\"", text);
                return Err(SmsError::InvalidCharacters);
            }
            let number = validate_and_normalize_phonenumber(number)?;
            Ok(Sms {
                number,
                text: text.to_string()
            })
        }
    
        pub fn deserialize_from(body: &str) -> Result<Self, SmsError> {
            lazy_static! {
                // flags m: multiline, s: allow . to match \n
                static ref SMS_PATTERN: Regex = Regex::new(r"(?ms)^To:\s([0-9+]+)(?:(?:\n\w*:\s?\w+))*?\n\n+(.*)").unwrap();
            }
    
            let captures = match SMS_PATTERN.captures(body) {
                Some(c) => c,
                None => return Err(SmsError::DeserializationError(body.to_string()))
            };
    
            let number = captures.get(1).map_or("", |m| m.as_str()).trim();