Fin du debuggage

This commit is contained in:
2025-10-03 21:19:14 +02:00
parent 68faea2758
commit a4d618c09c
20 changed files with 116 additions and 139 deletions

View File

@@ -47,7 +47,7 @@ async fn main() {
server.add_redirect("/", "/app").await; server.add_redirect("/", "/app").await;
info!("{}",SETAVTRANSPORTURI.to_markdown().await); info!("{}",SETAVTRANSPORTURI.to_markdown());
server.start().await; server.start().await;
server.wait().await; server.wait().await;

View File

@@ -10,10 +10,10 @@ use crate::UpnpInstance;
use crate::UpnpObject; use crate::UpnpObject;
use crate::UpnpTyped; use crate::UpnpTyped;
use crate::UpnpTypedInstance; use crate::UpnpTypedInstance;
use crate::{UpnpTypedObject, UpnpObjectType}; use crate::UpnpObjectType;
impl UpnpObject for ActionInstance { impl UpnpObject for ActionInstance {
async fn to_xml_element(&self) -> Element { fn to_xml_element(&self) -> Element {
let mut elem = Element::new("action"); let mut elem = Element::new("action");
// <name> // <name>
@@ -22,7 +22,7 @@ async fn to_xml_element(&self) -> Element {
elem.children.push(XMLNode::Element(name_elem)); elem.children.push(XMLNode::Element(name_elem));
// déplacer tous les enfants de args_elem dans un nouvel Element // déplacer tous les enfants de args_elem dans un nouvel Element
let args_container = self.arguments_set().to_xml_element().await; let args_container = self.arguments_set().to_xml_element();
elem.children.push(XMLNode::Element(args_container)); elem.children.push(XMLNode::Element(args_container));
elem elem
@@ -62,8 +62,8 @@ impl UpnpTypedInstance for ActionInstance {
impl ActionInstance { impl ActionInstance {
pub async fn arguments(&self, name: &str) -> Option<Arc<Argument>> { pub fn arguments(&self, name: &str) -> Option<Arc<Argument>> {
self.model.arguments.get_by_name(name).await self.model.arguments.get_by_name(name)
} }
pub fn arguments_set(&self) -> &ArgumentSet { pub fn arguments_set(&self) -> &ArgumentSet {

View File

@@ -1,5 +1,5 @@
use crate::{ use crate::{
UpnpTypedObject, UpnpObject, UpnpObject,
actions::{ActionInstanceSet}, actions::{ActionInstanceSet},
}; };
@@ -7,11 +7,11 @@ use xmltree::{Element,XMLNode};
impl UpnpObject for ActionInstanceSet { impl UpnpObject for ActionInstanceSet {
// Méthode pour convertir en XML (à implémenter avec une librairie XML) // Méthode pour convertir en XML (à implémenter avec une librairie XML)
async fn to_xml_element(&self) -> Element { fn to_xml_element(&self) -> Element {
let mut elem = Element::new("actionList"); let mut elem = Element::new("actionList");
for action in self.all().await { for action in self.all() {
let action_elem = action.to_xml_element().await; // retourne un <action> complet let action_elem = action.to_xml_element(); // retourne un <action> complet
elem.children.push(XMLNode::Element(action_elem)); elem.children.push(XMLNode::Element(action_elem));
} }

View File

@@ -1,18 +1,19 @@
use std::sync::Arc; use std::sync::Arc;
use xmltree::{Element,XMLNode}; use xmltree::{Element, XMLNode};
use crate::actions::ActionInstance;
use crate::UpnpModel; use crate::UpnpModel;
use crate::UpnpObject; use crate::UpnpObject;
use crate::UpnpObjectSetError;
use crate::UpnpObjectType;
use crate::UpnpTyped;
use crate::actions::Action; use crate::actions::Action;
use crate::actions::ActionInstance;
use crate::actions::Argument; use crate::actions::Argument;
use crate::actions::ArgumentSet; use crate::actions::ArgumentSet;
use crate::UpnpTyped;
use crate::{UpnpTypedObject, UpnpObjectType};
impl UpnpObject for Action { impl UpnpObject for Action {
async fn to_xml_element(&self) -> Element { fn to_xml_element(&self) -> Element {
let mut action_elem = Element::new("action"); let mut action_elem = Element::new("action");
// <name> // <name>
@@ -23,7 +24,7 @@ impl UpnpObject for Action {
action_elem.children.push(XMLNode::Element(name_elem)); action_elem.children.push(XMLNode::Element(name_elem));
// <argumentList> // <argumentList>
let args_elem = self.arguments.to_xml_element().await; let args_elem = self.arguments.to_xml_element();
action_elem.children.push(XMLNode::Element(args_elem)); action_elem.children.push(XMLNode::Element(args_elem));
action_elem action_elem
@@ -31,11 +32,9 @@ impl UpnpObject for Action {
} }
impl UpnpModel for Action { impl UpnpModel for Action {
type Instance = ActionInstance; type Instance = ActionInstance;
} }
impl UpnpTyped for Action { impl UpnpTyped for Action {
fn as_upnp_object_type(&self) -> &UpnpObjectType { fn as_upnp_object_type(&self) -> &UpnpObjectType {
return &self.object; return &self.object;
@@ -53,8 +52,8 @@ impl Action {
} }
} }
pub fn add_argument(&mut self, arg: Arc<Argument>) { pub fn add_argument(&mut self, arg: Arc<Argument>) -> Result<(), UpnpObjectSetError> {
self.arguments.insert(arg); self.arguments.insert(arg)
} }
pub fn arguments(&self) -> &ArgumentSet { pub fn arguments(&self) -> &ArgumentSet {

View File

@@ -1,18 +1,14 @@
use std::collections::HashMap;
use xmltree::{Element, XMLNode}; use xmltree::{Element, XMLNode};
use crate::actions::Action;
use crate::actions::ActionSet; use crate::actions::ActionSet;
use crate::actions::errors::ActionError;
use crate::UpnpTypedObject;
use crate::UpnpObject; use crate::UpnpObject;
impl UpnpObject for ActionSet { impl UpnpObject for ActionSet {
async fn to_xml_element(&self) -> Element { fn to_xml_element(&self) -> Element {
let mut elem = Element::new("actionList"); let mut elem = Element::new("actionList");
for action in self.all().await { for action in self.all() {
let action_elem = action.to_xml_element().await; // retourne un <action> complet let action_elem = action.to_xml_element(); // retourne un <action> complet
elem.children.push(XMLNode::Element(action_elem)); elem.children.push(XMLNode::Element(action_elem));
} }

View File

@@ -1,18 +1,18 @@
use std::collections::HashMap; use std::collections::HashMap;
use tokio::sync::RwLock; use std::sync::RwLock;
use xmltree::{Element, XMLNode}; use xmltree::{Element, XMLNode};
use crate::{actions::{ArgInstanceSet, ArgumentSet}, state_variables::StateVariableSet, UpnpObject}; use crate::{actions::{ArgInstanceSet, ArgumentSet}, UpnpObject};
use crate::UpnpInstance; use crate::UpnpInstance;
impl UpnpObject for ArgInstanceSet { impl UpnpObject for ArgInstanceSet {
async fn to_xml_element(&self) -> Element { fn to_xml_element(&self) -> Element {
let mut elem = Element::new("serviceStateTable"); let mut elem = Element::new("serviceStateTable");
for state_var in self.all().await { for state_var in self.all() {
let state_var_elem = state_var.to_xml_element().await; // retourne un <stateVariable> complet let state_var_elem = state_var.to_xml_element(); // retourne un <stateVariable> complet
elem.children.push(XMLNode::Element(state_var_elem)); elem.children.push(XMLNode::Element(state_var_elem));
} }

View File

@@ -4,8 +4,8 @@ use crate::{actions::{Argument, ArgumentInstance}, UpnpInstance, UpnpObject, Upn
impl UpnpObject for ArgumentInstance { impl UpnpObject for ArgumentInstance {
async fn to_xml_element(&self) -> Element { fn to_xml_element(&self) -> Element {
self.get_model().to_xml_element().await self.get_model().to_xml_element()
} }
} }

View File

@@ -1,11 +1,9 @@
use crate::actions::ArgInstanceSet; use crate::actions::ArgInstanceSet;
use crate::{UpnpModel, UpnpTypedObject}; use crate::UpnpModel;
use crate::{ use crate::{
UpnpObject, UpnpObject,
actions::{ArgumentSet}, actions::{ArgumentSet},
}; };
use std::collections::HashMap;
use std::sync::RwLock;
use xmltree::Element; use xmltree::Element;
impl UpnpObject for ArgumentSet { impl UpnpObject for ArgumentSet {

View File

@@ -3,7 +3,7 @@ use std::sync::Arc;
use xmltree::{Element, XMLNode}; use xmltree::{Element, XMLNode};
use crate::{ use crate::{
actions::{Argument, ArgumentInstance}, state_variables::StateVariable, UpnpInstance, UpnpModel, UpnpObject, UpnpObjectType, UpnpTyped, UpnpTypedObject actions::{Argument, ArgumentInstance}, state_variables::StateVariable, UpnpModel, UpnpObject, UpnpObjectType, UpnpTyped
}; };
impl UpnpTyped for Argument { impl UpnpTyped for Argument {
@@ -13,7 +13,7 @@ impl UpnpTyped for Argument {
} }
impl UpnpObject for Argument { impl UpnpObject for Argument {
async fn to_xml_element(&self) -> Element { fn to_xml_element(&self) -> Element {
let mut parent = Element::new("argumentList"); let mut parent = Element::new("argumentList");
if self.is_in() && self.is_out() { if self.is_in() && self.is_out() {

View File

@@ -12,7 +12,7 @@ pub mod variable_types;
use std::{collections::HashMap, sync::Arc}; use std::{collections::HashMap, sync::Arc};
use tokio::sync::RwLock; use std::sync::RwLock;
pub use crate::object_trait::*; pub use crate::object_trait::*;

View File

@@ -1,6 +1,6 @@
use std::{collections::HashMap, sync::Arc}; use std::{collections::HashMap, sync::Arc};
use tokio::sync::RwLock; use std::sync::RwLock;
use crate::{UpnpDeepClone, UpnpObjectSet, UpnpObjectSetError, UpnpTypedObject}; use crate::{UpnpDeepClone, UpnpObjectSet, UpnpObjectSetError, UpnpTypedObject};
@@ -11,7 +11,7 @@ use crate::{UpnpDeepClone, UpnpObjectSet, UpnpObjectSetError, UpnpTypedObject};
/// Les modifications sur l'un des sets n'affectent pas l'autre. /// Les modifications sur l'un des sets n'affectent pas l'autre.
impl<T: UpnpTypedObject> UpnpDeepClone for UpnpObjectSet<T> { impl<T: UpnpTypedObject> UpnpDeepClone for UpnpObjectSet<T> {
fn deep_clone(&self) -> Self { fn deep_clone(&self) -> Self {
let guard = self.objects.blocking_read(); let guard = self.objects.read().unwrap();
let cloned_map: HashMap<String, Arc<T>> = guard let cloned_map: HashMap<String, Arc<T>> = guard
.iter() .iter()
@@ -38,7 +38,7 @@ impl<T: UpnpTypedObject> UpnpDeepClone for UpnpObjectSet<T> {
/// seront visibles depuis les deux sets. /// seront visibles depuis les deux sets.
impl<T: UpnpTypedObject> Clone for UpnpObjectSet<T> { impl<T: UpnpTypedObject> Clone for UpnpObjectSet<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
let guard = self.objects.blocking_read(); let guard = self.objects.read().unwrap();
Self { Self {
objects: RwLock::new(guard.clone()), objects: RwLock::new(guard.clone()),
@@ -47,14 +47,19 @@ impl<T: UpnpTypedObject> Clone for UpnpObjectSet<T> {
} }
impl<T: UpnpTypedObject> UpnpObjectSet<T> { impl<T: UpnpTypedObject> UpnpObjectSet<T> {
/// Crée un nouveau `UpnpObjectSet` vide.
///
/// # Examples
///
/// ```
/// let set: UpnpObjectSet<MyObject> = UpnpObjectSet::new();
/// ```
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
objects: RwLock::new(HashMap::new()), objects: RwLock::new(HashMap::new()),
} }
} }
/// Insère un objet dans le set. /// Insère un objet dans le set.
/// ///
/// # Arguments /// # Arguments
@@ -71,10 +76,10 @@ impl<T: UpnpTypedObject> UpnpObjectSet<T> {
/// ``` /// ```
/// let mut set = UpnpObjectSet::new(); /// let mut set = UpnpObjectSet::new();
/// let obj = Arc::new(MyObject::new("test")); /// let obj = Arc::new(MyObject::new("test"));
/// set.insert(obj).await?; /// set.insert(obj)?;
/// ``` /// ```
pub async fn insert(&mut self, object: Arc<T>) -> Result<(), UpnpObjectSetError> { pub fn insert(&mut self, object: Arc<T>) -> Result<(), UpnpObjectSetError> {
let mut guard = self.objects.write().await; let mut guard = self.objects.write().unwrap();
let key = object.get_name().to_string(); let key = object.get_name().to_string();
if guard.contains_key(&key) { if guard.contains_key(&key) {
@@ -100,11 +105,11 @@ impl<T: UpnpTypedObject> UpnpObjectSet<T> {
/// let obj1 = Arc::new(MyObject::new("test")); /// let obj1 = Arc::new(MyObject::new("test"));
/// let obj2 = Arc::new(MyObject::new("test")); // Même nom /// let obj2 = Arc::new(MyObject::new("test")); // Même nom
/// ///
/// set.insert_or_replace(obj1).await; /// set.insert_or_replace(obj1);
/// set.insert_or_replace(obj2).await; // Remplace obj1 /// set.insert_or_replace(obj2); // Remplace obj1
/// ``` /// ```
pub async fn insert_or_replace(&mut self, object: Arc<T>) { pub fn insert_or_replace(&mut self, object: Arc<T>) {
let mut guard = self.objects.write().await; let mut guard = self.objects.write().unwrap();
let key: String = object.get_name().to_string(); let key: String = object.get_name().to_string();
guard.insert(key, object); guard.insert(key, object);
@@ -128,18 +133,18 @@ impl<T: UpnpTypedObject> UpnpObjectSet<T> {
/// let set = UpnpObjectSet::new(); /// let set = UpnpObjectSet::new();
/// let obj = Arc::new(MyObject::new("test")); /// let obj = Arc::new(MyObject::new("test"));
/// ///
/// if set.contains(obj.clone()).await { /// if set.contains(obj.clone()) {
/// println!("L'objet existe déjà"); /// println!("L'objet existe déjà");
/// } /// }
/// ``` /// ```
pub async fn contains(&self, object: Arc<T>) -> bool { pub fn contains(&self, object: Arc<T>) -> bool {
let guard = self.objects.read().await; let guard = self.objects.read().unwrap();
let key: String = object.get_name().to_string(); let key: String = object.get_name().to_string();
guard.contains_key(&key) guard.contains_key(&key)
} }
/// Récupère un objet par son nom (version asynchrone). /// Récupère un objet par son nom.
/// ///
/// # Arguments /// # Arguments
/// ///
@@ -155,16 +160,16 @@ impl<T: UpnpTypedObject> UpnpObjectSet<T> {
/// ``` /// ```
/// let set = UpnpObjectSet::new(); /// let set = UpnpObjectSet::new();
/// ///
/// if let Some(obj) = set.get_by_name("test").await { /// if let Some(obj) = set.get_by_name("test") {
/// println!("Objet trouvé: {}", obj.get_name()); /// println!("Objet trouvé: {}", obj.get_name());
/// } /// }
/// ``` /// ```
pub async fn get_by_name(&self, name: &str) -> Option<Arc<T>> { pub fn get_by_name(&self, name: &str) -> Option<Arc<T>> {
let guard = self.objects.read().await; let guard = self.objects.read().unwrap();
guard.get(name).cloned() guard.get(name).cloned()
} }
/// Retourne tous les objets du set (version asynchrone). /// Retourne tous les objets du set.
/// ///
/// # Returns /// # Returns
/// ///
@@ -176,43 +181,17 @@ impl<T: UpnpTypedObject> UpnpObjectSet<T> {
/// ``` /// ```
/// let set = UpnpObjectSet::new(); /// let set = UpnpObjectSet::new();
/// ///
/// for obj in set.all().await { /// for obj in set.all() {
/// println!("Objet: {}", obj.get_name());
/// }
/// ```
pub async fn all(&self) -> Vec<Arc<T>> {
let guard = self.objects.read().await;
guard.values().cloned().collect()
}
/// Retourne tous les objets du set (version synchrone bloquante).
///
/// Cette méthode bloque le thread appelant jusqu'à ce que le verrou de lecture
/// soit obtenu. Utilisez cette version uniquement dans du code synchrone.
/// Pour du code asynchrone, préférez [`all()`](Self::all).
///
/// # Returns
///
/// Un vecteur contenant des clones des `Arc` pointant vers tous les objets du set.
/// L'ordre des éléments n'est pas garanti.
///
/// # Examples
///
/// ```
/// let set = UpnpObjectSet::new();
///
/// // Dans un contexte synchrone
/// for obj in set.get_all() {
/// println!("Objet: {}", obj.get_name()); /// println!("Objet: {}", obj.get_name());
/// } /// }
/// ``` /// ```
/// ///
/// # Avertissement /// # Thread-safety
/// ///
/// N'appelez pas cette méthode depuis un contexte asynchrone car elle peut /// Cette méthode acquiert un verrou de lecture. Plusieurs threads peuvent
/// bloquer l'executor Tokio. Utilisez [`all()`](Self::all) à la place. /// appeler cette méthode simultanément sans blocage.
pub fn get_all(&self) -> Vec<Arc<T>> { pub fn all(&self) -> Vec<Arc<T>> {
let guard = self.objects.blocking_read(); let guard = self.objects.read().unwrap();
guard.values().cloned().collect() guard.values().cloned().collect()
} }
} }

View File

@@ -79,7 +79,7 @@ pub trait UpnpObject: Clone + Debug {
/// # Returns /// # Returns
/// ///
/// Un [`Element`] xmltree représentant l'objet. /// Un [`Element`] xmltree représentant l'objet.
async fn to_xml_element(&self) -> Element; fn to_xml_element(&self) -> Element;
/// Convertit l'objet en chaîne XML formatée. /// Convertit l'objet en chaîne XML formatée.
/// ///
@@ -101,8 +101,8 @@ pub trait UpnpObject: Clone + Debug {
/// // <child>value</child> /// // <child>value</child>
/// // </element> /// // </element>
/// ``` /// ```
async fn to_xml(&self) -> String { fn to_xml(&self) -> String {
let elem = self.to_xml_element().await; let elem = self.to_xml_element();
let config = EmitterConfig::new() let config = EmitterConfig::new()
.perform_indent(true) .perform_indent(true)
@@ -144,8 +144,8 @@ pub trait UpnpObject: Clone + Debug {
/// // - **element** /// // - **element**
/// // - **child**: `value` /// // - **child**: `value`
/// ``` /// ```
async fn to_markdown(&self) -> String { fn to_markdown(&self) -> String {
let elem = self.to_xml_element().await; let elem = self.to_xml_element();
let mut md = String::new(); let mut md = String::new();
fn is_url(s: &str) -> bool { fn is_url(s: &str) -> bool {

View File

@@ -9,7 +9,7 @@ use axum::{
http::{StatusCode, HeaderMap}, http::{StatusCode, HeaderMap},
body::Body, body::Body,
}; };
use tokio::sync::RwLock; use std::sync::RwLock;
use tokio::time; use tokio::time;
use tracing::{info, warn, debug, error}; use tracing::{info, warn, debug, error};

View File

@@ -1,11 +1,14 @@
use std::fmt; use std::fmt;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use tokio::sync::RwLock; use std::sync::RwLock;
use xmltree::Element; use xmltree::Element;
use crate::{ use crate::{
object_trait::{UpnpInstance, UpnpObject}, state_variables::{StateVarInstance, StateVariable, UpnpVariable}, variable_types::{StateValue, StateValueError, UpnpVarType}, UpnpObjectType, UpnpTyped, UpnpTypedInstance, UpnpTypedObject object_trait::{UpnpInstance, UpnpObject},
state_variables::{StateVarInstance, StateVariable, UpnpVariable},
variable_types::{StateValue, StateValueError, UpnpVarType},
UpnpObjectType, UpnpTyped, UpnpTypedInstance
}; };
impl UpnpVariable for StateVarInstance { impl UpnpVariable for StateVarInstance {
@@ -15,8 +18,8 @@ impl UpnpVariable for StateVarInstance {
} }
impl UpnpObject for StateVarInstance { impl UpnpObject for StateVarInstance {
async fn to_xml_element(&self) -> Element { fn to_xml_element(&self) -> Element {
self.get_definition().to_xml_element().await self.get_definition().to_xml_element()
} }
} }
@@ -76,10 +79,10 @@ impl Clone for StateVarInstance {
Self { Self {
object: self.object.clone(), object: self.object.clone(),
model: self.model.clone(), model: self.model.clone(),
value: RwLock::new(self.value.blocking_read().clone()), value: RwLock::new(self.value.read().unwrap().clone()),
old_value: RwLock::new(self.old_value.blocking_read().clone()), old_value: RwLock::new(self.old_value.read().unwrap().clone()),
last_modified: RwLock::new(self.last_modified.blocking_read().clone()), last_modified: RwLock::new(self.last_modified.read().unwrap().clone()),
last_notification: RwLock::new(self.last_notification.blocking_read().clone()), last_notification: RwLock::new(self.last_notification.read().unwrap().clone()),
} }
} }
} }
@@ -94,9 +97,9 @@ impl StateVarInstance {
} }
// Mise à jour avec les locks // Mise à jour avec les locks
let mut old_val = self.old_value.write().await; let mut old_val = self.old_value.write().unwrap();
let mut val = self.value.write().await; let mut val = self.value.write().unwrap();
let mut modified = self.last_modified.write().await; let mut modified = self.last_modified.write().unwrap();
*old_val = val.clone(); *old_val = val.clone();
*val = new_value; *val = new_value;
@@ -106,11 +109,11 @@ impl StateVarInstance {
} }
/// Accès à la valeur /// Accès à la valeur
pub fn value(&self) -> StateValue { pub fn value(&self) -> StateValue {
self.value.blocking_read().clone() self.value.read().unwrap().clone()
} }
/// Accès au timestamp /// Accès au timestamp
pub fn last_modified(&self) -> DateTime<Utc> { pub fn last_modified(&self) -> DateTime<Utc> {
self.last_modified.blocking_read().clone() self.last_modified.read().unwrap().clone()
} }
} }

View File

@@ -14,10 +14,12 @@ pub use crate::state_variables::variable_trait::UpnpVariable;
use bevy_reflect::Reflect; use bevy_reflect::Reflect;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
pub use errors::StateVariableError; pub use errors::StateVariableError;
use tokio::sync::RwLock; use std::sync::RwLock;
use crate::{ use crate::{
value_ranges::ValueRange, variable_types::{StateValue, StateVarType}, UpnpObjectSet, UpnpObjectType, UpnpSet value_ranges::ValueRange,
variable_types::{StateValue, StateVarType},
UpnpObjectSet, UpnpObjectType,
}; };
/// Type pour les fonctions de condition d'événement /// Type pour les fonctions de condition d'événement

View File

@@ -1,18 +1,18 @@
use std::collections::HashMap; use std::collections::HashMap;
use tokio::sync::RwLock; use std::sync::RwLock;
use xmltree::{Element, XMLNode}; use xmltree::{Element, XMLNode};
use crate::{state_variables::{StateVarInstance, StateVarInstanceSet, StateVariableSet}, UpnInstanceSet, UpnpObject, UpnpTyped}; use crate::{state_variables::{StateVarInstanceSet, StateVariableSet}, UpnpObject};
use crate::UpnpInstance; use crate::UpnpInstance;
impl UpnpObject for StateVarInstanceSet { impl UpnpObject for StateVarInstanceSet {
async fn to_xml_element(&self) -> Element { fn to_xml_element(&self) -> Element {
let mut elem = Element::new("serviceStateTable"); let mut elem = Element::new("serviceStateTable");
for state_var in self.all().await { for state_var in self.all() {
let state_var_elem = state_var.to_xml_element().await; // retourne un <stateVariable> complet let state_var_elem = state_var.to_xml_element(); // retourne un <stateVariable> complet
elem.children.push(XMLNode::Element(state_var_elem)); elem.children.push(XMLNode::Element(state_var_elem));
} }

View File

@@ -1,15 +1,15 @@
use xmltree::{Element, XMLNode}; use xmltree::{Element, XMLNode};
use crate::{object_trait::UpnpModel, state_variables::{StateVarInstanceSet, StateVariableSet}, UpnInstanceSet, UpnpObject}; use crate::{object_trait::UpnpModel, state_variables::{StateVarInstanceSet, StateVariableSet}, UpnpObject};
impl UpnpObject for StateVariableSet { impl UpnpObject for StateVariableSet {
async fn to_xml_element(&self) -> Element { fn to_xml_element(&self) -> Element {
let mut elem = Element::new("serviceStateTable"); let mut elem = Element::new("serviceStateTable");
for state_var in self.get_all() { for state_var in self.all() {
let state_var_elem = state_var.to_xml_element().await; // retourne un <stateVariable> complet let state_var_elem = state_var.to_xml_element(); // retourne un <stateVariable> complet
elem.children.push(XMLNode::Element(state_var_elem)); elem.children.push(XMLNode::Element(state_var_elem));
} }

View File

@@ -4,7 +4,7 @@ use std::{
sync::Arc, sync::Arc,
}; };
use tokio::sync::RwLock; use std::sync::RwLock;
use xmltree::{Element, XMLNode}; use xmltree::{Element, XMLNode};
use crate::{ use crate::{
@@ -31,7 +31,7 @@ impl UpnpVarType for StateVariable {
} }
impl UpnpObject for StateVariable { impl UpnpObject for StateVariable {
async fn to_xml_element(&self) -> Element { fn to_xml_element(&self) -> Element {
// Création de l'élément racine <stateVariable> // Création de l'élément racine <stateVariable>
let mut root = Element::new("stateVariable"); let mut root = Element::new("stateVariable");
root.attributes.insert( root.attributes.insert(
@@ -59,7 +59,7 @@ impl UpnpObject for StateVariable {
} }
// <allowedValueList> si défini // <allowedValueList> si défini
let av = self.allowed_values.read().await; let av = self.allowed_values.read().unwrap();
if !av.is_empty() { if !av.is_empty() {
let mut list_elem = Element::new("allowedValueList"); let mut list_elem = Element::new("allowedValueList");
for val in av.iter() { for val in av.iter() {
@@ -114,7 +114,7 @@ impl Clone for StateVariable {
// si le lock est "poisoned" on panic - tu peux adapter la gestion si tu veux // si le lock est "poisoned" on panic - tu peux adapter la gestion si tu veux
let guard = self let guard = self
.event_conditions .event_conditions
.blocking_read(); .read().unwrap();
// nécessite que Key: Clone, Value: Clone // nécessite que Key: Clone, Value: Clone
Arc::new(RwLock::new(guard.clone())) Arc::new(RwLock::new(guard.clone()))
}; };
@@ -122,7 +122,7 @@ impl Clone for StateVariable {
let allowed_values_clone = { let allowed_values_clone = {
let guard = self let guard = self
.allowed_values .allowed_values
.blocking_read(); .read().unwrap();
Arc::new(RwLock::new(guard.clone())) Arc::new(RwLock::new(guard.clone()))
}; };
@@ -156,7 +156,7 @@ impl fmt::Debug for StateVariable {
"event_conditions", "event_conditions",
&format_args!( &format_args!(
"len={}", "len={}",
self.event_conditions.blocking_read().len() self.event_conditions.read().unwrap().len()
), ),
) )
.field("description", &self.description) .field("description", &self.description)
@@ -166,7 +166,7 @@ impl fmt::Debug for StateVariable {
"allowed_values", "allowed_values",
&format_args!( &format_args!(
"len={}", "len={}",
self.allowed_values.blocking_read().len() self.allowed_values.read().unwrap().len()
), ),
) )
.field("send_events", &self.send_events) .field("send_events", &self.send_events)
@@ -298,18 +298,18 @@ impl StateVariable {
pub fn add_event_condition(&self, name: String, func: StateConditionFunc) { pub fn add_event_condition(&self, name: String, func: StateConditionFunc) {
// on lock en écriture // on lock en écriture
let mut guard = self.event_conditions.blocking_write(); let mut guard = self.event_conditions.write().unwrap();
guard.insert(name, func); guard.insert(name, func);
// le lock est automatiquement relâché ici (RAII) // le lock est automatiquement relâché ici (RAII)
} }
pub fn remove_event_condition(&self, name: &str) { pub fn remove_event_condition(&self, name: &str) {
let mut guard = self.event_conditions.blocking_write(); let mut guard = self.event_conditions.write().unwrap();
guard.remove(name); guard.remove(name);
} }
pub fn clear_event_conditions(&mut self) { pub fn clear_event_conditions(&mut self) {
let mut guard = self.event_conditions.blocking_write(); let mut guard = self.event_conditions.write().unwrap();
guard.clear() guard.clear()
} }
@@ -334,7 +334,7 @@ impl StateVariable {
pub fn extend_allowed_values(&mut self, values: &[StateValue]) -> Result<(), StateValueError> { pub fn extend_allowed_values(&mut self, values: &[StateValue]) -> Result<(), StateValueError> {
let mut av = self let mut av = self
.allowed_values .allowed_values
.blocking_write(); .write().unwrap();
for v in values { for v in values {
if self.as_state_var_type() == v.as_state_var_type() { if self.as_state_var_type() == v.as_state_var_type() {
@@ -352,7 +352,7 @@ impl StateVariable {
pub fn push_allowed_value(&mut self, value: &StateValue) -> Result<(), StateValueError> { pub fn push_allowed_value(&mut self, value: &StateValue) -> Result<(), StateValueError> {
let mut av = self let mut av = self
.allowed_values .allowed_values
.blocking_write(); .write().unwrap();
if self.as_state_var_type() == value.as_state_var_type() { if self.as_state_var_type() == value.as_state_var_type() {
av.push(value.clone()); av.push(value.clone());

View File

@@ -124,7 +124,7 @@ pub trait UpnpVariable {
/// ///
/// Retourne `false` si le lock est empoisonné (poisoned). /// Retourne `false` si le lock est empoisonné (poisoned).
fn has_event_conditions(&self) -> bool { fn has_event_conditions(&self) -> bool {
let guard = self.get_definition().event_conditions.blocking_read(); let guard = self.get_definition().event_conditions.read().unwrap();
!guard.is_empty() !guard.is_empty()
} }
@@ -142,7 +142,7 @@ pub trait UpnpVariable {
/// ///
/// Retourne `false` si le lock est empoisonné (poisoned). /// Retourne `false` si le lock est empoisonné (poisoned).
fn has_event_condition(&self, name: &String) -> bool { fn has_event_condition(&self, name: &String) -> bool {
let guard = self.get_definition().event_conditions.blocking_read(); let guard = self.get_definition().event_conditions.read().unwrap();
guard.contains_key(name) guard.contains_key(name)
} }
@@ -218,7 +218,7 @@ pub trait UpnpVariable {
fn has_allowed_values(&self) -> bool { fn has_allowed_values(&self) -> bool {
let guard = self.get_definition() let guard = self.get_definition()
.allowed_values .allowed_values
.blocking_read(); .read().unwrap();
!guard.is_empty() !guard.is_empty()
} }
@@ -252,7 +252,7 @@ pub trait UpnpVariable {
fn is_an_allowed_value(&self, value: &StateValue) -> bool { fn is_an_allowed_value(&self, value: &StateValue) -> bool {
let guard = self.get_definition() let guard = self.get_definition()
.allowed_values .allowed_values
.blocking_read(); .read().unwrap();
guard.contains(value) guard.contains(value)
} }

View File

@@ -76,7 +76,7 @@ pub fn guess_local_ip() -> String {
/// - Seules les adresses IPv4 sont retournées /// - Seules les adresses IPv4 sont retournées
/// - Les adresses de loopback (127.x.x.x) sont filtrées /// - Les adresses de loopback (127.x.x.x) sont filtrées
/// - Les adresses IPv6 sont ignorées /// - Les adresses IPv6 sont ignorées
fn list_all_ips() -> std::collections::HashMap<String, Vec<String>> { pub fn list_all_ips() -> std::collections::HashMap<String, Vec<String>> {
let mut result = std::collections::HashMap::new(); let mut result = std::collections::HashMap::new();
if let Ok(interfaces) = get_if_addrs() { if let Ok(interfaces) = get_if_addrs() {