mod parser;
mod types;
mod writer;
mod validator;
mod binary;
pub use types::{Interval, Point, TextGrid, TextGridError, Tier, TierType};
use std::path::Path;
impl TextGrid {
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self, TextGridError> {
let path_ref = path.as_ref();
if let Some(ext) = path_ref.extension() {
match ext.to_str().unwrap_or("").to_lowercase().as_str() {
"textgrid" => {
let textgrid = parser::parse_textgrid(path)?;
validator::validate_textgrid(&textgrid)?;
Ok(textgrid)
}
"textgridbin" => {
let textgrid = binary::read_binary(path)?;
validator::validate_textgrid(&textgrid)?;
Ok(textgrid)
}
_ => Err(TextGridError::Format("Unsupported file extension".into())),
}
} else {
Err(TextGridError::Format("No file extension".into()))
}
}
pub fn to_file<P: AsRef<Path>>(&self, path: P, short_format: bool) -> Result<(), TextGridError> {
validator::validate_textgrid(self)?;
writer::write_textgrid(self, path, short_format)
}
pub fn to_binary_file<P: AsRef<Path>>(&self, path: P) -> Result<(), TextGridError> {
validator::validate_textgrid(self)?;
binary::write_binary(self, path)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_undo_redo() {
let mut textgrid = TextGrid::new(0.0, 5.0).unwrap();
let tier = Tier {
name: "test".to_string(),
tier_type: TierType::IntervalTier,
xmin: 0.0,
xmax: 5.0,
intervals: vec![Interval { xmin: 0.0, xmax: 5.0, text: "test".to_string() }],
points: vec![],
};
textgrid.add_tier(tier.clone()).unwrap();
assert_eq!(textgrid.tiers.len(), 1);
textgrid.undo().unwrap();
assert_eq!(textgrid.tiers.len(), 0);
textgrid.redo().unwrap();
assert_eq!(textgrid.tiers.len(), 1);
textgrid.tier_add_interval("test", Interval { xmin: 2.0, xmax: 3.0, text: "new".to_string() }).unwrap();
assert_eq!(textgrid.get_tier("test").unwrap().intervals.len(), 2);
textgrid.undo().unwrap();
assert_eq!(textgrid.get_tier("test").unwrap().intervals.len(), 1);
}
#[test]
fn test_advanced_merge() {
let mut textgrid = TextGrid::new(0.0, 5.0).unwrap();
textgrid.add_tier(Tier {
name: "t1".to_string(),
tier_type: TierType::IntervalTier,
xmin: 0.0,
xmax: 5.0,
intervals: vec![Interval { xmin: 0.0, xmax: 2.0, text: "a".to_string() }],
points: vec![],
}).unwrap();
textgrid.add_tier(Tier {
name: "t2".to_string(),
tier_type: TierType::IntervalTier,
xmin: 0.0,
xmax: 5.0,
intervals: vec![Interval { xmin: 1.0, xmax: 3.0, text: "b".to_string() }],
points: vec![],
}).unwrap();
textgrid.merge_tiers_with_strategy("t1", "t2", "merged".to_string(), |a, b| {
Some(Interval {
xmin: a.xmin,
xmax: a.xmax.max(b.xmax),
text: format!("{}-{}", a.text, b.text),
})
}).unwrap();
let merged = textgrid.get_tier("merged").unwrap();
assert_eq!(merged.intervals[0].text, "a-b");
}
#[test]
fn test_query() {
let mut textgrid = TextGrid::new(0.0, 5.0).unwrap();
textgrid.add_tier(Tier {
name: "test".to_string(),
tier_type: TierType::IntervalTier,
xmin: 0.0,
xmax: 5.0,
intervals: vec![Interval { xmin: 0.0, xmax: 2.0, text: "hello".to_string() }],
points: vec![],
}).unwrap();
let results = textgrid.query_intervals_by_text("hello");
assert_eq!(results.len(), 1);
assert_eq!(results[0].1[0].text, "hello");
}
#[test]
fn test_binary() {
let mut textgrid = TextGrid::new(0.0, 5.0).unwrap();
textgrid.add_tier(Tier {
name: "test".to_string(),
tier_type: TierType::IntervalTier,
xmin: 0.0,
xmax: 5.0,
intervals: vec![Interval { xmin: 0.0, xmax: 2.0, text: "hello".to_string() }],
points: vec![],
}).unwrap();
textgrid.to_binary_file("test.textgridbin").unwrap();
let loaded = TextGrid::from_file("test.textgridbin").unwrap();
assert_eq!(loaded.tiers[0].intervals[0].text, "hello");
std::fs::remove_file("test.textgridbin").unwrap();
}
}