1use std::collections::HashMap;
5
6#[derive(Debug, Clone)]
8pub struct Descriptor {
9 pub name: String,
10 pub environment: HashMap<String, String>,
11 pub default: bool,
12 pub discrete: bool,
13}
14
15#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
17pub enum Preference {
18 #[default]
19 Default,
20 NonDefault,
21}
22
23impl Preference {
24 pub fn preferred(self, gpus: &[Descriptor]) -> Option<usize> {
26 let default_idx = gpus.iter().position(|gpu| gpu.default);
27 if matches!(self, Preference::Default) {
28 return default_idx;
29 }
30
31 let default_discrete = gpus.iter().position(|gpu| gpu.default && gpu.discrete);
32 if default_discrete.is_some() {
33 return default_discrete;
34 }
35
36 let non_default_discrete = gpus.iter().position(|gpu| gpu.discrete);
37 let non_default = || gpus.iter().position(|gpu| !gpu.default);
38 non_default_discrete.or_else(non_default).or(default_idx)
39 }
40
41 pub fn select(self, gpus: &[Descriptor]) -> Option<usize> {
43 if matches!(self, Preference::Default) {
44 return None;
45 }
46
47 let default_discrete = gpus.iter().position(|gpu| gpu.default && gpu.discrete);
48 if default_discrete.is_some() {
49 return None;
50 }
51
52 let non_default_discrete = gpus.iter().position(|gpu| gpu.discrete);
53 let non_default = || gpus.iter().position(|gpu| !gpu.default);
54 non_default_discrete.or_else(non_default)
55 }
56}