68 lines
2.3 KiB
Rust
68 lines
2.3 KiB
Rust
use std::str::FromStr;
|
|
use thiserror::Error;
|
|
use url::Url;
|
|
|
|
#[derive(Error, Debug)]
|
|
pub enum ParseLinkError {
|
|
#[error("Could not parse valid link")]
|
|
InvalidLink,
|
|
|
|
#[error("Unexpected host")]
|
|
UnknownHostError,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum Link {
|
|
E621Post { post: u32 },
|
|
E621Pool { pool: u32 },
|
|
}
|
|
|
|
impl FromStr for Link {
|
|
type Err = ParseLinkError;
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
let url = Url::from_str(s).map_err(|_| return ParseLinkError::InvalidLink)?;
|
|
|
|
if let Some(domain) = url.domain() {
|
|
match domain {
|
|
"www.e621.net" | "e621.net" | "www.e926.net" | "e926.net" => {
|
|
if let Some(mut path_segments) = url.path_segments() {
|
|
let first_segment = path_segments.next();
|
|
if first_segment.is_none() {
|
|
return Err(ParseLinkError::InvalidLink);
|
|
}
|
|
let first_segment = first_segment.unwrap();
|
|
|
|
let last_segment = path_segments.last();
|
|
if last_segment.is_none() {
|
|
return Err(ParseLinkError::InvalidLink);
|
|
}
|
|
let last_segment = last_segment.unwrap();
|
|
|
|
match first_segment {
|
|
"post" | "posts" => {
|
|
if let Ok(post) = u32::from_str(last_segment) {
|
|
return Ok(Link::E621Post { post });
|
|
}
|
|
}
|
|
"pools" => {
|
|
if let Ok(pool) = u32::from_str(last_segment) {
|
|
return Ok(Link::E621Pool { pool });
|
|
}
|
|
}
|
|
_ => {
|
|
println!("e621 first segment: {first_segment}");
|
|
}
|
|
}
|
|
}
|
|
return Err(ParseLinkError::UnknownHostError);
|
|
}
|
|
_ => {
|
|
return Err(ParseLinkError::UnknownHostError);
|
|
}
|
|
}
|
|
} else {
|
|
return Err(ParseLinkError::UnknownHostError);
|
|
}
|
|
}
|
|
}
|