use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use crate::types::Keyword;
pub(super) fn line_number_at_offset(source: &str, offset: usize) -> usize {
let clamped = offset.min(source.len());
source[..clamped].bytes().filter(|&b| b == b'\n').count() + 1
}
pub(super) fn slugify(s: &str) -> String {
let mut result = String::new();
let mut last_was_sep = true; for c in s.chars() {
if c.is_alphanumeric() {
result.push(c.to_ascii_lowercase());
last_was_sep = false;
} else if !last_was_sep {
result.push('_');
last_was_sep = true;
}
}
while result.ends_with('_') {
result.pop();
}
if result.len() > 60 {
result.truncate(60);
while result.ends_with('_') {
result.pop();
}
}
result
}
pub(super) fn content_hash(
keyword: Keyword,
text: &str,
condition: &Option<String>,
pending: bool,
) -> String {
let mut hasher = DefaultHasher::new();
format!("{:?}", keyword).hash(&mut hasher);
text.hash(&mut hasher);
condition.hash(&mut hasher);
pending.hash(&mut hasher);
format!("{:016x}", hasher.finish())
}