use crate::types::{Email, Person};
#[inline]
pub fn bytes_to_string(value: &[u8]) -> String {
std::str::from_utf8(value).map_or_else(
|_| String::from_utf8_lossy(value).into_owned(),
std::string::ToString::to_string,
)
}
#[inline]
#[must_use]
pub fn truncate_to_length(s: &str, max_len: usize) -> String {
if s.len() <= max_len {
s.to_string()
} else {
s.chars().take(max_len).collect()
}
}
#[must_use]
pub fn parse_rss_person(text: &str) -> Person {
let text = text.trim();
if let Some(paren_start) = text.find('(')
&& text.ends_with(')')
{
let email_part = text[..paren_start].trim();
let name_part = text[paren_start + 1..text.len() - 1].trim();
if !email_part.is_empty() {
return Person {
name: if name_part.is_empty() {
None
} else {
Some(name_part.into())
},
email: Some(Email::new(email_part.to_string())),
uri: None,
avatar: None,
};
}
}
if let Some(angle_start) = text.rfind('<')
&& text.ends_with('>')
{
let name_part = text[..angle_start].trim();
let email_part = text[angle_start + 1..text.len() - 1].trim();
if !email_part.is_empty() {
return Person {
name: if name_part.is_empty() {
None
} else {
Some(name_part.into())
},
email: Some(Email::new(email_part.to_string())),
uri: None,
avatar: None,
};
}
}
if text.contains('@') {
Person {
name: None,
email: Some(Email::new(text.to_string())),
uri: None,
avatar: None,
}
} else {
Person::from_name(text)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_rss_person_email_paren_name() {
let p = parse_rss_person("editor@example.com (John Editor)");
assert_eq!(p.name.as_deref(), Some("John Editor"));
assert_eq!(p.email.as_deref(), Some("editor@example.com"));
}
#[test]
fn test_parse_rss_person_name_angle_email() {
let p = parse_rss_person("John Editor <editor@example.com>");
assert_eq!(p.name.as_deref(), Some("John Editor"));
assert_eq!(p.email.as_deref(), Some("editor@example.com"));
}
#[test]
fn test_parse_rss_person_bare_email() {
let p = parse_rss_person("editor@example.com");
assert!(p.name.is_none());
assert_eq!(p.email.as_deref(), Some("editor@example.com"));
}
#[test]
fn test_parse_rss_person_plain_name() {
let p = parse_rss_person("John Editor");
assert_eq!(p.name.as_deref(), Some("John Editor"));
assert!(p.email.is_none());
}
#[test]
fn test_parse_rss_person_empty_name_in_parens() {
let p = parse_rss_person("editor@example.com ()");
assert!(p.name.is_none());
assert_eq!(p.email.as_deref(), Some("editor@example.com"));
}
}