164 lines
5.9 KiB
Rust
164 lines
5.9 KiB
Rust
use regex::Regex;
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ScriptureSection {
|
|
pub verse: String,
|
|
pub reference: String,
|
|
}
|
|
|
|
/// Format raw scripture text into structured sections with verses and references
|
|
pub fn format_scripture_text(text: &str) -> Vec<ScriptureSection> {
|
|
// Handle single-line format where verse and reference are together
|
|
if text.contains(" KJV") && !text.contains('\n') {
|
|
// Single line format: "verse text. Book chapter:verse KJV"
|
|
if let Some(kjv_pos) = text.rfind(" KJV") {
|
|
let before_kjv = &text[..kjv_pos];
|
|
// Find the last period or other punctuation that separates verse from reference
|
|
if let Some(last_period) = before_kjv.rfind('.') {
|
|
if let Some(reference_start) = before_kjv[last_period..].find(char::is_alphabetic) {
|
|
let actual_start = last_period + reference_start;
|
|
let verse_text = format!("{}.", &before_kjv[..last_period]);
|
|
let reference = format!("{} KJV", &before_kjv[actual_start..]);
|
|
return vec![ScriptureSection {
|
|
verse: verse_text.trim().to_string(),
|
|
reference: reference.trim().to_string(),
|
|
}];
|
|
}
|
|
}
|
|
}
|
|
// Fallback: treat entire text as verse with no separate reference
|
|
return vec![ScriptureSection {
|
|
verse: text.to_string(),
|
|
reference: String::new(),
|
|
}];
|
|
}
|
|
|
|
// Multi-line format (original logic)
|
|
let sections: Vec<&str> = text.split('\n').collect();
|
|
let mut formatted_sections = Vec::new();
|
|
let mut current_verse = String::new();
|
|
|
|
for section in sections {
|
|
let trimmed = section.trim();
|
|
if trimmed.is_empty() {
|
|
continue;
|
|
}
|
|
|
|
// Check if this line is a reference (contains "KJV" at the end)
|
|
if trimmed.ends_with("KJV") {
|
|
// This is a reference for the verse we just accumulated
|
|
if !current_verse.is_empty() {
|
|
formatted_sections.push(ScriptureSection {
|
|
verse: current_verse.clone(),
|
|
reference: trimmed.to_string(),
|
|
});
|
|
current_verse.clear(); // Reset for next verse
|
|
}
|
|
} else {
|
|
// This is verse text
|
|
if !current_verse.is_empty() {
|
|
current_verse.push(' ');
|
|
}
|
|
current_verse.push_str(trimmed);
|
|
}
|
|
}
|
|
|
|
// Add any remaining verse without a reference
|
|
if !current_verse.is_empty() {
|
|
formatted_sections.push(ScriptureSection {
|
|
verse: current_verse,
|
|
reference: String::new(),
|
|
});
|
|
}
|
|
|
|
formatted_sections
|
|
}
|
|
|
|
/// Extract scripture references from text (e.g., "Joel 2:28 KJV" patterns)
|
|
pub fn extract_scripture_references(text: &str) -> String {
|
|
let pattern = r"([1-3]?\s*[A-Za-z]+\s+\d+:\d+(?:-\d+)?)\s+KJV";
|
|
|
|
match Regex::new(pattern) {
|
|
Ok(regex) => {
|
|
let references: Vec<String> = regex
|
|
.captures_iter(text)
|
|
.filter_map(|cap| cap.get(1).map(|m| m.as_str().trim().to_string()))
|
|
.collect();
|
|
|
|
if references.is_empty() {
|
|
"Scripture Reading".to_string()
|
|
} else {
|
|
references.join(", ")
|
|
}
|
|
}
|
|
Err(_) => "Scripture Reading".to_string(),
|
|
}
|
|
}
|
|
|
|
/// Create standardized share text for sermons
|
|
pub fn create_sermon_share_text(title: &str, speaker: &str, video_url: Option<&str>, audio_url: Option<&str>) -> Vec<String> {
|
|
let mut items = Vec::new();
|
|
|
|
// Create share text
|
|
let share_text = format!("Check out this sermon: \"{}\" by {}", title, speaker);
|
|
items.push(share_text);
|
|
|
|
// Add video URL if available, otherwise audio URL
|
|
if let Some(url) = video_url {
|
|
items.push(url.to_string());
|
|
} else if let Some(url) = audio_url {
|
|
items.push(url.to_string());
|
|
}
|
|
|
|
items
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_single_line_scripture_format() {
|
|
let input = "And it shall come to pass afterward, that I will pour out my spirit upon all flesh. Joel 2:28 KJV";
|
|
let result = format_scripture_text(input);
|
|
|
|
assert_eq!(result.len(), 1);
|
|
assert_eq!(result[0].verse, "And it shall come to pass afterward, that I will pour out my spirit upon all flesh.");
|
|
assert_eq!(result[0].reference, "Joel 2:28 KJV");
|
|
}
|
|
|
|
#[test]
|
|
fn test_multi_line_scripture_format() {
|
|
let input = "And it shall come to pass afterward, that I will pour out my spirit upon all flesh\nJoel 2:28 KJV\nQuench not the Spirit. Despise not prophesyings.\n1 Thessalonians 5:19-21 KJV";
|
|
let result = format_scripture_text(input);
|
|
|
|
assert_eq!(result.len(), 2);
|
|
assert_eq!(result[0].verse, "And it shall come to pass afterward, that I will pour out my spirit upon all flesh");
|
|
assert_eq!(result[0].reference, "Joel 2:28 KJV");
|
|
assert_eq!(result[1].verse, "Quench not the Spirit. Despise not prophesyings.");
|
|
assert_eq!(result[1].reference, "1 Thessalonians 5:19-21 KJV");
|
|
}
|
|
|
|
#[test]
|
|
fn test_extract_scripture_references() {
|
|
let input = "Some text with Joel 2:28 KJV and 1 Thessalonians 5:19-21 KJV references";
|
|
let result = extract_scripture_references(input);
|
|
|
|
assert_eq!(result, "Joel 2:28, 1 Thessalonians 5:19-21");
|
|
}
|
|
|
|
#[test]
|
|
fn test_create_sermon_share_text() {
|
|
let result = create_sermon_share_text(
|
|
"Test Sermon",
|
|
"John Doe",
|
|
Some("https://example.com/video"),
|
|
Some("https://example.com/audio")
|
|
);
|
|
|
|
assert_eq!(result.len(), 2);
|
|
assert_eq!(result[0], "Check out this sermon: \"Test Sermon\" by John Doe");
|
|
assert_eq!(result[1], "https://example.com/video");
|
|
}
|
|
} |