objets_metier_rs 1.0.2

Bibliothèque Rust moderne et sûre pour l'API COM Objets Métier Sage 100c - Production Ready
// Exemple d'utilisation avancée des traits communs pour les factories
//
// Cet exemple démontre comment utiliser les traits génériques pour écrire
// du code réutilisable qui fonctionne avec n'importe quelle factory implémentant
// les traits appropriés.
//
// Pour exécuter cet exemple :
//     cargo run --example advanced_traits

use objets_metier_rs::errors::SageResult;
use objets_metier_rs::wrappers::cpta::traits::*;
use objets_metier_rs::wrappers::cpta::CptaApplication;

const BSCPTA_CLSID: &str = "309DE0FB-9FB8-4F4E-8295-CC60C60DAA33";

fn main() -> SageResult<()> {
    println!("🚀 Exemple d'utilisation des traits communs\n");
    println!("{}", "=".repeat(60));

    // Initialiser la connexion Sage (style C#)
    let app = CptaApplication::new(BSCPTA_CLSID)?;
    println!("✓ BSCPTAApplication100c créée");

    // Définir le chemin de la base
    app.set_name(r"D:\TMP\BIJOU.MAE")?;
    println!("✓ Base définie: D:\\TMP\\BIJOU.MAE");

    // Configurer les identifiants
    let loggable = app.loggable()?;
    loggable.set_user_name("<Administrateur>")?;
    loggable.set_user_pwd("")?;
    println!("✓ Identifiants configurés");

    // Ouvrir la connexion
    app.open()?;
    println!("✓ Connecté au dossier BIJOU\n");

    // Récupérer la factory des taxes
    let factory_taxe = app.factory_taxe()?;

    // =========================================================================
    // Exemple 1 : Utilisation du trait FactoryRead
    // =========================================================================
    println!("\n📋 Exemple 1 : Trait FactoryRead<T>");
    println!("{}", "-".repeat(60));

    afficher_toutes_avec_trait(&factory_taxe)?;

    // =========================================================================
    // Exemple 2 : Utilisation du trait FactoryReadByCode
    // =========================================================================
    println!("\n🔍 Exemple 2 : Trait FactoryReadByCode<T>");
    println!("{}", "-".repeat(60));

    lire_par_code_avec_trait(&factory_taxe, "C20")?;

    // =========================================================================
    // Exemple 3 : Utilisation du trait FactoryCreate
    // =========================================================================
    println!("\n➕ Exemple 3 : Trait FactoryCreate<T>");
    println!("{}", "-".repeat(60));

    // Note: Cette fonction créerait une entité mais ne la sauvegarde pas
    // pour éviter de modifier la base de données dans un exemple
    demontrer_creation_avec_trait(&factory_taxe)?;

    // =========================================================================
    // Exemple 4 : Utilisation du trait InfoLibreCapable
    // =========================================================================
    println!("\n📝 Exemple 4 : Trait InfoLibreCapable");
    println!("{}", "-".repeat(60));

    afficher_infos_libres(&factory_taxe)?;

    println!("\n{}", "=".repeat(60));
    println!("✅ Tous les exemples exécutés avec succès !");

    app.close()?;
    println!("✓ Connexion fermée");

    Ok(())
}

// =========================================================================
// Fonction générique utilisant le trait FactoryRead
// =========================================================================

/// Affiche toutes les entités d'une factory
///
/// Cette fonction générique fonctionne avec n'importe quelle factory
/// implémentant le trait FactoryRead<T>.
fn afficher_toutes_avec_trait<F, T>(factory: &F) -> SageResult<()>
where
    F: FactoryRead<T>,
{
    println!("Récupération de toutes les entités avec list()...");

    let entites = factory.list()?;
    println!("  ✓ Nombre d'entités trouvées : {}", entites.len());

    // Test de list_forward (curseur optimisé)
    println!("\nRécupération avec list_forward() (optimisé)...");
    let entites_forward = factory.list_forward()?;
    println!("  ✓ Nombre d'entités (forward) : {}", entites_forward.len());

    Ok(())
}

// =========================================================================
// Fonction générique utilisant le trait FactoryReadByCode
// =========================================================================

/// Lit une entité par son code
///
/// Cette fonction générique fonctionne avec n'importe quelle factory
/// implémentant le trait FactoryReadByCode<T>.
fn lire_par_code_avec_trait<F, T>(factory: &F, code: &str) -> SageResult<()>
where
    F: FactoryReadByCode<T>,
{
    println!("Vérification de l'existence du code '{}'...", code);

    if factory.exist_code(code)? {
        println!("  ✓ L'entité existe");

        println!("\nLecture de l'entité...");
        let _entite = factory.read_code(code)?;
        println!("  ✓ Entité lue avec succès");
    } else {
        println!("  ⚠ L'entité n'existe pas");
    }

    Ok(())
}

// =========================================================================
// Fonction générique utilisant le trait FactoryCreate
// =========================================================================

/// Démontre la création d'une entité (sans sauvegarde)
///
/// Cette fonction générique fonctionne avec n'importe quelle factory
/// implémentant le trait FactoryCreate<T>.
fn demontrer_creation_avec_trait<F, T>(factory: &F) -> SageResult<()>
where
    F: FactoryCreate<T>,
{
    println!("Création d'une nouvelle entité (non persistée)...");

    let _nouvelle_entite = factory.create()?;
    println!("  ✓ Entité créée avec succès");
    println!("  ℹ Note : L'entité n'est pas sauvegardée pour préserver la base");

    Ok(())
}

// =========================================================================
// Fonction utilisant le trait InfoLibreCapable
// =========================================================================

/// Affiche les informations sur les champs libres
///
/// Cette fonction fonctionne avec n'importe quelle factory
/// implémentant le trait InfoLibreCapable.
fn afficher_infos_libres<F>(factory: &F) -> SageResult<()>
where
    F: InfoLibreCapable,
{
    println!("Récupération de la collection d'informations libres...");

    match factory.info_libre_fields() {
        Ok(_fields) => {
            println!("  ✓ Collection d'infos libres récupérée");
            println!("  ℹ Les informations libres sont disponibles");
        }
        Err(e) => {
            println!("  ⚠ Pas d'informations libres configurées : {}", e);
        }
    }

    Ok(())
}

// =========================================================================
// Fonctions avancées : Composition de traits
// =========================================================================

/// Fonction combinant plusieurs traits
///
/// Cette fonction montre comment écrire du code générique qui nécessite
/// plusieurs traits en même temps.
#[allow(dead_code)]
fn operations_completes<F, T>(factory: &F, code: &str) -> SageResult<()>
where
    F: FactoryRead<T> + FactoryReadByCode<T> + FactoryCreate<T>,
{
    // Utilisation de FactoryRead
    let _toutes = factory.list()?;

    // Utilisation de FactoryReadByCode
    if factory.exist_code(code)? {
        let _entite = factory.read_code(code)?;
    }

    // Utilisation de FactoryCreate
    let _nouvelle = factory.create()?;

    Ok(())
}

// =========================================================================
// Exemple de fonction polymorphique avec Box<dyn Trait>
// =========================================================================

/// Traite n'importe quelle factory via un trait object
#[allow(dead_code)]
fn traiter_factory_generique<T>(factory: Box<dyn FactoryRead<T>>) -> SageResult<usize> {
    let entites = factory.list()?;
    Ok(entites.len())
}