On continue l'implementation de pmoupnp
This commit is contained in:
72
pmoupnp/errors.rs
Normal file
72
pmoupnp/errors.rs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum StateVariableError {
|
||||||
|
#[error("Conversion error: {0}")]
|
||||||
|
ConversionError(String),
|
||||||
|
|
||||||
|
#[error("Validation error: {0}")]
|
||||||
|
ValidationError(String),
|
||||||
|
|
||||||
|
#[error("Range error: {0}")]
|
||||||
|
RangeError(String),
|
||||||
|
|
||||||
|
#[error("Type error: {0}")]
|
||||||
|
TypeError(String),
|
||||||
|
|
||||||
|
#[error("Parse error: {0}")]
|
||||||
|
ParseError(String),
|
||||||
|
|
||||||
|
#[error("Event condition error: {0}")]
|
||||||
|
EventConditionError(String),
|
||||||
|
|
||||||
|
#[error("Arithmetic error: {0}")]
|
||||||
|
ArithmeticError(String),
|
||||||
|
|
||||||
|
#[error("Unknown error: {0}")]
|
||||||
|
Unknown(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::num::TryFromIntError> for StateVariableError {
|
||||||
|
fn from(err: std::num::TryFromIntError) -> Self {
|
||||||
|
StateVariableError::ConversionError(format!("Integer conversion error: {}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::str::ParseBoolError> for StateVariableError {
|
||||||
|
fn from(err: std::str::ParseBoolError) -> Self {
|
||||||
|
StateVariableError::ConversionError(format!("Boolean conversion error: {}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<uuid::Error> for StateVariableError {
|
||||||
|
fn from(err: uuid::Error) -> Self {
|
||||||
|
StateVariableError::ConversionError(format!("UUID conversion error: {}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<chrono::ParseError> for StateVariableError {
|
||||||
|
fn from(err: chrono::ParseError) -> Self {
|
||||||
|
StateVariableError::ConversionError(format!("Time conversion error: {}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<url::ParseError> for StateVariableError {
|
||||||
|
fn from(err: url::ParseError) -> Self {
|
||||||
|
StateVariableError::ConversionError(format!("URI conversion error: {}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<base64::DecodeError> for StateVariableError {
|
||||||
|
fn from(err: base64::DecodeError) -> Self {
|
||||||
|
StateVariableError::ConversionError(format!("Base64 conversion error: {}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<hex::FromHexError> for StateVariableError {
|
||||||
|
fn from(err: hex::FromHexError) -> Self {
|
||||||
|
StateVariableError::ConversionError(format!("Hex conversion error: {}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
51
pmoupnp/src/actions/action_instance.rs
Normal file
51
pmoupnp/src/actions/action_instance.rs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
use xmltree::{Element, XMLNode};
|
||||||
|
|
||||||
|
use crate::actions::Action;
|
||||||
|
use crate::actions::Argument;
|
||||||
|
use crate::actions::ArgumentSet;
|
||||||
|
use crate::actions::ActionInstance;
|
||||||
|
use crate::UpnpXml;
|
||||||
|
use crate::{UpnpObject, UpnpObjectType};
|
||||||
|
|
||||||
|
impl UpnpXml for ActionInstance {
|
||||||
|
fn to_xml_element(&self) -> Element {
|
||||||
|
let mut elem = Element::new("action");
|
||||||
|
|
||||||
|
// <name>
|
||||||
|
let mut name_elem = Element::new("name");
|
||||||
|
name_elem.children.push(XMLNode::Text(self.get_name().clone()));
|
||||||
|
elem.children.push(XMLNode::Element(name_elem));
|
||||||
|
|
||||||
|
// déplacer tous les enfants de args_elem dans un nouvel Element
|
||||||
|
let args_container = self.arguments_set().to_xml_element();
|
||||||
|
elem.children.push(XMLNode::Element(args_container));
|
||||||
|
|
||||||
|
elem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl UpnpObject for ActionInstance {
|
||||||
|
fn as_upnp_object_type(&self) -> &UpnpObjectType {
|
||||||
|
return &self.object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActionInstance {
|
||||||
|
|
||||||
|
pub fn new(action: &Action) -> Self {
|
||||||
|
Self {
|
||||||
|
object: UpnpObjectType {
|
||||||
|
name: action.get_name().clone(),
|
||||||
|
object_type: "ActionInstance".to_string(),
|
||||||
|
},
|
||||||
|
model: action.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn arguments(&self, name: &str) -> Option<&Argument> {
|
||||||
|
self.model.arguments.get(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn arguments_set(&self) -> &ArgumentSet {
|
||||||
|
&self.model.arguments
|
||||||
|
}
|
||||||
|
}
|
||||||
49
pmoupnp/src/actions/action_instance_set.rs
Normal file
49
pmoupnp/src/actions/action_instance_set.rs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
use crate::{
|
||||||
|
UpnpObject, UpnpXml,
|
||||||
|
actions::{ActionInstance, ActionInstanceSet},
|
||||||
|
};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use xmltree::{Element,XMLNode};
|
||||||
|
|
||||||
|
impl UpnpXml for ActionInstanceSet {
|
||||||
|
// Méthode pour convertir en XML (à implémenter avec une librairie XML)
|
||||||
|
fn to_xml_element(&self) -> Element {
|
||||||
|
let mut elem = Element::new("actionList");
|
||||||
|
|
||||||
|
for action in self.iter() {
|
||||||
|
let action_elem = action.to_xml_element(); // retourne un <action> complet
|
||||||
|
elem.children.push(XMLNode::Element(action_elem));
|
||||||
|
}
|
||||||
|
|
||||||
|
elem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActionInstanceSet {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
instances: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, instance: ActionInstance) {
|
||||||
|
self.instances.insert(instance.get_name().clone(), instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn contains(&self, name: &str) -> bool {
|
||||||
|
self.instances.contains_key(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, name: &str) -> Option<&ActionInstance> {
|
||||||
|
self.instances.get(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> impl Iterator<Item = &ActionInstance> {
|
||||||
|
self.instances.values()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn all(&self) -> Vec<&ActionInstance> {
|
||||||
|
self.instances.values().collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
51
pmoupnp/src/actions/action_methods.rs
Normal file
51
pmoupnp/src/actions/action_methods.rs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
use xmltree::{Element,XMLNode};
|
||||||
|
|
||||||
|
use crate::UpnpXml;
|
||||||
|
use crate::actions::Action;
|
||||||
|
use crate::actions::Argument;
|
||||||
|
use crate::actions::ArgumentSet;
|
||||||
|
use crate::{UpnpObject, UpnpObjectType};
|
||||||
|
|
||||||
|
impl UpnpXml 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 UpnpObject for Action {
|
||||||
|
fn as_upnp_object_type(&self) -> &UpnpObjectType {
|
||||||
|
return &self.object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Action {
|
||||||
|
pub fn new(name: String) -> Action {
|
||||||
|
Self {
|
||||||
|
object: UpnpObjectType {
|
||||||
|
name,
|
||||||
|
object_type: "Action".to_string(),
|
||||||
|
},
|
||||||
|
arguments: ArgumentSet::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_argument(&mut self, arg: Argument) {
|
||||||
|
self.arguments.insert(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn arguments(&self) -> &ArgumentSet {
|
||||||
|
&self.arguments
|
||||||
|
}
|
||||||
|
}
|
||||||
61
pmoupnp/src/actions/action_set_methods.rs
Normal file
61
pmoupnp/src/actions/action_set_methods.rs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use xmltree::{Element, XMLNode};
|
||||||
|
|
||||||
|
use crate::actions::Action;
|
||||||
|
use crate::actions::ActionSet;
|
||||||
|
use crate::actions::errors::ActionError;
|
||||||
|
use crate::UpnpObject;
|
||||||
|
use crate::UpnpXml;
|
||||||
|
|
||||||
|
impl UpnpXml for ActionSet {
|
||||||
|
fn to_xml_element(&self) -> Element {
|
||||||
|
let mut elem = Element::new("actionList");
|
||||||
|
|
||||||
|
for action in self.iter() {
|
||||||
|
let action_elem = action.to_xml_element(); // retourne un <action> complet
|
||||||
|
elem.children.push(XMLNode::Element(action_elem));
|
||||||
|
}
|
||||||
|
|
||||||
|
elem
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActionSet {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
actions: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, action: Action) -> Result<(), ActionError> {
|
||||||
|
let name = action.get_name();
|
||||||
|
if self.actions.contains_key(name) {
|
||||||
|
return Err(ActionError::SetError(
|
||||||
|
format!("Action {} already exists", name)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
self.actions.insert(name.clone(), action);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_or_replace(&mut self, action: Action) {
|
||||||
|
self.actions.insert(action.get_name().clone(), action);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn contains(&self, name: &str) -> bool {
|
||||||
|
self.actions.contains_key(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, name: &str) -> Option<&Action> {
|
||||||
|
self.actions.get(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> impl Iterator<Item = &Action> {
|
||||||
|
self.actions.values()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn all(&self) -> Vec<&Action> {
|
||||||
|
self.actions.values().collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
52
pmoupnp/src/actions/arg_set_methods.rs
Normal file
52
pmoupnp/src/actions/arg_set_methods.rs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
use crate::UpnpObject;
|
||||||
|
use crate::{
|
||||||
|
UpnpXml,
|
||||||
|
actions::{Argument, ArgumentSet},
|
||||||
|
};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use xmltree::Element;
|
||||||
|
|
||||||
|
impl UpnpXml for ArgumentSet {
|
||||||
|
// Méthode pour convertir en XML (à implémenter avec une librairie XML)
|
||||||
|
fn to_xml_element(&self) -> Element {
|
||||||
|
let mut elem = Element::new("argumentList");
|
||||||
|
|
||||||
|
for arg in self.iter() {
|
||||||
|
let arg_elem = arg.to_xml_element(); // toujours un <argumentList> contenant 1 ou 2 <argument>
|
||||||
|
|
||||||
|
// Pour InOut, on ajoute tous les enfants du <argumentList> généré
|
||||||
|
for child in arg_elem.children {
|
||||||
|
elem.children.push(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
elem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ArgumentSet {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
arguments: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, arg: Argument) {
|
||||||
|
self.arguments.insert(arg.get_name().clone(), arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn contains(&self, name: &str) -> bool {
|
||||||
|
self.arguments.contains_key(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, name: &str) -> Option<&Argument> {
|
||||||
|
self.arguments.get(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> impl Iterator<Item = &Argument> {
|
||||||
|
self.arguments.values()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn all(&self) -> Vec<&Argument> {
|
||||||
|
self.arguments.values().collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
108
pmoupnp/src/actions/argument.rs
Normal file
108
pmoupnp/src/actions/argument.rs
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
use xmltree::{Element, XMLNode};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
UpnpObject, UpnpObjectType, UpnpXml, actions::Argument, state_variables::StateVariable,
|
||||||
|
};
|
||||||
|
|
||||||
|
impl UpnpXml for Argument {
|
||||||
|
fn to_xml_element(&self) -> Element {
|
||||||
|
let mut parent = Element::new("argumentList");
|
||||||
|
|
||||||
|
if self.is_in() && self.is_out() {
|
||||||
|
// InOut → deux arguments
|
||||||
|
parent.children.push(XMLNode::Element(make_argument_elem(
|
||||||
|
self.get_name(),
|
||||||
|
"in",
|
||||||
|
self.state_variable().get_name(),
|
||||||
|
)));
|
||||||
|
parent.children.push(XMLNode::Element(make_argument_elem(
|
||||||
|
self.get_name(),
|
||||||
|
"out",
|
||||||
|
self.state_variable().get_name(),
|
||||||
|
)));
|
||||||
|
} else {
|
||||||
|
// Cas simple
|
||||||
|
let direction = if self.is_in() { "in" } else { "out" };
|
||||||
|
parent.children.push(XMLNode::Element(make_argument_elem(
|
||||||
|
self.get_name(),
|
||||||
|
direction,
|
||||||
|
self.state_variable().get_name(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UpnpObject for Argument {
|
||||||
|
fn as_upnp_object_type(&self) -> &UpnpObjectType {
|
||||||
|
return &self.object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Argument {
|
||||||
|
fn new(name: String, state_variable: StateVariable) -> Self {
|
||||||
|
Self {
|
||||||
|
object: UpnpObjectType {
|
||||||
|
name,
|
||||||
|
object_type: "Argument".to_string(),
|
||||||
|
},
|
||||||
|
state_variable,
|
||||||
|
is_in: false,
|
||||||
|
is_out: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_in(name: String, state_variable: StateVariable) -> Self {
|
||||||
|
let mut arg = Self::new(name, state_variable);
|
||||||
|
arg.is_in = true;
|
||||||
|
arg
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_out(name: String, state_variable: StateVariable) -> Self {
|
||||||
|
let mut arg = Self::new(name, state_variable);
|
||||||
|
arg.is_out = true;
|
||||||
|
arg
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_in_out(name: String, state_variable: StateVariable) -> Self {
|
||||||
|
let mut arg = Self::new(name, state_variable);
|
||||||
|
arg.is_in = true;
|
||||||
|
arg.is_out = true;
|
||||||
|
arg
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn state_variable(&self) -> &StateVariable {
|
||||||
|
&self.state_variable
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_in(&self) -> bool {
|
||||||
|
self.is_in
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_out(&self) -> bool {
|
||||||
|
self.is_out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fabrique un <argument> complet avec ses sous-éléments
|
||||||
|
fn make_argument_elem(name: &str, direction: &str, state_var_name: &str) -> Element {
|
||||||
|
let mut arg = Element::new("argument");
|
||||||
|
|
||||||
|
let mut name_elem = Element::new("name");
|
||||||
|
name_elem.children.push(XMLNode::Text(name.to_string()));
|
||||||
|
|
||||||
|
let mut dir_elem = Element::new("direction");
|
||||||
|
dir_elem.children.push(XMLNode::Text(direction.to_string()));
|
||||||
|
|
||||||
|
let mut rel_elem = Element::new("relatedStateVariable");
|
||||||
|
rel_elem
|
||||||
|
.children
|
||||||
|
.push(XMLNode::Text(state_var_name.to_string()));
|
||||||
|
|
||||||
|
arg.children.push(XMLNode::Element(name_elem));
|
||||||
|
arg.children.push(XMLNode::Element(dir_elem));
|
||||||
|
arg.children.push(XMLNode::Element(rel_elem));
|
||||||
|
|
||||||
|
arg
|
||||||
|
}
|
||||||
19
pmoupnp/src/actions/errors.rs
Normal file
19
pmoupnp/src/actions/errors.rs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum ActionError {
|
||||||
|
#[error("Action error: {0}")]
|
||||||
|
GeneralError(String),
|
||||||
|
|
||||||
|
#[error("Argument error: {0}")]
|
||||||
|
ArgumentError(String),
|
||||||
|
|
||||||
|
#[error("Set operation error: {0}")]
|
||||||
|
SetError(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::io::Error> for ActionError {
|
||||||
|
fn from(err: std::io::Error) -> Self {
|
||||||
|
ActionError::GeneralError(format!("IO error: {}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
48
pmoupnp/src/actions/mod.rs
Normal file
48
pmoupnp/src/actions/mod.rs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
mod errors;
|
||||||
|
|
||||||
|
mod action_methods;
|
||||||
|
mod action_instance;
|
||||||
|
mod action_set_methods;
|
||||||
|
mod action_instance_set;
|
||||||
|
mod argument;
|
||||||
|
mod arg_set_methods;
|
||||||
|
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use crate::{state_variables::StateVariable, UpnpObjectType};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct Action {
|
||||||
|
object: UpnpObjectType,
|
||||||
|
arguments: ArgumentSet,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
pub struct ActionSet {
|
||||||
|
actions: HashMap<String, Action>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ActionInstance {
|
||||||
|
object: UpnpObjectType,
|
||||||
|
model: Action,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
pub struct ActionInstanceSet {
|
||||||
|
instances: HashMap<String, ActionInstance>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Argument {
|
||||||
|
object: UpnpObjectType,
|
||||||
|
state_variable: StateVariable,
|
||||||
|
is_in: bool,
|
||||||
|
is_out: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
pub struct ArgumentSet {
|
||||||
|
arguments: HashMap<String, Argument>,
|
||||||
|
}
|
||||||
@@ -4,10 +4,11 @@ pub mod server;
|
|||||||
pub mod state_variables;
|
pub mod state_variables;
|
||||||
pub mod value_ranges;
|
pub mod value_ranges;
|
||||||
pub mod variable_types;
|
pub mod variable_types;
|
||||||
|
pub mod actions;
|
||||||
|
|
||||||
pub use crate::object_trait::UpnpObject;
|
pub use crate::object_trait::{UpnpXml,UpnpObject};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Debug,Clone)]
|
||||||
pub struct UpnpObjectType {
|
pub struct UpnpObjectType {
|
||||||
name: String,
|
name: String,
|
||||||
object_type: String,
|
object_type: String,
|
||||||
|
|||||||
@@ -2,18 +2,8 @@ use xmltree::{Element, EmitterConfig};
|
|||||||
|
|
||||||
use crate::UpnpObjectType;
|
use crate::UpnpObjectType;
|
||||||
|
|
||||||
pub trait UpnpObject {
|
pub trait UpnpXml {
|
||||||
fn as_upnp_object_type(&self) -> &UpnpObjectType;
|
|
||||||
fn to_xml_element(&self) -> Element;
|
fn to_xml_element(&self) -> Element;
|
||||||
|
|
||||||
fn get_name(&self) -> &String {
|
|
||||||
return &self.as_upnp_object_type().name;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_object_type(&self) -> &String {
|
|
||||||
&self.as_upnp_object_type().object_type
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_xml(&self) -> String {
|
fn to_xml(&self) -> String {
|
||||||
let elem = self.to_xml_element();
|
let elem = self.to_xml_element();
|
||||||
|
|
||||||
@@ -35,3 +25,16 @@ pub trait UpnpObject {
|
|||||||
xml_string
|
xml_string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub trait UpnpObject : UpnpXml {
|
||||||
|
fn as_upnp_object_type(&self) -> &UpnpObjectType;
|
||||||
|
|
||||||
|
fn get_name(&self) -> &String {
|
||||||
|
return &self.as_upnp_object_type().name;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_object_type(&self) -> &String {
|
||||||
|
&self.as_upnp_object_type().object_type
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use xmltree::Element;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
UpnpObject, UpnpObjectType,
|
UpnpObject, UpnpObjectType,
|
||||||
|
object_trait::UpnpXml,
|
||||||
state_variables::{StateVarInstance, StateVariable, UpnpVariable},
|
state_variables::{StateVarInstance, StateVariable, UpnpVariable},
|
||||||
variable_types::StateValue,
|
variable_types::StateValue,
|
||||||
};
|
};
|
||||||
@@ -13,14 +14,16 @@ impl UpnpVariable for StateVarInstance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl UpnpXml for StateVarInstance {
|
||||||
|
fn to_xml_element(&self) -> Element {
|
||||||
|
self.get_definition().to_xml_element()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl UpnpObject for StateVarInstance {
|
impl UpnpObject for StateVarInstance {
|
||||||
fn as_upnp_object_type(&self) -> &UpnpObjectType {
|
fn as_upnp_object_type(&self) -> &UpnpObjectType {
|
||||||
return &self.object;
|
return &self.object;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_xml_element(&self) -> Element {
|
|
||||||
self.get_definition().to_xml_element()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StateVarInstance {
|
impl StateVarInstance {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
mod errors;
|
mod errors;
|
||||||
mod instance_methods;
|
mod instance_methods;
|
||||||
mod variable_methods;
|
mod variable_methods;
|
||||||
|
mod var_set_methods;
|
||||||
mod variable_trait;
|
mod variable_trait;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
@@ -44,6 +45,11 @@ pub struct StateVariable {
|
|||||||
marshal: Option<ValueSerializer>,
|
marshal: Option<ValueSerializer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
pub struct StateVariableSet {
|
||||||
|
instances: HashMap<String, StateVariable>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct StateVarInstance {
|
pub struct StateVarInstance {
|
||||||
object: UpnpObjectType,
|
object: UpnpObjectType,
|
||||||
definition: StateVariable,
|
definition: StateVariable,
|
||||||
|
|||||||
34
pmoupnp/src/state_variables/var_set_methods.rs
Normal file
34
pmoupnp/src/state_variables/var_set_methods.rs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::{state_variables::{StateVariable, StateVariableSet}, UpnpObject};
|
||||||
|
|
||||||
|
impl StateVariableSet {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
instances: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, instance: StateVariable) {
|
||||||
|
self.instances.insert(instance.get_name().clone(), instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn contains(&self, name: &str) -> bool {
|
||||||
|
self.instances.contains_key(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, name: &str) -> Option<&StateVariable> {
|
||||||
|
self.instances.get(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> impl Iterator<Item = &StateVariable> {
|
||||||
|
self.instances.values()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn all(&self) -> Vec<&StateVariable> {
|
||||||
|
self.instances.values().collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,25 +1,16 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap, fmt, sync::{Arc, RwLock}
|
||||||
sync::{Arc, RwLock},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use xmltree::{Element, XMLNode};
|
use xmltree::{Element, XMLNode};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
UpnpObject, UpnpObjectType,
|
object_trait::UpnpXml, state_variables::{
|
||||||
state_variables::{
|
variable_trait::UpnpVariable, StateConditionFunc, StateVariable, StringValueParser, ValueSerializer
|
||||||
StateConditionFunc, StateVariable, StringValueParser, ValueSerializer,
|
}, value_ranges::ValueRange, variable_types::{StateValue, StateValueError, StateVarType, UpnpVarType}, UpnpObject, UpnpObjectType
|
||||||
variable_trait::UpnpVariable,
|
|
||||||
},
|
|
||||||
value_ranges::ValueRange,
|
|
||||||
variable_types::{StateValue, StateValueError, StateVarType, UpnpVarType},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
impl UpnpObject for StateVariable {
|
impl UpnpXml for StateVariable {
|
||||||
fn as_upnp_object_type(&self) -> &UpnpObjectType {
|
|
||||||
return &self.object;
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
||||||
@@ -91,6 +82,13 @@ impl UpnpObject for StateVariable {
|
|||||||
|
|
||||||
root
|
root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UpnpObject for StateVariable {
|
||||||
|
fn as_upnp_object_type(&self) -> &UpnpObjectType {
|
||||||
|
return &self.object;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for StateVariable {
|
impl Clone for StateVariable {
|
||||||
@@ -133,6 +131,37 @@ impl Clone for StateVariable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for StateVariable {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.debug_struct("StateVariable")
|
||||||
|
.field("object", &self.object)
|
||||||
|
.field("value_type", &self.value_type)
|
||||||
|
.field("step", &self.step)
|
||||||
|
.field("modifiable", &self.modifiable)
|
||||||
|
.field(
|
||||||
|
"event_conditions",
|
||||||
|
&format_args!(
|
||||||
|
"len={}",
|
||||||
|
self.event_conditions.read().map(|m| m.len()).unwrap_or(0)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.field("description", &self.description)
|
||||||
|
.field("default_value", &self.default_value)
|
||||||
|
.field("value_range", &self.value_range)
|
||||||
|
.field(
|
||||||
|
"allowed_values",
|
||||||
|
&format_args!(
|
||||||
|
"len={}",
|
||||||
|
self.allowed_values.read().map(|v| v.len()).unwrap_or(0)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.field("send_events", &self.send_events)
|
||||||
|
.field("parse", &self.parse.as_ref().map(|_| "Some(StringValueParser)").unwrap_or("None"))
|
||||||
|
.field("marshal", &self.marshal.as_ref().map(|_| "Some(ValueSerializer)").unwrap_or("None"))
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl UpnpVarType for StateVariable {
|
impl UpnpVarType for StateVariable {
|
||||||
fn as_state_var_type(&self) -> StateVarType {
|
fn as_state_var_type(&self) -> StateVarType {
|
||||||
self.value_type // utilise ton From<&StateValue> existant
|
self.value_type // utilise ton From<&StateValue> existant
|
||||||
|
|||||||
Reference in New Issue
Block a user