psocks/src/rules/list/source.rs

49 lines
1.4 KiB
Rust

use anyhow::{Result, bail};
use std::{path::PathBuf, str::FromStr};
use url::Url;
pub enum Source {
Path(PathBuf),
Url(Url),
}
impl Source {
pub fn from_str(source: &str) -> Result<Self> {
Ok(if source.contains("://") {
Self::Url(Url::from_str(source)?)
} else {
Self::Path(PathBuf::from_str(source)?.canonicalize()?)
})
}
pub async fn get(&self) -> Result<String> {
Ok(match self {
Source::Path(path) => tokio::fs::read_to_string(path).await?,
Source::Url(url) => {
let request = url.as_str();
let response = reqwest::get(request).await?;
let status = response.status();
if status.is_success() {
response.text().await?
} else {
bail!("Could not receive remote list `{request}`: `{status}`")
}
}
})
}
}
impl FromStr for Source {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Source::from_str(s)
}
}
impl std::fmt::Display for Source {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Path(path) => write!(f, "{}", path.to_string_lossy()),
Self::Url(url) => write!(f, "{url}"),
}
}
}