Initial commit.
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
use std::fmt;
|
||||
use std::fmt::Debug;
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use url::Url;
|
||||
|
||||
pub mod server;
|
||||
pub mod tls;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GeminiUrl {
|
||||
pub scheme: String,
|
||||
pub hostname: String,
|
||||
pub port: u16,
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for GeminiUrl {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}://{}:{}{}",
|
||||
self.scheme, self.hostname, self.port, self.path
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl GeminiUrl {
|
||||
/// Default scheme: "gemini://"
|
||||
/// Port: 1965
|
||||
/// Path: "/"
|
||||
pub fn new(input: &str) -> Result<GeminiUrl> {
|
||||
let input_with_scheme = if input.contains("://") {
|
||||
input.to_string()
|
||||
} else {
|
||||
format!("gemini://{}", input)
|
||||
};
|
||||
let parsed = Url::parse(&input_with_scheme)
|
||||
.with_context(|| format!("Invalid request URL {}", &input_with_scheme))?;
|
||||
if parsed.scheme() != "gemini" {
|
||||
return Err(anyhow!(
|
||||
"Invalid request (URL protocol should be gemini://)"
|
||||
));
|
||||
}
|
||||
let hostname = parsed
|
||||
.host_str()
|
||||
.ok_or_else(|| anyhow!("Invalid request (URL must have a host)"))?;
|
||||
let mut parsed = GeminiUrl {
|
||||
scheme: parsed.scheme().to_string(),
|
||||
hostname: hostname.to_string(),
|
||||
port: parsed.port().unwrap_or(1965),
|
||||
path: parsed.path().to_string(),
|
||||
};
|
||||
if parsed.path.is_empty() {
|
||||
parsed.path = String::from("/")
|
||||
};
|
||||
Ok(parsed)
|
||||
}
|
||||
|
||||
pub fn to_url(&self) -> Url {
|
||||
Url::parse(&self.to_string()).unwrap()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user