feat(ug-parser): implement UgTabFetcher for file and URL sources
This commit is contained in:
@@ -1 +1,53 @@
|
||||
pub struct UgTabFetcher;
|
||||
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() }
|
||||
}
|
||||
}
|
||||
|
||||
#[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\""));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user