#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LinkedInUrlKind {
Profile,
Company,
Post,
Pulse,
FeedUpdate,
Activity,
}
impl LinkedInUrlKind {
#[cfg(any(test, feature = "impersonate"))]
pub(super) fn has_oembed_fallback(self) -> bool {
matches!(self, Self::Post | Self::Pulse | Self::FeedUpdate)
}
pub(super) fn requires_auth(self) -> bool {
matches!(self, Self::Profile | Self::Company | Self::Activity)
}
}
#[must_use]
pub fn classify_linkedin_url(url: &str) -> Option<LinkedInUrlKind> {
let lower = url.to_lowercase();
let path = lower.split('?').next().unwrap_or(&lower);
if !path.contains("linkedin.com/") {
return None;
}
if path.contains("/recent-activity/") {
return Some(LinkedInUrlKind::Activity);
}
if path.contains("/feed/update/") {
return Some(LinkedInUrlKind::FeedUpdate);
}
if path.ends_with("/feed/") || path.ends_with("/feed") {
return Some(LinkedInUrlKind::Activity);
}
for section in &["/mynetwork/", "/jobs/", "/messaging/", "/notifications/"] {
if path.contains(section) {
return Some(LinkedInUrlKind::Activity);
}
}
if path.contains("/posts/") {
return Some(LinkedInUrlKind::Post);
}
if path.contains("/pulse/") {
return Some(LinkedInUrlKind::Pulse);
}
if path.contains("/company/") {
return Some(LinkedInUrlKind::Company);
}
if let Some(after) = path.split("/in/").nth(1) {
let segment = after.split('/').next().unwrap_or("");
if !segment.is_empty() {
return Some(LinkedInUrlKind::Profile);
}
}
None
}