Skip to main content

dkdc_rs/
open.rs

1use anyhow::{Context, Result};
2use std::sync::Arc;
3use tokio::sync::Semaphore;
4
5use crate::config::Config;
6
7pub fn alias_or_thing_to_uri(thing: &str, config: &Config) -> Result<String> {
8    // Check if it's an alias first
9    if let Some(alias_target) = config.aliases.get(thing) {
10        // Now check if the alias target is in things
11        if let Some(uri) = config.things.get(alias_target) {
12            return Ok(uri.clone());
13        }
14    }
15
16    // Check if it's directly in things
17    if let Some(uri) = config.things.get(thing) {
18        return Ok(uri.clone());
19    }
20
21    anyhow::bail!("'{}' not found in [things] or [aliases]", thing)
22}
23
24fn open_it(thing: &str) -> Result<()> {
25    open::that(thing).with_context(|| format!("failed to open {}", thing))?;
26    println!("opening {}...", thing);
27    Ok(())
28}
29
30pub async fn open_things(
31    things: Vec<String>,
32    max_workers: usize,
33    config: Arc<Config>,
34) -> Result<()> {
35    let num_cpus = num_cpus::get();
36    let max_workers = if max_workers == 0 || max_workers > num_cpus {
37        num_cpus
38    } else {
39        max_workers
40    };
41
42    let semaphore = Arc::new(Semaphore::new(max_workers));
43    let mut handles = vec![];
44
45    for thing in things {
46        let permit = semaphore.clone().acquire_owned().await?;
47        let config = config.clone();
48
49        let handle = tokio::spawn(async move {
50            let _permit = permit;
51
52            match alias_or_thing_to_uri(&thing, &config) {
53                Ok(uri) => {
54                    if let Err(e) = open_it(&uri) {
55                        eprintln!("[dkdc] failed to open {}: {}", thing, e);
56                    }
57                }
58                Err(e) => {
59                    eprintln!("[dkdc] skipping {}: {}", thing, e);
60                }
61            }
62        });
63
64        handles.push(handle);
65    }
66
67    // Wait for all tasks to complete
68    for handle in handles {
69        handle.await?;
70    }
71
72    Ok(())
73}