webpage_quality_analyzer 1.0.2

High-performance webpage quality analyzer with 115 comprehensive metrics - Rust library with WASM, C++, and Python bindings
Documentation
//! Phase 5 Profile Customization Example
//!
//! This example demonstrates the User Configuration Interface features:
//! - ProfileBuilder fluent API
//! - Content type presets
//! - Custom metric weights and thresholds
//! - ProfileTemplates system
//! - Template-based customization

use webpage_quality_analyzer::config::enhanced_models::QualityBandConfig;
use webpage_quality_analyzer::config::profile_builder::ContentType;
use webpage_quality_analyzer::config::{ProfileBuilder, ProfileTemplates};
use webpage_quality_analyzer::metrics::ThresholdSet;

fn main() {
    println!("=== Phase 5: User Configuration Interface Demo ===\n");

    // Example 1: Basic ProfileBuilder usage
    example_basic_builder();

    // Example 2: Using content type presets
    example_content_type_presets();

    // Example 3: Custom metric weights
    example_custom_weights();

    // Example 4: Custom thresholds
    example_custom_thresholds();

    // Example 5: Using ProfileTemplates
    example_profile_templates();

    // Example 6: Advanced customization
    example_advanced_customization();

    // Example 7: Quality band customization
    example_quality_bands();
}

fn example_basic_builder() {
    println!("## Example 1: Basic ProfileBuilder Usage\n");

    let profile = ProfileBuilder::new("my_blog_profile")
        .with_description("A custom profile for my blog")
        .build()
        .expect("Failed to build profile");

    println!("Profile Name: {}", profile.metadata.name);
    println!("Description: {}", profile.metadata.description);
    println!("Category Weights:");
    for (category, weight) in &profile.category_weights {
        println!("  {}: {:.2}", category, weight);
    }
    println!();
}

fn example_content_type_presets() {
    println!("## Example 2: Using Content Type Presets\n");

    // Long-form article preset
    let article_profile = ProfileBuilder::new("tech_blog")
        .for_content_type(ContentType::LongFormArticle)
        .with_description("Profile for technical blog posts")
        .build()
        .expect("Failed to build article profile");

    println!("Long-Form Article Profile:");
    println!(
        "  Content weight: {:.2}",
        article_profile.category_weights.get("content").unwrap()
    );
    if let Some(wc) = &article_profile.content_expectations.word_count {
        println!(
            "  Optimal word count: {}-{} words",
            wc.optimal_range.0, wc.optimal_range.1
        );
    }
    println!();

    // News article preset
    let news_profile = ProfileBuilder::new("news_site")
        .for_content_type(ContentType::NewsArticle)
        .with_description("Profile for news articles")
        .build()
        .expect("Failed to build news profile");

    println!("News Article Profile:");
    println!(
        "  Content weight: {:.2}",
        news_profile.category_weights.get("content").unwrap()
    );
    println!(
        "  SEO weight: {:.2}",
        news_profile.category_weights.get("seo").unwrap()
    );
    if let Some(wc) = &news_profile.content_expectations.word_count {
        println!(
            "  Optimal word count: {}-{} words",
            wc.optimal_range.0, wc.optimal_range.1
        );
    }
    println!();

    // Product page preset
    let product_profile = ProfileBuilder::new("ecommerce")
        .for_content_type(ContentType::ProductPage)
        .with_description("Profile for product pages")
        .build()
        .expect("Failed to build product profile");

    println!("Product Page Profile:");
    println!(
        "  SEO weight: {:.2}",
        product_profile.category_weights.get("seo").unwrap()
    );
    println!(
        "  Technical weight: {:.2}",
        product_profile.category_weights.get("technical").unwrap()
    );
    println!();
}

fn example_custom_weights() {
    println!("## Example 3: Custom Metric Weights\n");

    let profile = ProfileBuilder::new("content_first")
        .for_content_type(ContentType::LongFormArticle)
        .with_description("Extremely content-focused profile")
        .with_metric_weight("word_count", 0.60)
        .expect("Failed to set word_count weight")
        .with_metric_weight("paragraph_count", 0.30)
        .expect("Failed to set paragraph_count weight")
        .with_metric_weight("title_len", 0.10)
        .expect("Failed to set title_len weight")
        .build()
        .expect("Failed to build profile");

    println!("Custom Metric Weights:");
    for (metric, override_cfg) in &profile.metric_overrides {
        println!("  {}: {:.2}", metric, override_cfg.weight);
    }
    println!();
}

fn example_custom_thresholds() {
    println!("## Example 4: Custom Thresholds\n");

    // Define custom thresholds for word count
    let word_count_thresholds = ThresholdSet {
        excellent: 3000.0, // Very long articles
        good: 2000.0,
        fair: 1000.0,
        poor: 500.0,
    };

    let profile = ProfileBuilder::new("long_form_strict")
        .for_content_type(ContentType::LongFormArticle)
        .with_description("Strict long-form article requirements")
        .with_custom_threshold("word_count", word_count_thresholds)
        .expect("Failed to set custom thresholds")
        .build()
        .expect("Failed to build profile");

    if let Some(override_cfg) = profile.metric_overrides.get("word_count") {
        if let Some(thresholds) = &override_cfg.thresholds {
            println!("Custom Word Count Thresholds:");
            println!("  Excellent: {} words", thresholds.excellent);
            println!("  Good: {} words", thresholds.good);
            println!("  Fair: {} words", thresholds.fair);
            println!("  Poor: {} words", thresholds.poor);
        }
    }
    println!();
}

fn example_profile_templates() {
    println!("## Example 5: Using ProfileTemplates\n");

    // List all available templates
    let templates = ProfileTemplates::list_templates();
    println!("Available Templates:");
    for template in &templates {
        println!("  - {}", template);
    }
    println!();

    // Get a specific template
    let template = ProfileTemplates::get_template("content_article")
        .expect("Failed to get content_article template");

    println!("Content Article Template:");
    println!("  Name: {}", template.metadata.name);
    println!("  Description: {}", template.metadata.description);
    println!("  Tags: {:?}", template.metadata.tags);
    println!(
        "  Content weight: {:.2}",
        template.category_weights.get("content").unwrap()
    );
    println!();
}

fn example_advanced_customization() {
    println!("## Example 6: Advanced Customization\n");

    let profile = ProfileBuilder::new("custom_seo_focused")
        .for_content_type(ContentType::NewsArticle)
        .with_description("SEO-optimized news profile with custom settings")
        .with_tags(vec![
            "seo".to_string(),
            "news".to_string(),
            "custom".to_string(),
        ])
        // Adjust category weights
        .with_category_weights({
            let mut weights = std::collections::HashMap::new();
            weights.insert("seo".to_string(), 0.50);
            weights.insert("content".to_string(), 0.30);
            weights.insert("technical".to_string(), 0.10);
            weights.insert("structure".to_string(), 0.05);
            weights.insert("accessibility".to_string(), 0.05);
            weights
        })
        // Custom metric weights
        .with_metric_weight("meta_desc_len", 0.40)
        .expect("Failed to set meta_desc_len weight")
        .with_metric_weight("title_len", 0.30)
        .expect("Failed to set title_len weight")
        // Enable/disable specific metrics
        .with_metric_enabled("word_count", true)
        .with_metric_enabled("paragraph_count", false)
        .build()
        .expect("Failed to build advanced profile");

    println!("Advanced Custom Profile:");
    println!("  Name: {}", profile.metadata.name);
    println!("  Tags: {:?}", profile.metadata.tags);
    println!("\nCategory Weights:");
    for (category, weight) in &profile.category_weights {
        println!("  {}: {:.2}", category, weight);
    }
    println!("\nMetric Overrides:");
    for (metric, override_cfg) in &profile.metric_overrides {
        println!(
            "  {}: weight={:.2}, enabled={}",
            metric, override_cfg.weight, override_cfg.enabled
        );
    }
    println!();
}

fn example_quality_bands() {
    println!("## Example 7: Quality Band Customization\n");

    // Define stricter quality bands
    let strict_bands = QualityBandConfig {
        excellent: 95.0,
        good: 85.0,
        fair: 70.0,
        poor: 50.0,
    };

    let profile = ProfileBuilder::new("strict_standards")
        .for_content_type(ContentType::LongFormArticle)
        .with_description("Profile with strict quality standards")
        .with_quality_bands(strict_bands)
        .build()
        .expect("Failed to build profile with custom bands");

    println!("Strict Quality Standards:");
    println!(
        "  Excellent threshold: {:.1}",
        profile.quality_bands.excellent
    );
    println!("  Good threshold: {:.1}", profile.quality_bands.good);
    println!("  Fair threshold: {:.1}", profile.quality_bands.fair);
    println!("  Poor threshold: {:.1}", profile.quality_bands.poor);
    println!();

    // Define lenient quality bands
    let lenient_bands = QualityBandConfig {
        excellent: 80.0,
        good: 60.0,
        fair: 40.0,
        poor: 20.0,
    };

    let lenient_profile = ProfileBuilder::new("lenient_standards")
        .with_description("Profile with lenient quality standards")
        .with_quality_bands(lenient_bands)
        .build()
        .expect("Failed to build lenient profile");

    println!("Lenient Quality Standards:");
    println!(
        "  Excellent threshold: {:.1}",
        lenient_profile.quality_bands.excellent
    );
    println!(
        "  Good threshold: {:.1}",
        lenient_profile.quality_bands.good
    );
    println!(
        "  Fair threshold: {:.1}",
        lenient_profile.quality_bands.fair
    );
    println!(
        "  Poor threshold: {:.1}",
        lenient_profile.quality_bands.poor
    );
    println!();
}