|
1 use crate::core::types::Replay; |
|
2 //use super::demo::load; |
|
3 use std::fs; |
|
4 use std::path::PathBuf; |
|
5 |
|
6 pub struct ReplayStorage { |
|
7 borrowed_replays: Vec<ReplayId>, |
|
8 } |
|
9 |
|
10 #[derive(Clone, PartialEq)] |
|
11 pub struct ReplayId { |
|
12 path: PathBuf, |
|
13 } |
|
14 |
|
15 impl ReplayStorage { |
|
16 pub fn new() -> Self { |
|
17 ReplayStorage { |
|
18 borrowed_replays: vec![], |
|
19 } |
|
20 } |
|
21 |
|
22 pub fn pick_replay(&mut self, protocol: u16) -> Option<(ReplayId, Replay)> { |
|
23 let protocol_suffix = format!(".{}", protocol); |
|
24 let result = fs::read_dir("replays") |
|
25 .ok()? |
|
26 .flat_map(|f| Some(f.ok()?.path())) |
|
27 .filter(|f| { |
|
28 f.ends_with(&protocol_suffix) && !self.borrowed_replays.iter().any(|e| &e.path == f) |
|
29 }) |
|
30 .next() |
|
31 .and_then(|f| { |
|
32 Some(( |
|
33 ReplayId { path: f.clone() }, |
|
34 Replay::load(f.to_str()?).ok()?, |
|
35 )) |
|
36 }); |
|
37 |
|
38 if let Some((ref replay_id, _)) = result { |
|
39 self.borrowed_replays.push((*replay_id).clone()); |
|
40 } |
|
41 |
|
42 result |
|
43 } |
|
44 |
|
45 pub fn move_failed_replay(&mut self, id: &ReplayId) -> std::io::Result<()> { |
|
46 self.unborrow(id); |
|
47 self.move_file("failed", id) |
|
48 } |
|
49 |
|
50 pub fn move_checked_replay(&mut self, id: &ReplayId) -> std::io::Result<()> { |
|
51 self.unborrow(id); |
|
52 self.move_file("checked", id) |
|
53 } |
|
54 |
|
55 pub fn requeue_replay(&mut self, id: &ReplayId) { |
|
56 self.unborrow(id) |
|
57 } |
|
58 |
|
59 fn unborrow(&mut self, id: &ReplayId) { |
|
60 self.borrowed_replays.retain(|i| i != id) |
|
61 } |
|
62 |
|
63 fn move_file(&self, dir: &str, id: &ReplayId) -> std::io::Result<()> { |
|
64 let new_name = format!( |
|
65 "{}/{}", |
|
66 dir, |
|
67 id.path |
|
68 .file_name() |
|
69 .and_then(|f| f.to_str()) |
|
70 .expect("What's up with your file name?") |
|
71 ); |
|
72 |
|
73 fs::rename(&id.path, new_name) |
|
74 } |
|
75 } |