170 lines
4.5 KiB
Rust
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
|
|
}
|
|
}
|