1pub mod gsm_splitter;
48pub mod gsm_validator;
49pub mod splitter_options;
50pub mod splitter_result;
51pub mod unicode_splitter;
52use splitter_options::SplitterOptions;
54use splitter_result::{SplitterPart, SplitterResult};
55
56#[derive(Debug)]
57pub struct SplitSms {
58 options: SplitterOptions,
59}
60
61impl Default for SplitSms {
62 fn default() -> Self {
63 SplitSms::new(SplitterOptions::default())
64 }
65}
66
67impl SplitSms {
68 pub fn new(options: SplitterOptions) -> SplitSms {
69 SplitSms { options }
70 }
71
72 fn calculate_remaining(
73 &self,
74 parts: &Vec<SplitterPart>,
75 single_bytes: usize,
76 multi_bytes: usize,
77 char_bytes: usize,
78 ) -> usize {
79 let mut max = multi_bytes;
80 if parts.len() == 1 {
81 max = single_bytes;
82 }
83 (max - parts[parts.len() - 1].bytes) / char_bytes
84 }
85
86 fn validate_message(&self, message: String) -> bool {
87 if self.options.support_shift_tables {
88 return gsm_validator::GsmValidator::new().validate_message_with_shift_table(message);
89 }
90 gsm_validator::GsmValidator::new().validate_message(message)
91 }
92
93 pub fn split(&self, message: String) -> SplitSmsResult {
94 let is_gsm = self.validate_message(message.clone());
95 let split_result: SplitterResult;
96 let single_bytes: usize;
97 let multi_bytes: usize;
98 let char_bytes: usize;
99 let character_set: String;
100 if is_gsm {
101 split_result = gsm_splitter::GsmSplitter::new(SplitterOptions::new(
102 self.options.support_shift_tables,
103 self.options.summary,
104 ))
105 .split(message);
106 single_bytes = 160;
107 multi_bytes = 153;
108 char_bytes = 1;
109 character_set = "GSM".to_string();
110 } else {
111 split_result = unicode_splitter::UnicodeSplitter::new(SplitterOptions::new(
112 self.options.support_shift_tables,
113 self.options.summary,
114 ))
115 .split(message);
116 single_bytes = 140;
117 multi_bytes = 134;
118 char_bytes = 2;
119 character_set = "Unicode".to_string();
120 }
121 let remaining_in_part =
122 self.calculate_remaining(&split_result.parts, single_bytes, multi_bytes, char_bytes);
123 SplitSmsResult::new(
124 character_set,
125 split_result.parts,
126 split_result.total_bytes,
127 split_result.total_length,
128 remaining_in_part,
129 )
130 }
131}
132
133#[derive(Debug)]
134pub struct SplitSmsResult {
135 pub character_set: String,
136 pub parts: Vec<SplitterPart>,
137 pub bytes: usize,
138 pub length: usize,
139 pub remaining_in_part: usize,
140}
141
142impl SplitSmsResult {
143 pub fn new(
144 character_set: String,
145 parts: Vec<SplitterPart>,
146 bytes: usize,
147 length: usize,
148 remaining_in_part: usize,
149 ) -> SplitSmsResult {
150 SplitSmsResult {
151 character_set,
152 parts,
153 bytes,
154 length,
155 remaining_in_part,
156 }
157 }
158}
159
160impl Clone for SplitSmsResult {
161 fn clone(&self) -> Self {
162 SplitSmsResult {
163 character_set: self.character_set.clone(),
164 parts: self.parts.clone(),
165 bytes: self.bytes,
166 length: self.length,
167 remaining_in_part: self.remaining_in_part,
168 }
169 }
170}