feat(domain): add TabFetcherPort and TabParserPort traits
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
pub mod note;
|
pub mod note;
|
||||||
pub mod chord;
|
pub mod chord;
|
||||||
pub mod song;
|
pub mod song;
|
||||||
|
pub mod ports;
|
||||||
|
|
||||||
pub use note::Note;
|
pub use note::Note;
|
||||||
pub use chord::Chord;
|
pub use chord::Chord;
|
||||||
pub use song::{ChordPosition, LyricLine, Section, SectionKind, SongMeta, Song};
|
pub use song::{ChordPosition, LyricLine, Section, SectionKind, SongMeta, Song};
|
||||||
|
pub use ports::{FetchError, ParseError, TabFetcherPort, TabParserPort, TabSource};
|
||||||
|
|||||||
37
crates/domain/src/ports.rs
Normal file
37
crates/domain/src/ports.rs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
use std::path::PathBuf;
|
||||||
|
use thiserror::Error;
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use crate::song::Song;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum TabSource {
|
||||||
|
File(PathBuf),
|
||||||
|
Url(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum FetchError {
|
||||||
|
#[error("IO error: {0}")]
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
#[error("Network error: {0}")]
|
||||||
|
Network(String),
|
||||||
|
#[error("Response is not HTML")]
|
||||||
|
InvalidContentType,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum ParseError {
|
||||||
|
#[error("Tab content not found in HTML")]
|
||||||
|
MissingContent,
|
||||||
|
#[error("Malformed HTML: {0}")]
|
||||||
|
MalformedHtml(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait TabFetcherPort: Send + Sync {
|
||||||
|
async fn fetch(&self, source: TabSource) -> Result<String, FetchError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait TabParserPort: Send + Sync {
|
||||||
|
fn parse(&self, html: &str) -> Result<Song, ParseError>;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user