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