torsh-text 0.1.2

Natural language processing utilities for ToRSh deep learning framework
Documentation
//! Simple syntax verification for new torsh-text features
//!
//! This example verifies that the new enhanced features compile correctly

use std::collections::HashMap;

// Mock the external dependencies to verify our API design
#[allow(dead_code)]
mod mock_deps {
    pub struct Tensor;

    pub mod device {
        #[derive(Debug, Clone, Copy)]
        pub enum DeviceType {
            Cpu,
        }
    }

    pub mod random {
        pub struct Random<T> {
            _phantom: std::marker::PhantomData<T>,
        }

        impl<T> Random<T> {
            pub fn seed(_seed: u64) -> Self {
                Self {
                    _phantom: std::marker::PhantomData,
                }
            }

            pub fn gen_range(&mut self, range: std::ops::Range<usize>) -> usize {
                if range.start < range.end {
                    range.start + (range.end - range.start) / 2
                } else {
                    range.start
                }
            }
        }

        pub fn rng() -> Random<MockRng> {
            Random::seed(42)
        }

        pub struct MockRng;
    }

    #[derive(Debug)]
    pub enum TextError {
        Other(String),
    }

    impl std::fmt::Display for TextError {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            write!(f, "TextError")
        }
    }

    impl std::error::Error for TextError {}

    pub type Result<T> = std::result::Result<T, TextError>;
}

// Mock our enhanced functionality
use mock_deps::*;

/// Advanced text statistics with enhanced metrics
#[derive(Debug, Clone)]
pub struct AdvancedTextStats {
    pub char_count: usize,
    pub word_count: usize,
    pub sentence_count: usize,
    pub paragraph_count: usize,
    pub unique_words: usize,
    pub lexical_diversity: f64,
    pub average_word_length: f64,
    pub average_sentence_length: f64,
    pub readability_score: f64,
}

/// Text complexity metrics
#[derive(Debug, Clone)]
pub struct ComplexityMetrics {
    pub syntactic_complexity: f64,
    pub lexical_complexity: f64,
    pub semantic_complexity: f64,
    pub overall_complexity: f64,
    pub readability_score: f64,
}

/// Performance metrics for text operations
#[derive(Debug, Clone)]
pub struct PerformanceMetrics {
    pub operation: String,
    pub duration: std::time::Duration,
    pub throughput_chars_per_sec: f64,
    pub throughput_words_per_sec: f64,
    pub memory_usage_estimate: usize,
}

/// Advanced text sampler using SciRS2 random generation
pub struct AdvancedTextSampler {
    rng: random::Random<random::MockRng>,
}

impl AdvancedTextSampler {
    pub fn new() -> Self {
        Self {
            rng: random::Random::seed(42),
        }
    }

    pub fn with_seed(seed: u64) -> Self {
        Self {
            rng: random::Random::seed(seed),
        }
    }

    pub fn sample_words(&mut self, text: &str, count: usize) -> Vec<String> {
        let words: Vec<String> = text.split_whitespace().map(|w| w.to_lowercase()).collect();

        if words.is_empty() {
            return Vec::new();
        }

        let mut samples = Vec::new();
        for _ in 0..count {
            let idx = self.rng.gen_range(0..words.len());
            samples.push(words[idx].clone());
        }
        samples
    }

    pub fn generate_markov_text(&mut self, text: &str, length: usize, order: usize) -> String {
        let words: Vec<&str> = text.split_whitespace().collect();
        if words.len() < order + 1 {
            return text.to_string();
        }

        // Build simple Markov chain
        let mut chain: HashMap<Vec<String>, Vec<String>> = HashMap::new();

        for i in 0..=words.len().saturating_sub(order + 1) {
            let key: Vec<String> = words[i..i + order].iter().map(|s| s.to_string()).collect();
            let next_word = words[i + order].to_string();
            chain.entry(key).or_default().push(next_word);
        }

        // Generate text
        let mut result = Vec::new();
        let mut current_key: Vec<String> = words[0..order].iter().map(|s| s.to_string()).collect();
        result.extend(current_key.clone());

        for _ in 0..length.saturating_sub(order) {
            if let Some(next_words) = chain.get(&current_key) {
                if !next_words.is_empty() {
                    let idx = self.rng.gen_range(0..next_words.len());
                    let next_word = next_words[idx].clone();
                    result.push(next_word.clone());

                    // Update current key
                    current_key.remove(0);
                    current_key.push(next_word);
                } else {
                    break;
                }
            } else {
                break;
            }
        }

        result.join(" ")
    }
}

impl Default for AdvancedTextSampler {
    fn default() -> Self {
        Self::new()
    }
}

/// Performance monitor for text operations
pub struct PerformanceMonitor {
    start_time: Option<std::time::Instant>,
    operation_name: String,
}

impl PerformanceMonitor {
    pub fn new(operation: &str) -> Self {
        Self {
            start_time: None,
            operation_name: operation.to_string(),
        }
    }

    pub fn start(&mut self) {
        self.start_time = Some(std::time::Instant::now());
    }

    pub fn stop(&mut self, text: &str) -> PerformanceMetrics {
        let duration = self
            .start_time
            .map(|start| start.elapsed())
            .unwrap_or(std::time::Duration::ZERO);

        let char_count = text.chars().count();
        let word_count = text.split_whitespace().count();

        let throughput_chars_per_sec = if duration.as_secs_f64() > 0.0 {
            char_count as f64 / duration.as_secs_f64()
        } else {
            0.0
        };

        let throughput_words_per_sec = if duration.as_secs_f64() > 0.0 {
            word_count as f64 / duration.as_secs_f64()
        } else {
            0.0
        };

        PerformanceMetrics {
            operation: self.operation_name.clone(),
            duration,
            throughput_chars_per_sec,
            throughput_words_per_sec,
            memory_usage_estimate: text.len() + (word_count * 8),
        }
    }

    pub fn time_operation<F, R>(&mut self, text: &str, operation: F) -> (R, PerformanceMetrics)
    where
        F: FnOnce() -> R,
    {
        self.start();
        let result = operation();
        let metrics = self.stop(text);
        (result, metrics)
    }
}

/// Compute advanced text statistics
pub fn compute_advanced_stats(text: &str) -> Result<AdvancedTextStats> {
    let chars = text.chars().count();
    let words: Vec<&str> = text.split_whitespace().collect();
    let word_count = words.len();

    // Count sentences (basic heuristic)
    let sentences = text
        .split(&['.', '!', '?'])
        .filter(|s| !s.trim().is_empty())
        .count();

    // Count paragraphs
    let paragraphs = text
        .split("\n\n")
        .filter(|s| !s.trim().is_empty())
        .count()
        .max(1);

    // Unique words
    let unique_words: std::collections::HashSet<String> =
        words.iter().map(|w| w.to_lowercase()).collect();
    let unique_count = unique_words.len();

    // Lexical diversity (Type-Token Ratio)
    let lexical_diversity = if word_count > 0 {
        unique_count as f64 / word_count as f64
    } else {
        0.0
    };

    // Average word length
    let avg_word_length = if word_count > 0 {
        words.iter().map(|w| w.len()).sum::<usize>() as f64 / word_count as f64
    } else {
        0.0
    };

    // Average sentence length
    let avg_sentence_length = if sentences > 0 {
        word_count as f64 / sentences as f64
    } else {
        0.0
    };

    // Simple readability score (Flesch-like approximation)
    let readability_score = if sentences > 0 && word_count > 0 {
        206.835 - (1.015 * avg_sentence_length) - (84.6 * (avg_word_length / 4.7))
    } else {
        0.0
    };

    Ok(AdvancedTextStats {
        char_count: chars,
        word_count,
        sentence_count: sentences,
        paragraph_count: paragraphs,
        unique_words: unique_count,
        lexical_diversity,
        average_word_length: avg_word_length,
        average_sentence_length: avg_sentence_length,
        readability_score,
    })
}

/// Text complexity analyzer
pub struct ComplexityAnalyzer;

impl ComplexityAnalyzer {
    pub fn analyze_complexity(text: &str) -> Result<ComplexityMetrics> {
        let stats = compute_advanced_stats(text)?;

        // Syntactic complexity (average sentence length)
        let syntactic_complexity = (stats.average_sentence_length / 20.0).min(1.0);

        // Lexical complexity (unique word ratio and average word length)
        let lexical_complexity =
            ((stats.lexical_diversity * 0.7) + (stats.average_word_length / 10.0 * 0.3)).min(1.0);

        // Semantic complexity (approximated by word length distribution)
        let words: Vec<&str> = text.split_whitespace().collect();
        let long_words = words.iter().filter(|w| w.len() > 6).count();
        let semantic_complexity = if !words.is_empty() {
            (long_words as f64 / words.len() as f64).min(1.0)
        } else {
            0.0
        };

        // Overall complexity score
        let overall_complexity =
            (syntactic_complexity + lexical_complexity + semantic_complexity) / 3.0;

        Ok(ComplexityMetrics {
            syntactic_complexity,
            lexical_complexity,
            semantic_complexity,
            overall_complexity,
            readability_score: stats.readability_score,
        })
    }
}

fn main() -> Result<()> {
    println!("🔍 Torsh-Text Enhanced Features Syntax Check");
    println!("=============================================");

    let text = "This is a comprehensive test of the enhanced torsh-text functionality. \
                It includes advanced analytics, performance monitoring, and text sampling.";

    // Test advanced statistics
    println!("📊 Testing Advanced Text Statistics...");
    let stats = compute_advanced_stats(text)?;
    println!(
        "✅ Advanced stats computed: {} words, {:.3} lexical diversity",
        stats.word_count, stats.lexical_diversity
    );

    // Test complexity analysis
    println!("\n🧠 Testing Complexity Analysis...");
    let complexity = ComplexityAnalyzer::analyze_complexity(text)?;
    println!(
        "✅ Complexity analyzed: {:.3} overall complexity",
        complexity.overall_complexity
    );

    // Test text sampling
    println!("\n🎲 Testing Text Sampling...");
    let mut sampler = AdvancedTextSampler::with_seed(123);
    let samples = sampler.sample_words(text, 3);
    println!("✅ Random words sampled: {:?}", samples);

    // Test Markov generation
    println!("\n📝 Testing Markov Generation...");
    let generated = sampler.generate_markov_text(text, 10, 2);
    println!("✅ Generated text: {}", generated);

    // Test performance monitoring
    println!("\n⚡ Testing Performance Monitoring...");
    let mut monitor = PerformanceMonitor::new("syntax_test");
    let (word_count, metrics) = monitor.time_operation(text, || text.split_whitespace().count());
    println!(
        "✅ Performance monitored: {} words processed in {:.3}ms",
        word_count,
        metrics.duration.as_secs_f64() * 1000.0
    );

    println!("\n🎉 All enhanced features syntax check passed!");
    Ok(())
}