1use crate::AniError;
2
3pub struct I18n {
4 locale: Locale,
5}
6
7pub enum Locale {
8 En,
9 }
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}