Skip to content

Commit

Permalink
Make parse() a method on Protocol
Browse files Browse the repository at this point in the history
Signed-off-by: Sean Young <[email protected]>
  • Loading branch information
seanyoung committed Apr 13, 2024
1 parent d51a898 commit 5045e76
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 109 deletions.
3 changes: 2 additions & 1 deletion irp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ mod inverse;
mod message;
mod parser;
mod pronto;
pub mod protocols;
mod protocols;
mod variants;

pub use build_dfa::DFA;
pub use build_nfa::NFA;
pub use decoder::Decoder;
pub use protocols::Protocol;

use num_rational::Rational64;
use std::{collections::HashMap, fmt, rc::Rc};
Expand Down
203 changes: 105 additions & 98 deletions irp/src/protocols.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
//! Parsing of IrpTransmogrifier's IrpProtocols.xml.
use serde::Deserialize;
use std::{fs::File, io::BufReader, path::Path, str::FromStr};
use std::{
fs::File,
io::{self, BufReader},
path::Path,
str::FromStr,
};
use xml::reader::{EventReader, XmlEvent};

/// Entry in IrpTransmogrifier's IrpProtocols.xml.
#[derive(Debug, Deserialize, PartialEq, Default)]
pub struct Protocol {
pub name: String,
Expand Down Expand Up @@ -31,122 +37,123 @@ enum Element {
RejectRepeatLess,
}

/// Parsing IrpProtocols.xml file
#[allow(dead_code)]
pub fn parse(path: &Path) -> Vec<Protocol> {
let file = File::open(path).unwrap();
let file = BufReader::new(file);
impl Protocol {
/// Parse IrpTransmogrifier's IrpProtocols.xml.
pub fn parse(path: &Path) -> io::Result<Vec<Protocol>> {
let file = File::open(path)?;
let file = BufReader::new(file);

let parser = EventReader::new(file);
let mut protocols: Vec<Protocol> = Vec::new();
let mut protocol = None;
let mut element = Element::None;
let parser = EventReader::new(file);
let mut protocols: Vec<Protocol> = Vec::new();
let mut protocol = None;
let mut element = Element::None;

for e in parser {
match e {
Ok(XmlEvent::StartElement {
name, attributes, ..
}) => match name.local_name.as_ref() {
"protocol" => {
if attributes.len() == 1 && attributes[0].name.local_name == "name" {
protocol = Some(Protocol {
name: attributes[0].value.to_owned(),
decodable: true,
absolute_tolerance: 100,
relative_tolerance: 0.3,
minimum_leadout: 20000,
..Default::default()
});
} else {
panic!("missing name attribute");
for e in parser {
match e {
Ok(XmlEvent::StartElement {
name, attributes, ..
}) => match name.local_name.as_ref() {
"protocol" => {
if attributes.len() == 1 && attributes[0].name.local_name == "name" {
protocol = Some(Protocol {
name: attributes[0].value.to_owned(),
decodable: true,
absolute_tolerance: 100,
relative_tolerance: 0.3,
minimum_leadout: 20000,
..Default::default()
});
} else {
panic!("missing name attribute");
}
}
}
"irp" => {
element = Element::Irp;
}
"parameter" => {
for attr in attributes {
match attr.name.local_name.as_ref() {
"prefer_over" => {
element = Element::PreferOver;
"irp" => {
element = Element::Irp;
}
"parameter" => {
for attr in attributes {
match attr.name.local_name.as_ref() {
"prefer_over" => {
element = Element::PreferOver;
}
"absolute-tolerance" => {
element = Element::AbsoluteTolerance;
}
"relative-tolerance" => {
element = Element::RelativeTolerance;
}
"decodable" => {
element = Element::Decodable;
}
"decode-only" => {
element = Element::DecodeOnly;
}
"alt_name" => {
element = Element::AlternateName;
}
"minimum-leadout" => {
element = Element::MinimumLeadout;
}
"reject_repeatless" => {
element = Element::RejectRepeatLess;
}
_ => (),
}
}
}
_ => (),
},
Ok(XmlEvent::CData(data)) => {
if let Some(protocol) = &mut protocol {
match element {
Element::Irp => {
protocol.irp = data;
}
Element::AlternateName => {
protocol.alt_name.push(data);
}
"absolute-tolerance" => {
element = Element::AbsoluteTolerance;
Element::PreferOver => {
protocol.prefer_over.push(data);
}
"relative-tolerance" => {
element = Element::RelativeTolerance;
Element::Decodable => {
protocol.decodable = bool::from_str(&data).unwrap();
}
"decodable" => {
element = Element::Decodable;
Element::DecodeOnly => {
protocol.decode_only = bool::from_str(&data).unwrap();
}
"decode-only" => {
element = Element::DecodeOnly;
Element::RejectRepeatLess => {
protocol.reject_repeatess = bool::from_str(&data).unwrap();
}
"alt_name" => {
element = Element::AlternateName;
Element::AbsoluteTolerance => {
protocol.absolute_tolerance = u32::from_str(&data).unwrap();
}
"minimum-leadout" => {
element = Element::MinimumLeadout;
Element::RelativeTolerance => {
protocol.relative_tolerance = f32::from_str(&data).unwrap();
}
"reject_repeatless" => {
element = Element::RejectRepeatLess;
Element::MinimumLeadout => {
protocol.minimum_leadout = u32::from_str(&data).unwrap();
}
_ => (),
Element::None => (),
}
}

element = Element::None;
}
_ => (),
},
Ok(XmlEvent::CData(data)) => {
if let Some(protocol) = &mut protocol {
match element {
Element::Irp => {
protocol.irp = data;
}
Element::AlternateName => {
protocol.alt_name.push(data);
}
Element::PreferOver => {
protocol.prefer_over.push(data);
}
Element::Decodable => {
protocol.decodable = bool::from_str(&data).unwrap();
Ok(XmlEvent::EndElement { name }) => {
if name.local_name == "protocol" {
if let Some(protocol) = protocol {
protocols.push(protocol);
}
Element::DecodeOnly => {
protocol.decode_only = bool::from_str(&data).unwrap();
}
Element::RejectRepeatLess => {
protocol.reject_repeatess = bool::from_str(&data).unwrap();
}
Element::AbsoluteTolerance => {
protocol.absolute_tolerance = u32::from_str(&data).unwrap();
}
Element::RelativeTolerance => {
protocol.relative_tolerance = f32::from_str(&data).unwrap();
}
Element::MinimumLeadout => {
protocol.minimum_leadout = u32::from_str(&data).unwrap();
}
Element::None => (),
protocol = None;
}
}

element = Element::None;
}
Ok(XmlEvent::EndElement { name }) => {
if name.local_name == "protocol" {
if let Some(protocol) = protocol {
protocols.push(protocol);
}
protocol = None;
Err(e) => {
panic!("Error: {e}");
}
_ => {}
}
Err(e) => {
panic!("Error: {e}");
}
_ => {}
}
}

protocols
Ok(protocols)
}
}
20 changes: 10 additions & 10 deletions irp/tests/tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use irp::{
protocols::{parse, Protocol},
Decoder, Event, InfraredData, Irp, Message, Options, Vartable,
};
use irp::{Decoder, Event, InfraredData, Irp, Message, Options, Protocol, Vartable};
use irptransmogrifier::{create_jvm, IrpTransmogrifierRender};
use itertools::Itertools;
use rand::Rng;
Expand Down Expand Up @@ -266,9 +263,10 @@ fn vars() {

#[test]
fn parse_all_of_them() {
let protocols = parse(&PathBuf::from(
let protocols = Protocol::parse(&PathBuf::from(
"tests/IrpTransmogrifier/src/main/resources/IrpProtocols.xml",
));
))
.unwrap();

let mut broken = 0;
let mut total = 0;
Expand Down Expand Up @@ -327,9 +325,10 @@ fn compare_with_rounding(l: &[u32], r: &[u32]) -> bool {

#[test]
fn compare_encode_to_transmogrifier() {
let mut protocols = parse(&PathBuf::from(
let mut protocols = Protocol::parse(&PathBuf::from(
"tests/IrpTransmogrifier/src/main/resources/IrpProtocols.xml",
));
))
.unwrap();

let mut total_tests = 0;
let mut fails = 0;
Expand Down Expand Up @@ -424,9 +423,10 @@ fn compare_encode_to_transmogrifier() {

#[test]
fn decode_all() {
let protocols = parse(&PathBuf::from(
let protocols = Protocol::parse(&PathBuf::from(
"tests/IrpTransmogrifier/src/main/resources/IrpProtocols.xml",
));
))
.unwrap();

let mut total_tests = 0;
let mut fails = 0;
Expand Down

0 comments on commit 5045e76

Please sign in to comment.