fqdn 0.5.2

FQDN (Fully Qualified Domain Name)
Documentation
use fqdn::FQDN;
use serde::Deserialize;
use std::fs;
use std::fs::File;
use std::io::{BufReader, Write};

#[derive(Debug, Deserialize)]
struct DomainList {
    domains: Vec<FQDN>,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let test_file = "repro_domains.json";

    // Define different scenarios to test
    let test_cases = vec![
        (
            "Valid domains (mix of lengths)",
            r#"{
                "domains": [
                    "very-long-domain-name-example-that-exceeds-fifty-characters.com",
                    "short.com",
                    "a-label-that-is.com"
                ]
            }"#,
        ),
        (
            "Invalid domain: 51 characters long, starts with digit",
            r#"{
                "domains": [
                    "2athis-domain-is-exactly-fifty-one-characters-l.com"
                ]
            }"#,
        ),
        (
            "Valid domain: 50 characters long, starts with digit",
            r#"{
                "domains": [
                    "2athis-domain-is-exactly-fifty-one-characters-l.co"
                ]
            }"#,
        ),
        (
            "Valid domain: 52 characters long, starts with digit",
            r#"{
                "domains": [
                    "2athis-domain-is-exactly-fifty-one-characters-l.coms"
                ]
            }"#,
        ),
        (
            "Valid domain: 51 characters long, doesn't start with digit",
            r#"{
                "domains": [
                    "aathis-domain-is-exactly-fifty-one-characters-l.com"
                ]
            }"#,
        ),
    ];

    for (description, json_content) in test_cases {
        println!("\n--- Scenario: {} ---", description);

        // 1. Write the specific test case to the file
        let mut file = File::create(test_file)?;
        file.write_all(json_content.as_bytes())?;

        // 2. Open and parse directly into FQDN
        let file = File::open(test_file)?;
        let reader = BufReader::new(file);

        // This will trigger FQDN's FromStr via Serde's Deserialize impl
        match serde_json::from_reader::<_, DomainList>(reader) {
            Ok(data) => {
                println!("✅ Successfully parsed {} domains.", data.domains.len());
                for d in data.domains {
                    println!(" - {:?}", d);
                }
            }
            Err(e) => {
                // If any domain is invalid, it will fail here.
                eprintln!("❌ Deserialization failed!");
                eprintln!("Error: {}", e);
            }
        }
    }

    // Cleanup
    fs::remove_file(test_file)?;

    Ok(())
}