1use std::io::SeekFrom;
2
3pub trait Seek {
6 fn seek(&mut self, pos: SeekFrom) -> impl Future<Output = std::io::Result<u64>>;
8
9 fn rewind(&mut self) -> impl Future<Output = std::io::Result<u64>> {
13 self.seek(SeekFrom::Start(0))
14 }
15
16 fn stream_position(&mut self) -> impl Future<Output = std::io::Result<u64>> {
20 self.seek(SeekFrom::Current(0))
21 }
22
23 fn seek_relative(&mut self, offset: i64) -> impl Future<Output = std::io::Result<u64>> {
27 self.seek(SeekFrom::Current(offset))
28 }
29}
30
31#[cfg(test)]
32mod test {
33 use super::*;
34
35 struct MockSeek {
36 position: u64,
37 max_size: i64,
38 }
39
40 impl MockSeek {
41 fn new(max_size: i64) -> Self {
42 Self {
43 position: 0,
44 max_size,
45 }
46 }
47 }
48
49 impl Seek for MockSeek {
50 async fn seek(&mut self, pos: SeekFrom) -> std::io::Result<u64> {
51 match pos {
52 SeekFrom::Start(offset) => {
53 self.position = offset;
54 }
55 SeekFrom::Current(offset) => {
56 self.position = self.position.saturating_add(offset as u64);
57 }
58 SeekFrom::End(offset) => {
59 self.position = self.max_size.saturating_add(offset) as u64;
60 }
61 }
62 Ok(self.position)
63 }
64 }
65
66 #[tokio::test]
67 async fn test_seek() {
68 let mut seek = MockSeek::new(50);
69 assert_eq!(seek.seek(SeekFrom::Start(10)).await.unwrap(), 10);
70 assert_eq!(seek.seek(SeekFrom::Current(5)).await.unwrap(), 15);
71 assert_eq!(seek.seek(SeekFrom::End(-5)).await.unwrap(), 45);
72 }
73}