feat: implement CLI for XBRL parsing and validation

- Parse command with optional stats flag
- Validate command with SEC EDGAR profile support
- Benchmark command for performance testing
- Colored output for better UX
This commit is contained in:
Stefano Amorelli
2025-08-16 17:25:06 +03:00
parent fd5b3a968d
commit 46ecbd2635
20 changed files with 25911 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
use std::env;
use std::fs;
use std::time::Instant;
use crabrl::Parser;
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
eprintln!("Usage: {} <xbrl_file>", args[0]);
std::process::exit(1);
}
let filename = &args[1];
let content = fs::read_to_string(filename)
.expect("Failed to read file");
let parser = Parser::new();
let start = Instant::now();
match parser.parse(&content) {
Ok(document) => {
let elapsed = start.elapsed();
println!("Parsed in {:.3}ms: {} facts, {} contexts, {} units",
elapsed.as_secs_f64() * 1000.0,
document.facts.len(),
document.contexts.len(),
document.units.len());
}
Err(e) => {
eprintln!("Parse error: {}", e);
std::process::exit(1);
}
}
}

27
examples/parse.rs Normal file
View File

@@ -0,0 +1,27 @@
//! Basic parsing example
use crabrl::Parser;
use std::env;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
eprintln!("Usage: {} <xbrl-file>", args[0]);
std::process::exit(1);
}
let parser = Parser::new();
let doc = parser.parse_file(&args[1])?;
println!("Parsed {} successfully", args[1]);
println!(" Facts: {}", doc.facts.len());
println!(" Contexts: {}", doc.contexts.len());
println!(" Units: {}", doc.units.len());
// Show first 5 facts
for fact in doc.facts.iter().take(5) {
println!(" - {}: {}", fact.name, fact.value);
}
Ok(())
}

35
examples/validate.rs Normal file
View File

@@ -0,0 +1,35 @@
//! Validation example
use crabrl::{Parser, Validator};
use std::env;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
eprintln!("Usage: {} <xbrl-file>", args[0]);
std::process::exit(1);
}
// Parse
let parser = Parser::new();
let doc = parser.parse_file(&args[1])?;
// Validate
let validator = Validator::new();
let result = validator.validate(&doc)?;
if result.is_valid {
println!("✓ Document is valid");
} else {
println!("✗ Document has {} errors", result.errors.len());
for error in result.errors.iter().take(5) {
println!(" - {}", error);
}
}
println!("\nValidation stats:");
println!(" Facts validated: {}", result.stats.facts_validated);
println!(" Time: {}ms", result.stats.duration_ms);
Ok(())
}