# Plan: Suppression des duplications dans `@pmowebrenderer`

## Objectif
Éliminer les redondances de code identifiées lors de l'audit.

---

## Duplication 1: Helper functions dupliquées dans `renderer.rs`

**Fichiers affectés**: `src/renderer.rs`

**Problème**:
- Lignes 17-54: `add_arg_in`, `add_arg_out`, `add_var`, `add_action` définies
- Lignes 150-181: Dans `build_avtransport()`, réimplémentation locale avec closures `|svc, var| { ... }`
- Répétition de 20+ appels `add_var(&mut svc, &VAR)?` et `add_action(&mut svc, Arc::new(action))?`

**Solution**:
1. Supprimer les closures locales redéclarées (lignes 150-181)
2. Utiliser directement les fonctions helpers du haut du fichier
3. Créer une macro ou fonction utilitaire pour les appels répétés:
   ```rust
   macro_rules! add_vars {
       ($svc:expr, $($var:expr),*) => { $({ add_var($svc, &$var)?; })* };
   }
   ```

---

## Duplication 2: Pattern handlers boilerplate dans `handlers.rs`

**Fichiers affectés**: `src/handlers.rs`

**Problème**:
- `play_handler`, `stop_handler`, `pause_handler` (lignes 23-71): structure identique
- `next_handler`, `previous_handler` (lignes 74-95): clones
- Handlers GET (lignes 166-317): pattern `state.clone()` + `Box::pin(async move { ... set!() ... })` dupliqué

**Solution**:
1. Créer un helper générique:
   ```rust
   fn make_state_handler<F>(state: SharedState, f: F) -> ActionHandler
   where F: FnOnce(&mut ActionData, &RendererState) -> Result<ActionData, ActionError> + Send + 'static
   ```
2. Factoriser les closures `let state = state.clone()` dans chaque handler

---

## Duplication 3: Extraction metadata dupliquée

**Fichiers affectés**: `src/handlers.rs`

**Problème**:
- Lignes 118-123: `set_uri_handler` extraction metadata
- Lignes 146-151: `set_next_uri_handler` extraction metadata (identique)

**Solution**:
1. Extraire en fonction utilitaire:
   ```rust
   fn extract_metadata(data: &ActionData, key: &str) -> String { ... }
   ```

---

## Duplication 4: Méthodes pipeline dans `registry.rs`

**Fichiers affectés**: `src/registry.rs`

**Problème**:
- `send_pipeline_command` (lignes 272-279) appelle `get_pipeline` (lignes 281-283)
- `load_uri` (lignes 286-290), `send_play_command` (lignes 293-296), `send_pause_command` (lignes 299-301) sont des wrappers quasi-identiques

**Solution**:
Consolider en méthodes génériques:
```rust
pub async fn send_command(&self, instance_id: &str, cmd: PipelineControl) {
    if let Some(pipeline) = self.get_pipeline(instance_id) {
        pipeline.send(cmd).await;
    }
}
```

---

## Duplication 5: Feature flags avec code dupliqué

**Fichiers affectés**: `src/registry.rs`

**Problème**:
- Lignes 51-68 et 334-395: double impl de `create_instance` selon feature

**Solution**:
- Extraire la logique commune dans une fonction privée
- Utiliser `#[cfg]` seulement pour les différences (appel à pmoserver)

---

## Ordre de traitement suggéré

1. **Phase 1**: Helpers dans `renderer.rs` (les plus simples)
2. **Phase 2**: Handlers dans `handlers.rs` (plus complexe, nécessite macro)
3. **Phase 3**: Méthodes pipeline dans `registry.rs`
4. **Phase 4**: Feature flags

## Vérification
Après chaque phase, exécuter:
```bash
cargo check --package pmowebrenderer
```