sim_lib_view_device/
profile_surface.rs1use sim_kernel::{Expr, Symbol};
4use sim_lib_view::SurfaceCaps;
5use sim_value::build;
6
7use crate::profile::{DeviceProfile, has_symbol};
8
9impl DeviceProfile {
10 pub fn to_surface_caps(&self, client_id: impl Into<String>) -> SurfaceCaps {
17 SurfaceCaps {
18 client_id: client_id.into(),
19 preset: Symbol::qualified("surface", self.kind.name.clone()),
20 display: display_map_from_profile(&self.display),
21 input: flags_map(&self.input),
22 output: flags_map(&self.output),
23 transport: transport_map_from_profile(&self.links),
24 privacy: self.policy.clone(),
25 rate: self.rate.to_expr(),
26 streams: flags_map(&self.streams),
27 codecs: vec![
28 Symbol::qualified("surface", "lisp"),
29 Symbol::qualified("surface", "json"),
30 ],
31 }
32 }
33}
34
35fn display_map_from_profile(symbols: &[Symbol]) -> Expr {
36 let mut entries = vec![(
37 Expr::Symbol(build::keyword("media")),
38 build::list(Vec::new()),
39 )];
40 if let Some(density) = first_named(symbols, &["glance", "compact", "regular", "dense"]) {
41 entries.push((
42 Expr::Symbol(build::keyword("density")),
43 Expr::Symbol(density),
44 ));
45 }
46 if let Some(shape) = first_named(symbols, &["round", "flat"]) {
47 entries.push((Expr::Symbol(build::keyword("shape")), Expr::Symbol(shape)));
48 }
49 if has_symbol(symbols, "stereo") {
50 entries.push((Expr::Symbol(build::keyword("stereo")), Expr::Bool(true)));
51 }
52 if has_symbol(symbols, "hud") {
53 entries.push((Expr::Symbol(build::keyword("lines")), build::uint(2)));
54 }
55 Expr::Map(entries)
56}
57
58fn flags_map(symbols: &[Symbol]) -> Expr {
59 Expr::Map(
60 symbols
61 .iter()
62 .map(|symbol| {
63 (
64 Expr::Symbol(Symbol::new(symbol.name.clone())),
65 Expr::Bool(true),
66 )
67 })
68 .collect(),
69 )
70}
71
72fn transport_map_from_profile(links: &[Symbol]) -> Expr {
73 let kind = links
74 .first()
75 .cloned()
76 .unwrap_or_else(|| Symbol::new("local"));
77 build::map(vec![
78 ("kind", Expr::Symbol(kind)),
79 (
80 "offline-queue",
81 Expr::Bool(has_symbol(links, "relay") || has_symbol(links, "phone-relay")),
82 ),
83 ("ordered", Expr::Bool(true)),
84 ("round-trip-ms", build::uint(1)),
85 ])
86}
87
88fn first_named(symbols: &[Symbol], names: &[&str]) -> Option<Symbol> {
89 names
90 .iter()
91 .find_map(|name| symbols.iter().find(|symbol| symbol.name.as_ref() == *name))
92 .cloned()
93}