use std::fs;
use std::path::Path;
#[derive(Debug, Clone)]
pub struct Document {
pub doc_id: String,
pub text: String,
pub source: String,
pub title: String,
pub is_reference: bool,
}
fn source_for_dir(dir_name: &str) -> (String, bool) {
match dir_name {
"textfiles" => ("textfile".to_string(), true),
other => (other.to_string(), false),
}
}
pub fn load_raw_docs(raw_root: &Path) -> std::io::Result<Vec<Document>> {
let mut docs = Vec::new();
if !raw_root.is_dir() {
return Ok(docs);
}
for sub in fs::read_dir(raw_root)? {
let sub = sub?.path();
if !sub.is_dir() {
continue;
}
let dir_name = sub.file_name().and_then(|n| n.to_str()).unwrap_or("").to_string();
let (source, is_reference) = source_for_dir(&dir_name);
for entry in fs::read_dir(&sub)? {
let path = entry?.path();
if path.extension().and_then(|e| e.to_str()) != Some("txt") {
continue;
}
let stem = path.file_stem().and_then(|s| s.to_str()).unwrap_or("").to_string();
let text = match fs::read_to_string(&path) {
Ok(t) => t,
Err(e) => {
eprintln!("kibble: skipping unreadable {}: {e}", path.display());
continue;
}
};
if text.trim().is_empty() {
continue;
}
docs.push(Document {
doc_id: format!("{source}:{stem}"),
text,
source: source.clone(),
title: stem,
is_reference,
});
}
}
Ok(docs)
}
#[cfg(test)]
mod tests {
use super::load_raw_docs;
use std::fs;
#[test]
fn loads_docs_with_source_and_reference_flags() {
let dir = std::env::temp_dir().join(format!("kibble_corpus_test_{}", std::process::id()));
let _ = fs::remove_dir_all(&dir);
let raw = dir.join("raw");
fs::create_dir_all(raw.join("twitter")).unwrap();
fs::create_dir_all(raw.join("textfiles")).unwrap();
fs::write(raw.join("twitter").join("tweet_111.txt"), "hello world").unwrap();
fs::write(raw.join("twitter").join("manifest.json"), "{}").unwrap();
fs::write(raw.join("textfiles").join("phrack_1.txt"), "old school text").unwrap();
let mut docs = load_raw_docs(&raw).unwrap();
docs.sort_by(|a, b| a.doc_id.cmp(&b.doc_id));
assert_eq!(docs.len(), 2); let tw = docs.iter().find(|d| d.source == "twitter").unwrap();
assert_eq!(tw.doc_id, "twitter:tweet_111");
assert!(!tw.is_reference);
let tf = docs.iter().find(|d| d.source == "textfile").unwrap();
assert!(tf.is_reference);
assert_eq!(tf.title, "phrack_1");
}
}