objets_metier_rs 1.0.2

Bibliothèque Rust moderne et sûre pour l'API COM Objets Métier Sage 100c - Production Ready
//! Trait pour la lecture d'entités depuis les factories
//!
//! Ce trait standardise les méthodes de lecture communes à toutes les factories :
//! - `list()` - Liste complète des entités
//! - `list_forward()` - Liste optimisée avec curseur forward-only
//! - `query_predicate()` - Requête avec prédicat personnalisé

use crate::errors::SageResult;

/// Trait pour les factories supportant la lecture d'entités
///
/// Ce trait fournit une interface commune pour récupérer des collections d'entités
/// depuis les factories Sage. Toutes les méthodes retournent des vecteurs d'entités
/// plutôt que des `ComInstance` bruts, pour une utilisation type-safe.
///
/// # Type Parameter
///
/// * `T` - Le type d'entité retourné par la factory
///
/// # Exemple
///
/// ```rust,ignore
/// use objets_metier_rs::wrappers::cpta::traits::FactoryRead;
///
/// fn compter_entites<F, T>(factory: &F) -> SageResult<usize>
/// where
///     F: FactoryRead<T>,
/// {
///     let items = factory.list()?;
///     Ok(items.len())
/// }
/// ```
pub trait FactoryRead<T> {
    /// Retourne la liste complète des entités
    ///
    /// Cette méthode récupère toutes les entités disponibles dans la factory.
    /// Pour les grandes collections, préférer `list_forward()` qui est plus performant.
    ///
    /// # Errors
    ///
    /// Retourne une erreur si :
    /// - La connexion COM échoue
    /// - L'accès aux données est refusé
    /// - Une erreur de conversion se produit
    ///
    /// # Exemple
    ///
    /// ```rust,ignore
    /// let journaux = factory_journal.list()?;
    /// println!("Nombre de journaux : {}", journaux.len());
    /// ```
    fn list(&self) -> SageResult<Vec<T>>;

    /// Retourne la liste optimisée des entités avec curseur forward-only
    ///
    /// Cette méthode utilise un curseur optimisé (forward-only) pour parcourir
    /// les entités. Elle est généralement plus rapide que `list()` car elle
    /// ne charge pas toute la collection en mémoire d'un coup.
    ///
    /// # Performance
    ///
    /// Préférer cette méthode pour les collections volumineuses (>1000 entités)
    ///
    /// # Errors
    ///
    /// Retourne une erreur si :
    /// - La connexion COM échoue
    /// - L'itération sur le curseur échoue
    ///
    /// # Exemple
    ///
    /// ```rust,ignore
    /// let comptes = factory_compte_g.list_forward()?;
    /// for compte in comptes {
    ///     println!("Compte : {}", compte.numero()?);
    /// }
    /// ```
    fn list_forward(&self) -> SageResult<Vec<T>>;

    /// Exécute une requête avec un prédicat personnalisé
    ///
    /// Cette méthode permet d'exécuter des requêtes filtrées sur les entités
    /// en utilisant la syntaxe de prédicats Sage (similaire à SQL WHERE).
    ///
    /// # Arguments
    ///
    /// * `predicate` - Expression de filtrage (ex: "JO_Num = 'BQ'")
    ///
    /// # Syntaxe des prédicats
    ///
    /// - Comparaisons : `=`, `<>`, `<`, `>`, `<=`, `>=`
    /// - Logique : `AND`, `OR`, `NOT`
    /// - Chaînes : délimitées par `'`
    /// - Nombres : sans délimiteurs
    ///
    /// # Errors
    ///
    /// Retourne une erreur si :
    /// - Le prédicat est invalide
    /// - La requête échoue
    ///
    /// # Exemple
    ///
    /// ```rust,ignore
    /// // Journaux de type 'ACH' (Achats)
    /// let journaux_achat = factory_journal.query_predicate("JO_Type = 3")?;
    ///
    /// // Comptes commençant par '6'
    /// let comptes_charges = factory_compte_g.query_predicate("CG_Num LIKE '6%'")?;
    /// ```
    fn query_predicate(&self, predicate: &str) -> SageResult<Vec<T>>;
}