adblock-list-compiler 0.0.8

CLI tool to compile multiple adblock list sources into a single file
Documentation
use std::path::PathBuf;
use std::str::FromStr;

use thiserror::Error;
use url::Url;

use crate::{
    config::ConfigUrl,
    fetch::{Fetch, FetchError},
};

#[derive(Debug)]
pub struct FetchSource(Fetch);

#[derive(Error, Debug)]
#[error("FetchSourceError: {0}")]
pub struct FetchSourceError(#[from] FetchError);

#[derive(Error, Debug)]
pub enum FetchSourceInitError {
    #[error("InvalidUrl: {0}")]
    InvalidUrl(#[from] url::ParseError),

    #[error("InvalidPath")]
    InvalidPath,

    #[error("FileNotExists")]
    FileNotExists,

    #[error("Infallible")]
    Infallible(#[from] core::convert::Infallible),
}

impl FetchSource {
    pub fn try_from(
        source_path: &str,
        config_url: &ConfigUrl,
    ) -> Result<Self, FetchSourceInitError> {
        if source_path.starts_with("http") {
            let url = Url::parse(source_path)?;
            Ok(Self(url.into()))
        } else if source_path.starts_with("./") {
            match config_url {
                ConfigUrl::Url(u) => {
                    let url = u.join(source_path)?;
                    Ok(Self(url.into()))
                }
                ConfigUrl::File(p) => {
                    let path = p
                        .parent()
                        .ok_or(FetchSourceInitError::InvalidPath)?
                        .join(source_path);
                    if path.exists() {
                        Ok(Self(path.into()))
                    } else {
                        Err(FetchSourceInitError::FileNotExists)
                    }
                }
            }
        } else {
            let path = PathBuf::from_str(source_path)?;
            if path.exists() {
                Ok(Self(path.into()))
            } else {
                Err(FetchSourceInitError::FileNotExists)
            }
        }
    }

    pub async fn fetch(&self) -> Result<String, FetchSourceError> {
        Ok(self.0.fetch().await?)
    }
}