use ggen_utils::error::Result;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone)]
pub struct GenerateFromRdfOptions {
pub ttl_file: PathBuf,
pub output_dir: PathBuf,
pub template_dir: PathBuf,
}
impl GenerateFromRdfOptions {
pub fn new(ttl_file: PathBuf, output_dir: PathBuf, template_dir: PathBuf) -> Self {
Self {
ttl_file,
output_dir,
template_dir,
}
}
}
#[derive(Debug, Clone)]
pub struct GenerateFromRdfResult {
pub output_dir: PathBuf,
pub files_generated: usize,
pub project_name: String,
}
pub fn generate_cli_from_rdf(options: &GenerateFromRdfOptions) -> Result<GenerateFromRdfResult> {
if !options.ttl_file.exists() {
return Err(ggen_utils::error::Error::new(&format!(
"TTL file not found: {}",
options.ttl_file.display()
)));
}
if !options.template_dir.exists() {
return Err(ggen_utils::error::Error::new(&format!(
"Template directory not found: {}",
options.template_dir.display()
)));
}
std::fs::create_dir_all(&options.output_dir).map_err(|e| {
ggen_utils::error::Error::new(&format!("Failed to create output directory: {}", e))
})?;
let generator = ggen_ai::rdf::CliGenerator::new(options.template_dir.clone());
generator
.generate_from_ttl(&options.ttl_file, &options.output_dir)
.map_err(|e| ggen_utils::error::Error::new(&format!("RDF generation failed: {}", e)))?;
let files_generated = count_files_in_directory(&options.output_dir)?;
let project_name = options
.output_dir
.file_name()
.and_then(|n| n.to_str())
.unwrap_or("generated-project")
.to_string();
Ok(GenerateFromRdfResult {
output_dir: options.output_dir.clone(),
files_generated,
project_name,
})
}
fn count_files_in_directory(dir: &Path) -> Result<usize> {
let mut count = 0;
if !dir.exists() {
return Ok(0);
}
for entry in std::fs::read_dir(dir)
.map_err(|e| ggen_utils::error::Error::new(&format!("Failed to read directory: {}", e)))?
{
let entry = entry
.map_err(|e| ggen_utils::error::Error::new(&format!("Failed to read entry: {}", e)))?;
let path = entry.path();
if path.is_file() {
count += 1;
} else if path.is_dir() {
count += count_files_in_directory(&path)?;
}
}
Ok(count)
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use tempfile::TempDir;
#[test]
fn test_generate_from_rdf_options_creation() {
let options = GenerateFromRdfOptions::new(
PathBuf::from("test.ttl"),
PathBuf::from("output"),
PathBuf::from("templates"),
);
assert_eq!(options.ttl_file, PathBuf::from("test.ttl"));
assert_eq!(options.output_dir, PathBuf::from("output"));
assert_eq!(options.template_dir, PathBuf::from("templates"));
}
#[test]
fn test_count_files_in_directory() {
let temp_dir = TempDir::new().unwrap();
fs::write(temp_dir.path().join("file1.txt"), "content").unwrap();
fs::write(temp_dir.path().join("file2.txt"), "content").unwrap();
fs::create_dir(temp_dir.path().join("subdir")).unwrap();
fs::write(temp_dir.path().join("subdir/file3.txt"), "content").unwrap();
let count = count_files_in_directory(temp_dir.path()).unwrap();
assert_eq!(count, 3);
}
#[test]
fn test_count_files_empty_directory() {
let temp_dir = TempDir::new().unwrap();
let count = count_files_in_directory(temp_dir.path()).unwrap();
assert_eq!(count, 0);
}
#[test]
fn test_count_files_nonexistent_directory() {
let count = count_files_in_directory(Path::new("/nonexistent/path")).unwrap();
assert_eq!(count, 0);
}
#[test]
fn test_generate_cli_from_rdf_missing_ttl() {
let temp_dir = TempDir::new().unwrap();
let options = GenerateFromRdfOptions::new(
PathBuf::from("/nonexistent/test.ttl"),
temp_dir.path().to_path_buf(),
PathBuf::from("templates"),
);
let result = generate_cli_from_rdf(&options);
assert!(result.is_err());
assert!(result
.unwrap_err()
.to_string()
.contains("TTL file not found"));
}
#[test]
fn test_generate_cli_from_rdf_missing_template_dir() {
let temp_dir = TempDir::new().unwrap();
let ttl_file = temp_dir.path().join("test.ttl");
fs::write(&ttl_file, "@prefix cnv: <http://example.com#> .").unwrap();
let options = GenerateFromRdfOptions::new(
ttl_file,
temp_dir.path().join("output"),
PathBuf::from("/nonexistent/templates"),
);
let result = generate_cli_from_rdf(&options);
assert!(result.is_err());
assert!(result
.unwrap_err()
.to_string()
.contains("Template directory not found"));
}
}