This is a UPnP client library for Rust.

Merge pull request #5 from tsirysndr/feat/GetTransportInfo

feat: add support for `GetTransportInfo` action

authored by tsiry-sandratraina.com and committed by GitHub 5c3e13d1 8f223bdc

+1 -1
Cargo.toml
··· 1 1 [package] 2 2 name = "upnp-client" 3 - version = "0.1.5" 3 + version = "0.1.6" 4 4 edition = "2021" 5 5 repository = "https://github.com/tsirysndr/upnp-client-rs" 6 6 license = "MIT"
+15 -2
src/media_renderer.rs
··· 7 7 8 8 use crate::{ 9 9 device_client::DeviceClient, 10 - parser::{parse_duration, parse_position, parse_supported_protocols, parse_volume}, 11 - types::{Event, LoadOptions, Metadata, ObjectClass}, 10 + parser::{ 11 + parse_duration, parse_position, parse_supported_protocols, parse_transport_info, 12 + parse_volume, 13 + }, 14 + types::{Event, LoadOptions, Metadata, ObjectClass, TransportInfo}, 12 15 BROADCAST_EVENT, 13 16 }; 14 17 ··· 261 264 yield event; 262 265 } 263 266 } 267 + } 268 + 269 + pub async fn get_transport_info(&self) -> Result<TransportInfo, Error> { 270 + let mut params = HashMap::new(); 271 + params.insert("InstanceID".to_string(), "0".to_string()); 272 + let response = self 273 + .device_client 274 + .call_action("AVTransport", "GetTransportInfo", params) 275 + .await?; 276 + Ok(parse_transport_info(response.as_str())?) 264 277 } 265 278 } 266 279
+49 -1
src/parser.rs
··· 1 1 use std::time::Duration; 2 2 3 - use crate::types::{Action, Argument, Container, Device, Item, Metadata, Service}; 3 + use crate::types::{Action, Argument, Container, Device, Item, Metadata, Service, TransportInfo}; 4 4 use anyhow::Error; 5 5 use elementtree::Element; 6 6 use surf::{http::Method, Client, Config, Url}; ··· 707 707 } 708 708 Ok((containers, items)) 709 709 } 710 + 711 + pub fn parse_transport_info(xml: &str) -> Result<TransportInfo, Error> { 712 + let parser = EventReader::from_str(xml); 713 + let mut in_transport_state = false; 714 + let mut in_transport_status = false; 715 + let mut in_transport_play_speed = false; 716 + let mut transport_info = TransportInfo::default(); 717 + 718 + for e in parser { 719 + match e { 720 + Ok(XmlEvent::StartElement { name, .. }) => { 721 + if name.local_name == "CurrentTransportState" { 722 + in_transport_state = true; 723 + } 724 + if name.local_name == "CurrentTransportStatus" { 725 + in_transport_status = true; 726 + } 727 + if name.local_name == "CurrentSpeed" { 728 + in_transport_play_speed = true; 729 + } 730 + } 731 + Ok(XmlEvent::EndElement { name }) => { 732 + if name.local_name == "CurrentTransportState" { 733 + in_transport_state = false; 734 + } 735 + if name.local_name == "CurrentTransportStatus" { 736 + in_transport_status = false; 737 + } 738 + if name.local_name == "CurrentSpeed" { 739 + in_transport_play_speed = false; 740 + } 741 + } 742 + Ok(XmlEvent::Characters(value)) => { 743 + if in_transport_state { 744 + transport_info.current_transport_state = value.clone(); 745 + } 746 + if in_transport_status { 747 + transport_info.current_transport_status = value.clone(); 748 + } 749 + if in_transport_play_speed { 750 + transport_info.current_speed = value.clone(); 751 + } 752 + } 753 + _ => {} 754 + } 755 + } 756 + Ok(transport_info) 757 + }
+7
src/types.rs
··· 212 212 pub duration: Option<String>, 213 213 pub object_class: Option<ObjectClass>, 214 214 } 215 + 216 + #[derive(Debug, Clone, Default)] 217 + pub struct TransportInfo { 218 + pub current_transport_state: String, 219 + pub current_transport_status: String, 220 + pub current_speed: String, 221 + }