1use async_trait::async_trait;
2
3mod cache;
4mod error;
5mod extractor;
6mod fetcher;
7mod github_types;
8mod logging;
9mod preview_generator;
10mod preview_service;
11mod utils;
12
13pub use cache::Cache;
14pub use error::PreviewError;
15pub use extractor::MetadataExtractor;
16pub use fetcher::{FetchResult, Fetcher, FetcherConfig};
17pub use logging::{log_error_card, log_preview_card, setup_logging, LogConfig, LogLevelGuard};
18pub use preview_generator::{CacheStrategy, UrlPreviewGenerator};
19pub use preview_service::{PreviewService, PreviewServiceConfig, MAX_CONCURRENT_REQUESTS};
20
21#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
22pub struct Preview {
23 pub url: String,
24 pub title: Option<String>,
25 pub description: Option<String>,
26 pub image_url: Option<String>,
27 pub favicon: Option<String>,
28 pub site_name: Option<String>,
29}
30
31#[async_trait]
32pub trait PreviewGenerator {
33 async fn generate_preview(&self, url: &str) -> Result<Preview, PreviewError>;
34}
35
36pub fn is_twitter_url(url: &str) -> bool {
37 url.contains("twitter.com") || url.contains("x.com")
38}