use crate::encoding::split_content;
use crate::pdu::Submit;
#[derive(Debug, Clone)]
pub struct SubmitOptions {
pub service_id: String,
pub msg_src: String,
pub src_id: String,
pub dest_terminal_ids: Vec<String>,
pub registered_delivery: u8,
pub msg_level: u8,
pub fee_user_type: u8,
pub fee_terminal_id: String,
pub fee_type: String,
pub fee_code: String,
pub tp_pid: u8,
pub valid_time: String,
pub at_time: String,
}
impl SubmitOptions {
pub fn new(
service_id: impl Into<String>,
msg_src: impl Into<String>,
src_id: impl Into<String>,
dest_terminal_id: impl Into<String>,
) -> Self {
SubmitOptions {
service_id: service_id.into(),
msg_src: msg_src.into(),
src_id: src_id.into(),
dest_terminal_ids: vec![dest_terminal_id.into()],
registered_delivery: 1,
msg_level: 0,
fee_user_type: 2,
fee_terminal_id: String::new(),
fee_type: "01".into(),
fee_code: "000000".into(),
tp_pid: 0,
valid_time: String::new(),
at_time: String::new(),
}
}
pub fn dest_terminal_ids(mut self, ids: Vec<String>) -> Self {
self.dest_terminal_ids = ids;
self
}
pub fn registered_delivery(mut self, v: u8) -> Self {
self.registered_delivery = v;
self
}
pub fn msg_level(mut self, v: u8) -> Self {
self.msg_level = v;
self
}
pub fn fee(
mut self,
user_type: u8,
fee_type: impl Into<String>,
fee_code: impl Into<String>,
) -> Self {
self.fee_user_type = user_type;
self.fee_type = fee_type.into();
self.fee_code = fee_code.into();
self
}
pub fn build_submits(&self, content: &str) -> Vec<Submit> {
split_content(content)
.into_iter()
.map(|seg| Submit {
msg_id: [0u8; 8],
pk_total: seg.pk_total,
pk_number: seg.pk_number,
registered_delivery: self.registered_delivery,
msg_level: self.msg_level,
service_id: self.service_id.clone(),
fee_user_type: self.fee_user_type,
fee_terminal_id: self.fee_terminal_id.clone(),
tp_pid: self.tp_pid,
tp_udhi: seg.tp_udhi,
msg_fmt: seg.msg_fmt,
msg_src: self.msg_src.clone(),
fee_type: self.fee_type.clone(),
fee_code: self.fee_code.clone(),
valid_time: self.valid_time.clone(),
at_time: self.at_time.clone(),
src_id: self.src_id.clone(),
dest_terminal_ids: self.dest_terminal_ids.clone(),
msg_content: seg.content,
})
.collect()
}
pub fn build_short_submit(&self, content: &str) -> Option<Submit> {
let mut submits = self.build_submits(content);
if submits.len() == 1 && submits[0].tp_udhi == 0 {
Some(submits.remove(0))
} else {
None
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn short_ascii_is_single_segment() {
let opts = SubmitOptions::new("SVC", "901234", "10690001", "13800138000");
let submits = opts.build_submits("hello");
assert_eq!(submits.len(), 1);
assert_eq!(submits[0].pk_total, 1);
assert_eq!(submits[0].tp_udhi, 0);
assert_eq!(submits[0].registered_delivery, 1);
assert_eq!(
submits[0].dest_terminal_ids,
vec!["13800138000".to_string()]
);
}
#[test]
fn long_chinese_splits() {
let opts = SubmitOptions::new("SVC", "901234", "10690001", "13800138000");
let content: String = "中".repeat(100);
let submits = opts.build_submits(&content);
assert!(submits.len() >= 2);
for (i, s) in submits.iter().enumerate() {
assert_eq!(s.tp_udhi, 1);
assert_eq!(s.pk_number as usize, i + 1);
assert_eq!(s.pk_total as usize, submits.len());
}
}
}