Files
pocket-chords/crates/infrastructure/ug-parser/src/fetcher.rs

60 lines
1.7 KiB
Rust

use async_trait::async_trait;
use domain::{FetchError, TabFetcherPort, TabSource};
pub struct UgTabFetcher {
client: reqwest::Client,
}
impl UgTabFetcher {
pub fn new() -> Self {
Self { client: reqwest::Client::new() }
}
}
impl Default for UgTabFetcher {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl TabFetcherPort for UgTabFetcher {
async fn fetch(&self, source: TabSource) -> Result<String, FetchError> {
match source {
TabSource::File(path) => {
Ok(tokio::fs::read_to_string(&path).await?)
}
TabSource::Url(url) => {
let resp = self.client.get(&url).send().await
.map_err(|e| FetchError::Network(e.to_string()))?;
let content_type = resp.headers()
.get(reqwest::header::CONTENT_TYPE)
.and_then(|v| v.to_str().ok())
.unwrap_or("");
if !content_type.contains("text/html") {
return Err(FetchError::InvalidContentType);
}
resp.text().await.map_err(|e| FetchError::Network(e.to_string()))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use domain::TabSource;
use std::path::PathBuf;
#[tokio::test]
async fn fetch_local_file() {
let fetcher = UgTabFetcher::new();
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent().unwrap().parent().unwrap().parent().unwrap()
.join("samples/A DROP IN THE OCEAN.html");
let html = fetcher.fetch(TabSource::File(path)).await.unwrap();
assert!(html.contains("[Chorus]"));
assert!(html.contains("data-name=\"Em\""));
}
}