use super::MessageParser;
use crate::errors::ParseError;
use crate::traits::SwiftField;
pub fn extract_block4(input: &str) -> Result<String, ParseError> {
if input.starts_with("{") {
super::SwiftParser::extract_block(input, 4)?.ok_or_else(|| ParseError::InvalidFormat {
message: "Block 4 not found".to_string(),
})
} else {
Ok(input.to_string())
}
}
pub fn append_field<T: SwiftField>(result: &mut String, field: &T) {
result.push_str(&field.to_swift_string());
result.push_str("\r\n");
}
pub fn append_optional_field<T: SwiftField>(result: &mut String, field: &Option<T>) {
if let Some(f) = field {
result.push_str(&f.to_swift_string());
result.push_str("\r\n");
}
}
pub fn append_vec_field<T: SwiftField>(result: &mut String, fields: &Option<Vec<T>>) {
if let Some(vec) = fields {
for field in vec {
result.push_str(&field.to_swift_string());
result.push_str("\r\n");
}
}
}
pub fn parse_repeated_field<T: crate::traits::SwiftField>(
parser: &mut MessageParser,
tag: &str,
) -> Result<Option<Vec<T>>, ParseError> {
let mut fields = Vec::new();
while let Ok(field) = parser.parse_field::<T>(tag) {
fields.push(field);
}
Ok(if fields.is_empty() {
None
} else {
Some(fields)
})
}
pub fn verify_parser_complete(parser: &MessageParser) -> Result<(), ParseError> {
if !parser.is_complete() {
return Err(ParseError::InvalidFormat {
message: format!(
"Unparsed content remaining in message: {}",
parser.remaining()
),
});
}
Ok(())
}
pub fn remove_trailing_crlf(result: &mut String) {
if result.ends_with("\r\n") {
result.truncate(result.len() - 2);
}
}
pub fn finalize_mt_string(mut result: String, add_terminator: bool) -> String {
remove_trailing_crlf(&mut result);
if add_terminator {
result.push('-');
}
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_extract_block4_with_blocks() {
let input = "{1:F01BANKFRPPAXXX0000000000}{4:\r\n:20:TEST123\r\n-}";
let result = extract_block4(input);
assert!(result.is_ok());
assert!(result.unwrap().contains(":20:TEST123"));
}
#[test]
fn test_extract_block4_plain() {
let input = ":20:TEST123\r\n";
let result = extract_block4(input);
assert!(result.is_ok());
assert_eq!(result.unwrap(), input);
}
#[test]
fn test_extract_block4_missing() {
let input = "{1:F01BANKFRPPAXXX0000000000}";
let result = extract_block4(input);
assert!(result.is_err());
}
#[test]
fn test_remove_trailing_crlf() {
let mut s = String::from("test\r\n");
remove_trailing_crlf(&mut s);
assert_eq!(s, "test");
let mut s2 = String::from("test");
remove_trailing_crlf(&mut s2);
assert_eq!(s2, "test");
}
#[test]
fn test_finalize_mt_string() {
let result = finalize_mt_string(String::from("test\r\n"), true);
assert_eq!(result, "test-");
let result2 = finalize_mt_string(String::from("test\r\n"), false);
assert_eq!(result2, "test");
}
}