f323ba1
use crate::parse::{EmbedRule, Platform};
use crate::Category;
pub struct Googlemaps;
impl Platform for Googlemaps {
fn id(&self) -> &'static str {
"googlemaps"
}
fn name(&self) -> &'static str {
"Google Maps"
}
fn category(&self) -> Category {
Category::Dev
}
fn domains(&self) -> &'static [&'static str] {
&["maps.google.com", "google.com", "maps.app.goo.gl"]
}
fn embed_rule(&self) -> Option<EmbedRule> {
// 原实现把整个 URL 塞进 `q=`,生成 `?q=https%3A%2F%2Fmaps.google.com…`
// 这种自我嵌套的地址。这里只取原 URL 的 `q` 参数,其余形态交给 `parse`。
Some(EmbedRule::capture(
r"[?&]q=([^&]+)",
"https://maps.google.com/maps?q={id}&output=embed",
crate::Aspect::Wide,
))
}
/// `/maps/place/<名字>` 与 `/maps/@lat,lng,zoom` 各自取对参数;
/// `google.com` 只在 `/maps` 路径上认领,否则搜索/邮箱/云盘会被误判成地图。
fn parse(&self, url: &url::Url) -> Option<crate::Resolved> {
use crate::parse::{capture_args, default_parse, platform_resolved};
use crate::EmbedKind;
let host = url.host_str().unwrap_or_default();
let host_owned = host.trim_start_matches("www.");
// `maps.app.goo.gl` 是短链:落地地址由 chat 的重定向跟随补上,
// 这里先按卡片出,避免把短链本身当坐标。
let on_map_host = host_owned.starts_with("maps.google.");
if host_owned.starts_with("maps.app.goo.gl") {
return Some(platform_resolved(
self,
url,
EmbedKind::Link,
None,
crate::Aspect::Auto,
));
}
if !on_map_host && !url.path().starts_with("/maps") {
// 非地图路径:让这条链接走普通卡片,别贴 Google Maps 的标签。
return None;
}
if let Some(caps) = capture_args(r"^/maps/place/([^/@]+)", url) {
let place: String = url::form_urlencoded::byte_serialize(caps[0].as_bytes()).collect();
return Some(platform_resolved(
self,
url,
EmbedKind::Iframe,
Some(format!("https://maps.google.com/maps?q={place}&output=embed")),
crate::Aspect::Wide,
));
}
if let Some(caps) = capture_args(r"^/maps/@(-?\d+\.\d+),(-?\d+\.\d+)", url) {
return Some(platform_resolved(
self,
url,
EmbedKind::Iframe,
Some(format!(
"https://maps.google.com/maps?q={},{}&output=embed",
caps[0], caps[1]
)),
crate::Aspect::Wide,
));
}
default_parse(self, url)
}
}
pub static PLATFORM: Googlemaps = Googlemaps;