#[derive(Default)]
pub struct QbtMock {
pub deleted: std::sync::Mutex<Vec<crate::InfoHash>>,
pub free_space: u64,
pub torrents: Vec<crate::MockTorrent>,
pub trackers: Vec<crate::Tracker>,
}
impl QbtMock {
pub fn with_trackers(
trackers: impl IntoIterator<Item = crate::Tracker>,
) -> Self {
Self {
trackers: trackers.into_iter().collect(),
..Default::default()
}
}
pub fn deleted(&self) -> Vec<crate::InfoHash> {
self.deleted.lock().unwrap().clone()
}
}
pub fn global_with_trackers(
config: crate::Config,
now: std::time::SystemTime,
trackers: impl IntoIterator<Item = crate::Tracker>,
) -> crate::Global<QbtMock> {
crate::Global {
config,
now,
qbt: QbtMock::with_trackers(trackers),
}
}
impl crate::Qbt for QbtMock {
async fn logout(self) -> anyhow::Result<()> {
unimplemented!("QbtMock::logout")
}
async fn server_state(&self) -> anyhow::Result<crate::ServerState> {
Ok(crate::ServerState {
free_space_on_disk: self.free_space,
})
}
async fn torrents_info(&self) -> anyhow::Result<Vec<crate::Torrent>> {
Ok(self.torrents.iter()
.map(|t| t.torrent.clone())
.collect())
}
async fn torrent_files(&self, hash: crate::InfoHash)
-> anyhow::Result<Vec<crate::TorrentFile>>
{
let t = self.torrents.iter()
.find(|t| t.torrent.hash == hash)
.ok_or_else(|| anyhow::format_err!("no torrent for {hash}"))?;
Ok(t.files.clone())
}
async fn torrent_trackers(&self, _: crate::InfoHash)
-> anyhow::Result<Vec<crate::Tracker>>
{
Ok(self.trackers.clone())
}
async fn delete_torrents(&self, hashes: &[crate::InfoHash]) -> anyhow::Result<()> {
self.deleted.lock().unwrap().extend_from_slice(hashes);
Ok(())
}
}