1use alloc::format;
23use alloc::string::String;
24
25use plat::assoc::{self, AssocError, Conflict, Package};
26
27fn error_code(e: &AssocError) -> i32 {
28 match e {
29 AssocError::Unavailable | AssocError::Empty => 2,
30 _ => 1,
31 }
32}
33
34#[doc(hidden)]
36pub fn desk_boot(package: Option<&str>) -> Option<i32> {
37 assoc::package_set(package);
38 let args = plat::args();
39 let has = |o: &str| args.iter().skip(1).any(|a| a == o);
40 let headless = ["--shot", "--script"].iter().any(|o| plat::arg_value(o).is_some()) || has("--agent-json") || has("--agent-mcp");
42 if headless {
43 plat::recent::recent_os(false);
44 }
45 let Some(switch) = ["--unregister", "--register-replace", "--register"].into_iter().find(|s| has(s)) else {
46 assoc::app_id_boot();
47 return None;
48 };
49 let (code, text) = assoc_switch(&assoc::package(), switch)?;
50 assoc::console_print(&text);
51 Some(code)
52}
53
54pub fn assoc_switch(pkg: &Package, switch: &str) -> Option<(i32, String)> {
56 if switch == "--unregister" {
57 return Some(match assoc::assoc_unregister() {
58 Ok(true) => (0, String::from("unregistered: the file types and URL schemes are removed\n")),
59 Ok(false) => (0, String::from("nothing to unregister\n")),
60 Err(e) => (error_code(&e), format!("error: {e}\n")),
61 });
62 }
63 let replace = match switch {
64 "--register" => false,
65 "--register-replace" => true,
66 _ => return None,
67 };
68 let mut take = |_: &Conflict| replace;
69 Some(match assoc::assoc_register(pkg, &mut take) {
70 Ok(r) => {
71 let plural = |n: usize, one: &str, many: &str| format!("{n} {}", if n == 1 { one } else { many });
72 let mut out = format!("registered {}: {}, {}\n", r.exe, plural(r.types, "file type", "file types"), plural(r.schemes, "URL scheme", "URL schemes"));
73 for c in &r.kept {
74 let why = if c.fixed { "the user's choice in Windows' settings" } else { "--register-replace takes it" };
75 out.push_str(&format!("kept: {} stays with {} ({why})\n", c.what, c.holder));
76 }
77 for n in &r.notes {
78 out.push_str(&format!("note: {n}\n"));
79 }
80 (0, out)
81 }
82 Err(e) => {
83 let mut out = format!("error: {e}\n");
84 if let AssocError::Declined(_) = e {
85 out.push_str("(--register-replace moves it aside; --unregister puts it back)\n");
86 }
87 (error_code(&e), out)
88 }
89 })
90}