Skip to main content

discord_proxy/discord/
mod.rs

1use anyhow::Result;
2use std::{fmt, path::Path, str::FromStr};
3
4#[cfg(windows)]
5mod windows;
6
7#[cfg(windows)]
8pub use windows::{
9    DiscordInstall, InstallCandidateReport, LaunchPlan, discover_install, inspect_candidates,
10    is_process_running,
11};
12
13#[cfg(not(windows))]
14mod unsupported {
15    use super::DiscordChannel;
16    use anyhow::{Result, bail};
17    use std::path::Path;
18    use tokio::process::Child;
19
20    #[derive(Debug)]
21    pub struct DiscordInstall;
22
23    #[derive(Debug)]
24    pub struct InstallCandidateReport;
25
26    pub struct LaunchPlan;
27
28    impl DiscordInstall {
29        pub fn source(&self) -> &str {
30            ""
31        }
32
33        pub fn channel(&self) -> DiscordChannel {
34            DiscordChannel::Stable
35        }
36
37        pub fn root(&self) -> &Path {
38            Path::new("")
39        }
40
41        pub fn app_dir(&self) -> &Path {
42            Path::new("")
43        }
44
45        pub fn update_exe(&self) -> Option<&Path> {
46            None
47        }
48
49        pub fn exe_path(&self) -> &Path {
50            Path::new("")
51        }
52
53        pub fn exe_name(&self) -> &str {
54            ""
55        }
56    }
57
58    impl LaunchPlan {
59        pub fn new(_install: DiscordInstall, _proxy_url: String) -> Self {
60            Self
61        }
62
63        pub fn describe(&self) -> String {
64            "this MVP currently supports Windows launch plans only".to_string()
65        }
66
67        pub fn spawn(&self) -> Result<Child> {
68            bail!("this MVP currently supports Windows launch plans only")
69        }
70    }
71
72    pub fn discover_install(
73        _channel: DiscordChannel,
74        _override_dir: Option<&Path>,
75    ) -> Result<DiscordInstall> {
76        bail!("this MVP currently supports Windows Discord discovery only")
77    }
78
79    pub fn inspect_candidates(
80        _channel: DiscordChannel,
81        _override_dir: Option<&Path>,
82    ) -> Vec<InstallCandidateReport> {
83        Vec::new()
84    }
85
86    pub fn is_process_running(_exe_name: &str) -> bool {
87        false
88    }
89}
90
91#[cfg(not(windows))]
92pub use unsupported::{
93    DiscordInstall, InstallCandidateReport, LaunchPlan, discover_install, inspect_candidates,
94    is_process_running,
95};
96
97#[derive(Debug, Clone, Copy, Eq, PartialEq)]
98pub enum DiscordChannel {
99    Stable,
100    Canary,
101    Ptb,
102    Development,
103}
104
105impl DiscordChannel {
106    pub fn valid_values() -> &'static [&'static str] {
107        &["stable", "canary", "ptb", "development"]
108    }
109
110    pub fn install_dir_name(self) -> &'static str {
111        match self {
112            Self::Stable => "Discord",
113            Self::Canary => "DiscordCanary",
114            Self::Ptb => "DiscordPTB",
115            Self::Development => "DiscordDevelopment",
116        }
117    }
118
119    pub fn exe_candidates(self) -> &'static [&'static str] {
120        match self {
121            Self::Stable => &["Discord.exe"],
122            Self::Canary => &["DiscordCanary.exe"],
123            Self::Ptb => &["DiscordPTB.exe"],
124            Self::Development => &["DiscordDevelopment.exe"],
125        }
126    }
127}
128
129impl FromStr for DiscordChannel {
130    type Err = anyhow::Error;
131
132    fn from_str(value: &str) -> Result<Self> {
133        match value.trim().to_ascii_lowercase().as_str() {
134            "stable" | "discord" => Ok(Self::Stable),
135            "canary" | "discordcanary" => Ok(Self::Canary),
136            "ptb" | "discordptb" => Ok(Self::Ptb),
137            "development" | "dev" | "discorddevelopment" => Ok(Self::Development),
138            other => anyhow::bail!("unsupported Discord channel: {other}"),
139        }
140    }
141}
142
143impl fmt::Display for DiscordChannel {
144    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
145        let value = match self {
146            Self::Stable => "stable",
147            Self::Canary => "canary",
148            Self::Ptb => "ptb",
149            Self::Development => "development",
150        };
151        formatter.write_str(value)
152    }
153}
154
155#[allow(dead_code)]
156pub fn discover(_channel: DiscordChannel, _override_dir: Option<&Path>) -> Result<DiscordInstall> {
157    discover_install(_channel, _override_dir)
158}