Files
pmomusic/pmoupnp/src/actions/action_methods.rs
2025-10-09 22:38:02 +02:00

170 lines
4.5 KiB
Rust

use std::collections::HashMap;
use std::sync::Arc;
use tracing::{debug, trace};
use xmltree::{Element, XMLNode};
use crate::{
action_handler,
UpnpModel,
UpnpObject,
UpnpObjectSetError,
UpnpObjectType,
UpnpTyped,
UpnpTypedInstance,
};
use crate::actions::{
Action,
ActionData,
ActionHandler,
ActionInstance,
Argument,
ArgumentSet,
};
impl UpnpObject for Action {
fn to_xml_element(&self) -> Element {
let mut action_elem = Element::new("action");
// <name>
let mut name_elem = Element::new("name");
name_elem
.children
.push(XMLNode::Text(self.get_name().clone()));
action_elem.children.push(XMLNode::Element(name_elem));
// <argumentList>
let args_elem = self.arguments.to_xml_element();
action_elem.children.push(XMLNode::Element(args_elem));
action_elem
}
}
impl UpnpModel for Action {
type Instance = ActionInstance;
}
impl UpnpTyped for Action {
fn as_upnp_object_type(&self) -> &UpnpObjectType {
return &self.object;
}
}
impl Action {
/// Crée un handler par défaut pour une action.
///
/// Ce handler logge simplement l'appel et les arguments d'entrée.
/// La méthode [`ActionInstance::run()`](crate::actions::ActionInstance::run) s'occupe
/// automatiquement de collecter les valeurs OUT après l'exécution.
///
/// # Returns
///
/// Un [`ActionHandler`] qui logge les entrées.
///
/// # Comportement
///
/// - Logge le nom de l'action
/// - Logge les arguments IN avec leurs valeurs
/// - Ne fait aucune modification (handler passif)
///
/// # Note
///
/// Ce handler est automatiquement assigné lors de la création d'une action.
/// Il peut être remplacé via [`set_handler`](Self::set_handler).
fn default_handler() -> ActionHandler {
action_handler!(|instance, data| {
use crate::UpnpTypedInstance;
debug!("🎬 Action '{}' called", instance.get_name());
// Logger les arguments d'entrée
for arg_inst in instance.arguments_set().all() {
let arg_model = arg_inst.as_ref().get_model();
if arg_model.is_in() {
if let Some(value) = data.get(arg_inst.get_name()) {
trace!(" IN {} = {:?}", arg_inst.get_name(), value);
}
}
}
Ok(()) // Succès - handler par défaut ne fait rien d'autre
})
}
/// Crée une nouvelle action UPnP.
///
/// L'action est initialisée avec un handler par défaut qui logge les entrées
/// et retourne les valeurs des variables d'instance pour les arguments de sortie.
///
/// # Arguments
///
/// * `name` - Nom de l'action
///
/// # Examples
///
/// ```rust
/// # use pmoupnp::actions::Action;
/// let mut action = Action::new("Play".to_string());
/// ```
pub fn new(name: String) -> Action {
Self {
object: UpnpObjectType {
name,
object_type: "Action".to_string(),
},
arguments: ArgumentSet::new(),
handle: Self::default_handler(),
}
}
/// Ajoute un argument à l'action.
///
/// # Arguments
///
/// * `arg` - Argument à ajouter
///
/// # Errors
///
/// Retourne une erreur si un argument avec le même nom existe déjà.
pub fn add_argument(&mut self, arg: Arc<Argument>) -> Result<(), UpnpObjectSetError> {
self.arguments.insert(arg)
}
/// Retourne les arguments de l'action.
pub fn arguments(&self) -> &ArgumentSet {
&self.arguments
}
/// Définit un handler personnalisé pour cette action.
///
/// Remplace le handler par défaut par un handler personnalisé.
///
/// # Arguments
///
/// * `handler` - Le nouveau handler à utiliser
///
/// # Examples
///
/// ```rust,no_run
/// # use pmoupnp::actions::Action;
/// # use pmoupnp::action_handler;
/// let mut action = Action::new("Play".to_string());
///
/// let custom_handler = action_handler!(|instance, data| {
/// // Logique personnalisée
/// data
/// });
///
/// action.set_handler(custom_handler);
/// ```
pub fn set_handler(&mut self, handler: ActionHandler) {
self.handle = handler;
}
/// Retourne le handler de l'action.
pub fn handler(&self) -> &ActionHandler {
&self.handle
}
}