1use std::collections::HashMap;
2use std::sync::Arc;
3use tokio::sync::RwLock;
4
5use crate::{ProbeResult, probe};
6
7#[derive(Debug, Clone)]
9pub struct ProbeCache {
10 cache: Arc<RwLock<HashMap<String, ProbeResult>>>,
11 engine: ProbeEngine,
12}
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum ProbeEngine {
17 Ffprobe,
19 #[cfg(feature = "revelo")]
21 Revelo,
22}
23
24impl ProbeCache {
25 pub fn new() -> Self {
27 Self { cache: Arc::default(), engine: ProbeEngine::Ffprobe }
28 }
29
30 #[cfg(feature = "revelo")]
32 pub fn with_revelo() -> Self {
33 Self { cache: Arc::default(), engine: ProbeEngine::Revelo }
34 }
35
36 pub fn with_engine(engine: ProbeEngine) -> Self {
38 Self { cache: Arc::default(), engine }
39 }
40
41 pub async fn probe(&self, path: &str) -> anyhow::Result<ProbeResult> {
43 {
44 let cache = self.cache.read().await;
45 if let Some(result) = cache.get(path) {
46 return Ok(result.clone());
47 }
48 }
49
50 let result = match self.engine {
51 ProbeEngine::Ffprobe => probe(path).await?,
52 #[cfg(feature = "revelo")]
53 ProbeEngine::Revelo => crate::probe_revelo(path).await?,
54 };
55
56 {
57 let mut cache = self.cache.write().await;
58 cache.insert(path.to_string(), result.clone());
59 }
60
61 Ok(result)
62 }
63}
64
65impl Default for ProbeCache {
66 fn default() -> Self {
67 Self::new()
68 }
69}