| 2163 | } |
| 2164 | |
| 2165 | fn simdeck_open_link( |
| 2166 | base: &str, |
| 2167 | udid: &str, |
| 2168 | addresses: &[PairingAddress], |
| 2169 | ) -> anyhow::Result<String> { |
| 2170 | let trimmed = base.trim().trim_end_matches('/'); |
| 2171 | if trimmed.is_empty() { |
| 2172 | anyhow::bail!("link base URL must not be empty"); |
| 2173 | } |
| 2174 | let primary = addresses |
| 2175 | .iter() |
| 2176 | .find(|address| address.kind != "local") |
| 2177 | .or_else(|| addresses.first()) |
| 2178 | .map(|address| address.url.as_str()) |
| 2179 | .context("No SimDeck server address is available")?; |
| 2180 | let mut url = format!( |
| 2181 | "{trimmed}/open?u={}&udid={}", |
| 2182 | percent_encode(&pairing_address_value(primary)), |
| 2183 | percent_encode(udid) |
| 2184 | ); |
| 2185 | for address in addresses |
| 2186 | .iter() |
| 2187 | .filter(|address| address.url != primary && address.kind != "local") |
| 2188 | { |
| 2189 | url.push_str("&a="); |
| 2190 | url.push_str(&percent_encode(&pairing_address_value(&address.url))); |
| 2191 | } |
| 2192 | Ok(url) |
| 2193 | } |
| 2194 | |
| 2195 | fn pairing_address_value(url: &str) -> String { |
| 2196 | let Ok(parsed) = url.parse::<http::Uri>() else { |