Skip to main content

ani_lib/
i18n.rs

1use crate::AniError;
2
3pub struct I18n {
4    locale: Locale,
5}
6
7pub enum Locale {
8    En,
9    // Pl later
10}
11
12impl Default for I18n {
13    fn default() -> Self {
14        Self::new(Locale::En)
15    }
16}
17
18impl I18n {
19    pub fn new(locale: Locale) -> Self {
20        Self { locale }
21    }
22
23    pub fn error(&self, error: &AniError) -> String {
24        match self.locale {
25            Locale::En => self.error_en(error),
26        }
27    }
28
29    fn error_en(&self, error: &AniError) -> String {
30        const DOCS_TROUBLESHOOTING: &str =
31            "https://vorlie.github.io/ani-cli-rs/support/troubleshooting/";
32        match error {
33            AniError::Network(msg) => format!("Network request failed: {msg}"),
34            AniError::Provider(msg) => format!(
35                "Provider returned invalid data: {msg}\n\
36                 Help: {DOCS_TROUBLESHOOTING}#search-works-but-sources-fail"
37            ),
38            AniError::Catalog { provider, message } => {
39                format!(
40                    "{provider} catalog error: {message}\n\
41                     Help: {DOCS_TROUBLESHOOTING}#search-works-but-sources-fail"
42                )
43            }
44            AniError::ProviderRateLimited {
45                provider,
46                retry_after_seconds,
47            } => {
48                format!(
49                    "{provider} is rate limiting requests. Try again in {retry_after_seconds} seconds.\n\
50                     Help: {DOCS_TROUBLESHOOTING}#search-works-but-sources-fail"
51                )
52            }
53
54            AniError::Unavailable(msg) => format!("Episode unavailable: {msg}"),
55            AniError::Player(msg) => format!("Player failed: {msg}"),
56            AniError::Download(msg) => format!("Download failed: {msg}"),
57            AniError::History(msg) => format!("History operation failed: {msg}"),
58            AniError::Update(msg) => format!("Update failed: {msg}"),
59            AniError::Input(msg) => format!("Invalid input: {msg}"),
60
61            AniError::Io(msg) => format!("Could not access local data: {msg}"),
62            AniError::Json(msg) => format!("Could not process response data: {msg}"),
63            AniError::Url(msg) => format!("Invalid URL: {msg}"),
64
65            AniError::DownloadNoDownloader => format!(
66                "HLS downloads require yt-dlp or FFmpeg to be installed and available in PATH.\n\
67                Help: {DOCS_TROUBLESHOOTING}#mpv-vlc-syncplay-aria2c-yt-dlp-or-ffmpeg-not-found"
68            ),
69            AniError::DownloadFailed => format!(
70                "HLS download failed.\n\
71                Help: {DOCS_TROUBLESHOOTING}#part-remains-after-a-download"
72            ),
73
74            AniError::HistoryStateDirectory => {
75                "Could not determine where to store history data.".to_string()
76            }
77
78            AniError::PlayerNotFound => format!(
79                "Player executable not found. Make sure your configured player is installed.\n\
80                Help: {DOCS_TROUBLESHOOTING}#mpv-vlc-syncplay-aria2c-yt-dlp-or-ffmpeg-not-found"
81            ),
82
83            AniError::PlayerLaunchFailed => format!(
84                "Could not launch the player.\n\
85                Help: {DOCS_TROUBLESHOOTING}#mpv-vlc-syncplay-aria2c-yt-dlp-or-ffmpeg-not-found"
86            ),
87
88            AniError::PlayerExitFailed => format!(
89                "Player exited with an error.\n\
90                Help: {DOCS_TROUBLESHOOTING}#mpv-vlc-syncplay-aria2c-yt-dlp-or-ffmpeg-not-found"
91            ),
92
93            AniError::PlayerAndroidTerminalRequired => format!(
94                "Android HLS playback requires an interactive Termux terminal.\n\
95                Help: {DOCS_TROUBLESHOOTING}#termux-playback-stops-after-returning-to-the-terminal"
96            ),
97
98            AniError::InputSelectionOutOfRange => "Selection is out of range.".to_string(),
99
100            AniError::InputEmptyQuery => "Search query cannot be empty.".to_string(),
101
102            AniError::InputInvalidEpisode => "Invalid episode selection.".to_string(),
103
104            AniError::InputRequiresQuery => "This command requires an anime query.".to_string(),
105
106            AniError::UnavailableNoResults => "No results found.".to_string(),
107
108            AniError::UnavailableNoStreams => format!(
109                "No streams are available for this episode.\n\
110                Help: {DOCS_TROUBLESHOOTING}#search-works-but-sources-fail"
111            ),
112
113            AniError::UnavailableNoEpisodes => format!(
114                "No episodes are available.\n\
115                Help: {DOCS_TROUBLESHOOTING}#search-works-but-sources-fail"
116            ),
117        }
118    }
119}