talw_timecode/
time_range.rs1use crate::error::TimecodeError;
2use crate::timecode::Timecode;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub struct TimeRange {
6 start: Timecode,
7 duration_frames: i64,
8}
9
10impl TimeRange {
11 pub fn new(start: Timecode, duration_frames: i64) -> Self {
12 Self {
13 start,
14 duration_frames,
15 }
16 }
17
18 pub fn from_start_end(start: Timecode, end: Timecode) -> Result<Self, TimecodeError> {
19 let diff = end.frame_diff(&start)?;
20 Ok(Self {
21 start,
22 duration_frames: diff,
23 })
24 }
25
26 pub fn start(&self) -> Timecode {
27 self.start
28 }
29
30 pub fn duration_frames(&self) -> i64 {
31 self.duration_frames
32 }
33
34 pub fn end(&self) -> Timecode {
35 self.start + self.duration_frames
36 }
37
38 pub fn contains(&self, tc: Timecode) -> bool {
39 if tc.rate() != self.start.rate() {
40 return false;
41 }
42 let f = tc.total_frames();
43 f >= self.start.total_frames() && f < self.start.total_frames() + self.duration_frames
44 }
45
46 pub fn overlaps(&self, other: &TimeRange) -> bool {
47 if self.start.rate() != other.start.rate() {
48 return false;
49 }
50 let s1 = self.start.total_frames();
51 let e1 = s1 + self.duration_frames;
52 let s2 = other.start.total_frames();
53 let e2 = s2 + other.duration_frames;
54
55 s1 < e2 && s2 < e1
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62 use crate::framerate::FrameRate;
63
64 #[test]
65 fn basic_range() {
66 let start = Timecode::from_frames(0, FrameRate::Fps24);
67 let r = TimeRange::new(start, 240);
68 assert_eq!(r.end().total_frames(), 240);
69 }
70
71 #[test]
72 fn contains() {
73 let start = Timecode::from_frames(100, FrameRate::Fps24);
74 let r = TimeRange::new(start, 50);
75 assert!(r.contains(Timecode::from_frames(120, FrameRate::Fps24)));
76 assert!(!r.contains(Timecode::from_frames(150, FrameRate::Fps24)));
77 assert!(!r.contains(Timecode::from_frames(99, FrameRate::Fps24)));
78 }
79
80 #[test]
81 fn overlaps() {
82 let a = TimeRange::new(Timecode::from_frames(0, FrameRate::Fps24), 100);
83 let b = TimeRange::new(Timecode::from_frames(50, FrameRate::Fps24), 100);
84 let c = TimeRange::new(Timecode::from_frames(100, FrameRate::Fps24), 50);
85
86 assert!(a.overlaps(&b));
87 assert!(!a.overlaps(&c));
88 }
89
90 #[test]
91 fn from_start_end() {
92 let start = Timecode::from_frames(100, FrameRate::Fps24);
93 let end = Timecode::from_frames(200, FrameRate::Fps24);
94 let r = TimeRange::from_start_end(start, end).unwrap();
95 assert_eq!(r.duration_frames(), 100);
96 }
97}