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)]
15pub enum ProbeEngine {
16 Ffprobe,
17 #[cfg(feature = "revelo")]
18 Revelo,
19}
20
21impl ProbeCache {
22 pub fn new() -> Self {
23 Self { cache: Arc::default(), engine: ProbeEngine::Ffprobe }
24 }
25
26 #[cfg(feature = "revelo")]
27 pub fn with_revelo() -> Self {
28 Self { cache: Arc::default(), engine: ProbeEngine::Revelo }
29 }
30
31 pub fn with_engine(engine: ProbeEngine) -> Self {
32 Self { cache: Arc::default(), engine }
33 }
34
35 pub async fn probe(&self, path: &str) -> anyhow::Result<ProbeResult> {
37 {
38 let cache = self.cache.read().await;
39 if let Some(result) = cache.get(path) {
40 return Ok(result.clone());
41 }
42 }
43
44 let result = match self.engine {
45 ProbeEngine::Ffprobe => probe(path).await?,
46 #[cfg(feature = "revelo")]
47 ProbeEngine::Revelo => crate::probe_revelo(path).await?,
48 };
49
50 {
51 let mut cache = self.cache.write().await;
52 cache.insert(path.to_string(), result.clone());
53 }
54
55 Ok(result)
56 }
57}
58
59impl Default for ProbeCache {
60 fn default() -> Self {
61 Self::new()
62 }
63}