aboutsummaryrefslogtreecommitdiffstats
path: root/crates
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-07-10 16:58:59 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-07-10 16:58:59 +0200
commitc3abafd4878df886dc8765a048cb0b70f282f1f3 (patch)
tree24d5bb2a35d99f7206ba619609e652dffc1c5d17 /crates
parentdocs(crates/libmpv2): Correctly format doc-test (diff)
downloadyt-c3abafd4878df886dc8765a048cb0b70f282f1f3.zip
refactor(crates/yt): Make every `pub` item `pub(crate)`
Otherwise, rust will not warn use about unused code (and `yt` is not a library).
Diffstat (limited to '')
-rw-r--r--crates/yt/src/ansi_escape_codes.rs15
-rw-r--r--crates/yt/src/app.rs8
-rw-r--r--crates/yt/src/cache/mod.rs7
-rw-r--r--crates/yt/src/cli.rs67
-rw-r--r--crates/yt/src/comments/comment.rs61
-rw-r--r--crates/yt/src/comments/description.rs5
-rw-r--r--crates/yt/src/comments/display.rs2
-rw-r--r--crates/yt/src/comments/mod.rs2
-rw-r--r--crates/yt/src/comments/output.rs8
-rw-r--r--crates/yt/src/constants.rs2
-rw-r--r--crates/yt/src/download/download_options.rs7
-rw-r--r--crates/yt/src/download/mod.rs10
-rw-r--r--crates/yt/src/download/progress_hook.rs11
-rw-r--r--crates/yt/src/main.rs34
-rw-r--r--crates/yt/src/select/cmds/add.rs2
-rw-r--r--crates/yt/src/select/mod.rs8
-rw-r--r--crates/yt/src/select/selection_file/duration.rs22
-rw-r--r--crates/yt/src/select/selection_file/mod.rs4
-rw-r--r--crates/yt/src/status/mod.rs12
-rw-r--r--crates/yt/src/storage/migrate/mod.rs22
-rw-r--r--crates/yt/src/storage/mod.rs6
-rw-r--r--crates/yt/src/subscribe/mod.rs11
-rw-r--r--crates/yt/src/update/mod.rs4
-rw-r--r--crates/yt/src/update/updater.rs2
-rw-r--r--crates/yt/src/version/mod.rs2
-rw-r--r--crates/yt/src/videos/display/format_video.rs7
-rw-r--r--crates/yt/src/videos/display/mod.rs50
-rw-r--r--crates/yt/src/videos/mod.rs8
-rw-r--r--crates/yt/src/watch/mod.rs2
-rw-r--r--crates/yt/src/watch/playlist.rs2
-rw-r--r--crates/yt/src/watch/playlist_handler/mod.rs4
31 files changed, 205 insertions, 202 deletions
diff --git a/crates/yt/src/ansi_escape_codes.rs b/crates/yt/src/ansi_escape_codes.rs
index 462a126..4528bd0 100644
--- a/crates/yt/src/ansi_escape_codes.rs
+++ b/crates/yt/src/ansi_escape_codes.rs
@@ -10,10 +10,10 @@
// see: https://en.wikipedia.org/wiki/ANSI_escape_code#Control_Sequence_Introducer_commands
const CSI: &str = "\x1b[";
-pub fn erase_in_display_from_cursor() {
+pub(crate) fn erase_in_display_from_cursor() {
print!("{CSI}0J");
}
-pub fn cursor_up(number: usize) {
+pub(crate) fn cursor_up(number: usize) {
// HACK(@bpeetz): The default is `1` and running this command with a
// number of `0` results in it using the default (i.e., `1`) <2025-03-25>
if number != 0 {
@@ -21,16 +21,9 @@ pub fn cursor_up(number: usize) {
}
}
-pub fn clear_whole_line() {
+pub(crate) fn clear_whole_line() {
eprint!("{CSI}2K");
}
-pub fn move_to_col(x: usize) {
+pub(crate) fn move_to_col(x: usize) {
eprint!("{CSI}{x}G");
}
-
-pub fn hide_cursor() {
- eprint!("{CSI}?25l");
-}
-pub fn show_cursor() {
- eprint!("{CSI}?25h");
-}
diff --git a/crates/yt/src/app.rs b/crates/yt/src/app.rs
index 15a9388..3ea12a4 100644
--- a/crates/yt/src/app.rs
+++ b/crates/yt/src/app.rs
@@ -16,13 +16,13 @@ use sqlx::{SqlitePool, sqlite::SqliteConnectOptions};
use crate::{config::Config, storage::migrate::migrate_db};
#[derive(Debug)]
-pub struct App {
- pub database: SqlitePool,
- pub config: Config,
+pub(crate) struct App {
+ pub(crate) database: SqlitePool,
+ pub(crate) config: Config,
}
impl App {
- pub async fn new(config: Config, should_migrate_db: bool) -> Result<Self> {
+ pub(crate) async fn new(config: Config, should_migrate_db: bool) -> Result<Self> {
let options = SqliteConnectOptions::new()
.filename(&config.paths.database_path)
.optimize_on_close(true, None)
diff --git a/crates/yt/src/cache/mod.rs b/crates/yt/src/cache/mod.rs
index 83d5ee0..589c6ba 100644
--- a/crates/yt/src/cache/mod.rs
+++ b/crates/yt/src/cache/mod.rs
@@ -55,7 +55,7 @@ async fn invalidate_video(app: &App, video: &Video, hard: bool) -> Result<()> {
Ok(())
}
-pub async fn invalidate(app: &App, hard: bool) -> Result<()> {
+pub(crate) async fn invalidate(app: &App, hard: bool) -> Result<()> {
let all_cached_things = get::videos(app, &[VideoStatusMarker::Cached]).await?;
info!("Got videos to invalidate: '{}'", all_cached_things.len());
@@ -67,14 +67,13 @@ pub async fn invalidate(app: &App, hard: bool) -> Result<()> {
Ok(())
}
-/// # Panics
-/// Only if internal assertions fail.
-pub async fn maintain(app: &App, all: bool) -> Result<()> {
let domain = if all {
VideoStatusMarker::ALL.as_slice()
} else {
&[VideoStatusMarker::Watch, VideoStatusMarker::Cached]
};
+/// Remove the cache paths from the db, that no longer exist on the file system.
+pub(crate) async fn maintain(app: &App, all: bool) -> Result<()> {
let cached_videos = get::videos(app, domain).await?;
diff --git a/crates/yt/src/cli.rs b/crates/yt/src/cli.rs
index 98bbb2d..e30f5f7 100644
--- a/crates/yt/src/cli.rs
+++ b/crates/yt/src/cli.rs
@@ -18,7 +18,6 @@ use std::{
};
use anyhow::Context;
-use bytes::Bytes;
use chrono::NaiveDate;
use clap::{ArgAction, Args, Parser, Subcommand, ValueEnum};
use clap_complete::{ArgValueCompleter, CompletionCandidate};
@@ -29,6 +28,7 @@ use crate::{
app::App,
config::Config,
select::selection_file::duration::MaybeDuration,
+ shared::bytes::Bytes,
storage::{subscriptions, video_database::extractor_hash::LazyExtractorHash},
};
@@ -36,44 +36,44 @@ use crate::{
#[clap(author, about, long_about = None)]
#[allow(clippy::module_name_repetitions)]
/// An command line interface to select, download and watch videos
-pub struct CliArgs {
+pub(crate) struct CliArgs {
#[command(subcommand)]
/// The subcommand to execute [default: select]
- pub command: Option<Command>,
+ pub(crate) command: Option<Command>,
/// Show the version and exit
#[arg(long, short = 'V', action= ArgAction::SetTrue)]
- pub version: bool,
+ pub(crate) version: bool,
/// Do not perform database migration before starting.
/// Setting this could cause runtime database access errors.
#[arg(long, short, action=ArgAction::SetTrue, default_value_t = false)]
- pub no_migrate_db: bool,
+ pub(crate) no_migrate_db: bool,
/// Display colors [defaults to true, if the config file has no value]
#[arg(long, short = 'C')]
- pub color: Option<bool>,
+ pub(crate) color: Option<bool>,
/// Set the path to the videos.db. This overrides the default and the config file.
#[arg(long, short)]
- pub db_path: Option<PathBuf>,
+ pub(crate) db_path: Option<PathBuf>,
/// Set the path to the config.toml.
/// This overrides the default.
#[arg(long, short)]
- pub config_path: Option<PathBuf>,
+ pub(crate) config_path: Option<PathBuf>,
/// Increase message verbosity
#[arg(long="verbose", short = 'v', action = ArgAction::Count)]
- pub verbosity: u8,
+ pub(crate) verbosity: u8,
/// Silence all output
#[arg(long, short = 'q')]
- pub quiet: bool,
+ pub(crate) quiet: bool,
}
#[derive(Subcommand, Debug)]
-pub enum Command {
+pub(crate) enum Command {
/// Download and cache URLs
Download {
/// Forcefully re-download all cached videos (i.e. delete the cache path, then download).
@@ -189,7 +189,7 @@ impl Default for Command {
}
#[derive(Subcommand, Clone, Debug)]
-pub enum VideosCommand {
+pub(crate) enum VideosCommand {
/// List the videos in the database
#[command(visible_alias = "ls")]
List {
@@ -206,11 +206,16 @@ pub enum VideosCommand {
Info {
/// The short hash of the video
hash: LazyExtractorHash,
+
+ /// The format string to use.
+ // TODO(@bpeetz): Encode the default format, as the default string here. <2025-07-04>
+ #[arg(short, long)]
+ format: Option<String>,
},
}
#[derive(Subcommand, Clone, Debug)]
-pub enum SubscriptionCommand {
+pub(crate) enum SubscriptionCommand {
/// Subscribe to an URL
Add {
#[arg(short, long)]
@@ -247,35 +252,35 @@ pub enum SubscriptionCommand {
#[derive(Clone, Debug, Args)]
#[command(infer_subcommands = true)]
/// Mark the video given by the hash to be watched
-pub struct SharedSelectionCommandArgs {
+pub(crate) struct SharedSelectionCommandArgs {
/// The ordering priority (higher means more at the top)
#[arg(short, long)]
- pub priority: Option<i64>,
+ pub(crate) priority: Option<i64>,
/// The subtitles to download (e.g. 'en,de,sv')
#[arg(short = 'l', long)]
- pub subtitle_langs: Option<String>,
+ pub(crate) subtitle_langs: Option<String>,
/// The speed to set mpv to
#[arg(short, long)]
- pub speed: Option<f64>,
+ pub(crate) speed: Option<f64>,
/// The short extractor hash
- pub hash: LazyExtractorHash,
+ pub(crate) hash: LazyExtractorHash,
- pub title: Option<String>,
+ pub(crate) title: Option<String>,
- pub date: Option<OptionalNaiveDate>,
+ pub(crate) date: Option<OptionalNaiveDate>,
- pub publisher: Option<OptionalPublisher>,
+ pub(crate) publisher: Option<OptionalPublisher>,
- pub duration: Option<MaybeDuration>,
+ pub(crate) duration: Option<MaybeDuration>,
- pub url: Option<Url>,
+ pub(crate) url: Option<Url>,
}
#[derive(Clone, Debug, Copy)]
-pub struct OptionalNaiveDate {
- pub date: Option<NaiveDate>,
+pub(crate) struct OptionalNaiveDate {
+ pub(crate) date: Option<NaiveDate>,
}
impl FromStr for OptionalNaiveDate {
type Err = anyhow::Error;
@@ -290,8 +295,8 @@ impl FromStr for OptionalNaiveDate {
}
}
#[derive(Clone, Debug)]
-pub struct OptionalPublisher {
- pub publisher: Option<String>,
+pub(crate) struct OptionalPublisher {
+ pub(crate) publisher: Option<String>,
}
impl FromStr for OptionalPublisher {
type Err = anyhow::Error;
@@ -307,7 +312,7 @@ impl FromStr for OptionalPublisher {
}
#[derive(Default, ValueEnum, Clone, Copy, Debug)]
-pub enum SelectSplitSortKey {
+pub(crate) enum SelectSplitSortKey {
/// Sort by the name of the publisher.
#[default]
Publisher,
@@ -325,7 +330,7 @@ impl Display for SelectSplitSortKey {
}
#[derive(Default, ValueEnum, Clone, Copy, Debug)]
-pub enum SelectSplitSortMode {
+pub(crate) enum SelectSplitSortMode {
/// Sort in ascending order (small -> big)
#[default]
Asc,
@@ -346,7 +351,7 @@ impl Display for SelectSplitSortMode {
#[derive(Subcommand, Clone, Debug)]
// NOTE: Keep this in sync with the [`constants::HELP_STR`] constant. <2024-08-20>
// NOTE: Also keep this in sync with the `tree-sitter-yts/grammar.js`. <2024-11-04>
-pub enum SelectCommand {
+pub(crate) enum SelectCommand {
/// Open a `git rebase` like file to select the videos to watch (the default)
File {
/// Include done (watched, dropped) videos
@@ -436,7 +441,7 @@ impl Default for SelectCommand {
}
#[derive(Subcommand, Clone, Copy, Debug)]
-pub enum CacheCommand {
+pub(crate) enum CacheCommand {
/// Invalidate all cache entries
Invalidate {
/// Also delete the cache path
diff --git a/crates/yt/src/comments/comment.rs b/crates/yt/src/comments/comment.rs
index 5bc939c..d9e3036 100644
--- a/crates/yt/src/comments/comment.rs
+++ b/crates/yt/src/comments/comment.rs
@@ -44,8 +44,8 @@ impl From<String> for Parent {
#[derive(Debug, Deserialize, Serialize, Clone, Eq, PartialEq, PartialOrd, Ord)]
#[serde(from = "String")]
#[serde(deny_unknown_fields)]
-pub struct Id {
- pub id: String,
+pub(crate) struct Id {
+ pub(crate) id: String,
}
impl From<String> for Id {
fn from(value: String) -> Self {
@@ -58,26 +58,26 @@ impl From<String> for Id {
#[derive(Debug, Deserialize, Serialize, Clone, Eq, PartialEq, PartialOrd, Ord)]
#[allow(clippy::struct_excessive_bools)]
-pub struct Comment {
- pub id: Id,
- pub text: String,
+pub(crate) struct Comment {
+ pub(crate) id: Id,
+ pub(crate) text: String,
#[serde(default = "zero")]
- pub like_count: u32,
- pub is_pinned: bool,
- pub author_id: String,
+ pub(crate) like_count: u32,
+ pub(crate) is_pinned: bool,
+ pub(crate) author_id: String,
#[serde(default = "unknown")]
- pub author: String,
- pub author_is_verified: bool,
- pub author_thumbnail: Url,
- pub parent: Parent,
+ pub(crate) author: String,
+ pub(crate) author_is_verified: bool,
+ pub(crate) author_thumbnail: Url,
+ pub(crate) parent: Parent,
#[serde(deserialize_with = "edited_from_time_text", alias = "_time_text")]
- pub edited: bool,
+ pub(crate) edited: bool,
// Can't also be deserialized, as it's already used in 'edited'
// _time_text: String,
- pub timestamp: i64,
- pub author_url: Option<Url>,
- pub author_is_uploader: bool,
- pub is_favorited: bool,
+ pub(crate) timestamp: i64,
+ pub(crate) author_url: Option<Url>,
+ pub(crate) author_is_uploader: bool,
+ pub(crate) is_favorited: bool,
}
fn unknown() -> String {
@@ -100,46 +100,37 @@ where
#[derive(Debug, Clone)]
#[allow(clippy::module_name_repetitions)]
-pub struct CommentExt {
- pub value: Comment,
- pub replies: Vec<CommentExt>,
+pub(crate) struct CommentExt {
+ pub(crate) value: Comment,
+ pub(crate) replies: Vec<CommentExt>,
}
#[derive(Debug, Default)]
-pub struct Comments {
+pub(crate) struct Comments {
pub(super) vec: Vec<CommentExt>,
}
impl Comments {
- pub fn new() -> Self {
+ pub(crate) fn new() -> Self {
Self::default()
}
- pub fn push(&mut self, value: CommentExt) {
+ pub(crate) fn push(&mut self, value: CommentExt) {
self.vec.push(value);
}
- pub fn get_mut(&mut self, key: &str) -> Option<&mut CommentExt> {
- self.vec.iter_mut().filter(|c| c.value.id.id == key).last()
- }
- pub fn insert(&mut self, key: &str, value: CommentExt) {
+ pub(crate) fn insert(&mut self, key: &str, value: CommentExt) {
let parent = self
.vec
.iter_mut()
.filter(|c| c.value.id.id == key)
- .last()
+ .next_back()
.expect("One of these should exist");
parent.push_reply(value);
}
}
impl CommentExt {
- pub fn push_reply(&mut self, value: CommentExt) {
+ pub(crate) fn push_reply(&mut self, value: CommentExt) {
self.replies.push(value);
}
- pub fn get_mut_reply(&mut self, key: &str) -> Option<&mut CommentExt> {
- self.replies
- .iter_mut()
- .filter(|c| c.value.id.id == key)
- .last()
- }
}
impl From<Comment> for CommentExt {
diff --git a/crates/yt/src/comments/description.rs b/crates/yt/src/comments/description.rs
index 878b573..9f87441 100644
--- a/crates/yt/src/comments/description.rs
+++ b/crates/yt/src/comments/description.rs
@@ -19,7 +19,7 @@ use crate::{
use anyhow::{Result, bail};
use yt_dlp::json_cast;
-pub async fn description(app: &App) -> Result<()> {
+pub(crate) async fn description(app: &App) -> Result<()> {
let description = get(app).await?;
display_fmt_and_less(description).await?;
@@ -40,7 +40,6 @@ pub async fn get(app: &App) -> Result<String> {
Ok(info_json
.get("description")
- .map(|val| json_cast!(val, as_str))
- .unwrap_or("<No description>")
+ .map_or("<No description>", |val| json_cast!(val, as_str))
.to_owned())
}
diff --git a/crates/yt/src/comments/display.rs b/crates/yt/src/comments/display.rs
index 6166b2b..de50614 100644
--- a/crates/yt/src/comments/display.rs
+++ b/crates/yt/src/comments/display.rs
@@ -19,7 +19,7 @@ use crate::comments::comment::CommentExt;
use super::comment::Comments;
impl Comments {
- pub fn render(&self, color: bool) -> String {
+ pub(crate) fn render(&self, color: bool) -> String {
self.render_help(color).expect("This should never fail.")
}
diff --git a/crates/yt/src/comments/mod.rs b/crates/yt/src/comments/mod.rs
index 54031a4..b856cad 100644
--- a/crates/yt/src/comments/mod.rs
+++ b/crates/yt/src/comments/mod.rs
@@ -149,7 +149,7 @@ pub async fn get(app: &App) -> Result<Comments> {
Ok(comments)
}
-pub async fn comments(app: &App) -> Result<()> {
+pub(crate) async fn comments(app: &App) -> Result<()> {
let comments = get(app).await?;
display_fmt_and_less(comments.render(true)).await?;
diff --git a/crates/yt/src/comments/output.rs b/crates/yt/src/comments/output.rs
index cb3a9c4..67dec8f 100644
--- a/crates/yt/src/comments/output.rs
+++ b/crates/yt/src/comments/output.rs
@@ -17,9 +17,7 @@ use std::{
use anyhow::{Context, Result};
use uu_fmt::{FmtOptions, process_text};
-use crate::unreachable::Unreachable;
-
-pub async fn display_fmt_and_less(input: String) -> Result<()> {
+pub(crate) async fn display_fmt_and_less(input: String) -> Result<()> {
let mut less = Command::new("less")
.args(["--raw-control-chars"])
.stdin(Stdio::piped())
@@ -41,7 +39,9 @@ pub async fn display_fmt_and_less(input: String) -> Result<()> {
}
#[must_use]
-pub fn format_text(input: &str) -> String {
+pub(crate) fn format_text(input: &str) -> String {
+ let input = input.trim();
+
let width = termsize::get().map_or(90, |size| size.cols);
let fmt_opts = FmtOptions {
uniform: true,
diff --git a/crates/yt/src/constants.rs b/crates/yt/src/constants.rs
index 0f5b918..690e018 100644
--- a/crates/yt/src/constants.rs
+++ b/crates/yt/src/constants.rs
@@ -9,4 +9,4 @@
// You should have received a copy of the License along with this program.
// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
-pub const HELP_STR: &str = include_str!("./select/selection_file/help.str");
+pub(crate) const HELP_STR: &str = include_str!("./select/selection_file/help.str");
diff --git a/crates/yt/src/download/download_options.rs b/crates/yt/src/download/download_options.rs
index 558adfd..2eac4c3 100644
--- a/crates/yt/src/download/download_options.rs
+++ b/crates/yt/src/download/download_options.rs
@@ -13,11 +13,14 @@ use anyhow::Context;
use serde_json::{Value, json};
use yt_dlp::{YoutubeDL, options::YoutubeDLOptions};
-use crate::{app::App, storage::video_database::YtDlpOptions};
+use crate::app::App;
use super::progress_hook::wrapped_progress_hook;
-pub fn download_opts(app: &App, additional_opts: &YtDlpOptions) -> anyhow::Result<YoutubeDL> {
+pub(crate) fn download_opts(
+ app: &App,
+ subtitle_langs: Option<&String>,
+) -> anyhow::Result<YoutubeDL> {
YoutubeDLOptions::new()
.with_progress_hook(wrapped_progress_hook)
.set("extract_flat", "in_playlist")
diff --git a/crates/yt/src/download/mod.rs b/crates/yt/src/download/mod.rs
index 6065cf9..2e7315d 100644
--- a/crates/yt/src/download/mod.rs
+++ b/crates/yt/src/download/mod.rs
@@ -72,7 +72,7 @@ enum CacheSizeCheck {
}
#[derive(Debug)]
-pub struct Downloader {
+pub(crate) struct Downloader {
current_download: Option<CurrentDownload>,
video_size_cache: HashMap<ExtractorHash, u64>,
printed_warning: bool,
@@ -87,7 +87,7 @@ impl Default for Downloader {
impl Downloader {
#[must_use]
- pub fn new() -> Self {
+ pub(crate) fn new() -> Self {
Self {
current_download: None,
video_size_cache: HashMap::new(),
@@ -179,8 +179,8 @@ impl Downloader {
/// This Downloader will periodically check if the database has changed, and then also
/// change which videos it downloads.
/// This will run, until the database doesn't contain any watchable videos
- pub async fn consume(&mut self, app: Arc<App>, max_cache_size: u64) -> Result<()> {
- while let Some(next_video) = get_next_uncached_video(&app).await? {
+ pub(crate) async fn consume(&mut self, app: Arc<App>, max_cache_size: u64) -> Result<()> {
+ while let Some(next_video) = Video::next_to_download(&app).await? {
match self
.is_enough_cache_available(&app, max_cache_size, &next_video)
.await?
@@ -238,7 +238,7 @@ impl Downloader {
Ok(())
}
- pub async fn get_current_cache_allocation(app: &App) -> Result<Bytes> {
+ pub(crate) async fn get_current_cache_allocation(app: &App) -> Result<Bytes> {
fn dir_size(mut dir: fs::ReadDir) -> BoxFuture<'static, Result<Bytes>> {
async move {
let mut acc = 0;
diff --git a/crates/yt/src/download/progress_hook.rs b/crates/yt/src/download/progress_hook.rs
index ad754b0..99d1a74 100644
--- a/crates/yt/src/download/progress_hook.rs
+++ b/crates/yt/src/download/progress_hook.rs
@@ -13,19 +13,20 @@ use std::{
process,
};
-use bytes::Bytes;
use log::{Level, log_enabled};
-use yt_dlp::mk_python_function;
+use owo_colors::OwoColorize;
+use yt_dlp::{json_cast, json_get, wrap_progress_hook};
use crate::{
ansi_escape_codes::{clear_whole_line, move_to_col},
select::selection_file::duration::MaybeDuration,
+ shared::bytes::Bytes,
};
/// # Panics
/// If expectations fail.
-#[allow(clippy::too_many_lines, clippy::needless_pass_by_value)]
-pub fn progress_hook(
+#[allow(clippy::needless_pass_by_value)]
+pub(crate) fn progress_hook(
input: serde_json::Map<String, serde_json::Value>,
) -> Result<(), std::io::Error> {
// Only add the handler, if the log-level is higher than Debug (this avoids covering debug
@@ -195,4 +196,4 @@ pub fn progress_hook(
Ok(())
}
-mk_python_function!(progress_hook, wrapped_progress_hook);
+wrap_progress_hook!(progress_hook, wrapped_progress_hook);
diff --git a/crates/yt/src/main.rs b/crates/yt/src/main.rs
index faee401..52b8e07 100644
--- a/crates/yt/src/main.rs
+++ b/crates/yt/src/main.rs
@@ -36,24 +36,24 @@ use crate::{
storage::subscription,
};
-pub mod ansi_escape_codes;
-pub mod app;
-pub mod cli;
-pub mod unreachable;
+pub(crate) mod ansi_escape_codes;
+pub(crate) mod app;
+pub(crate) mod cli;
+pub(crate) mod shared;
-pub mod cache;
-pub mod comments;
-pub mod config;
-pub mod constants;
-pub mod download;
-pub mod select;
-pub mod status;
-pub mod storage;
-pub mod subscribe;
-pub mod update;
-pub mod version;
-pub mod videos;
-pub mod watch;
+pub(crate) mod cache;
+pub(crate) mod comments;
+pub(crate) mod config;
+pub(crate) mod constants;
+pub(crate) mod download;
+pub(crate) mod select;
+pub(crate) mod status;
+pub(crate) mod storage;
+pub(crate) mod subscribe;
+pub(crate) mod update;
+pub(crate) mod version;
+pub(crate) mod videos;
+pub(crate) mod watch;
#[tokio::main]
// This is _the_ main function after all. It is not really good, but it sort of works.
diff --git a/crates/yt/src/select/cmds/add.rs b/crates/yt/src/select/cmds/add.rs
index 2c9a323..f793117 100644
--- a/crates/yt/src/select/cmds/add.rs
+++ b/crates/yt/src/select/cmds/add.rs
@@ -23,7 +23,7 @@ use url::Url;
use yt_dlp::{YoutubeDL, info_json::InfoJson, json_cast, json_get};
#[allow(clippy::too_many_lines)]
-pub(super) async fn add(
+pub(crate) async fn add(
app: &App,
urls: Vec<Url>,
start: Option<usize>,
diff --git a/crates/yt/src/select/mod.rs b/crates/yt/src/select/mod.rs
index 2478b76..543013e 100644
--- a/crates/yt/src/select/mod.rs
+++ b/crates/yt/src/select/mod.rs
@@ -36,10 +36,10 @@ use selection_file::process_line;
use tempfile::Builder;
use tokio::process::Command;
-pub mod cmds;
-pub mod selection_file;
+pub(crate) mod cmds;
+pub(crate) mod selection_file;
-pub async fn select_split(
+pub(crate) async fn select_split(
app: &App,
done: bool,
sort_key: SelectSplitSortKey,
@@ -158,7 +158,7 @@ pub async fn select_split(
Ok(())
}
-pub async fn select_file(app: &App, done: bool, use_last_selection: bool) -> Result<()> {
+pub(crate) async fn select_file(app: &App, done: bool, use_last_selection: bool) -> Result<()> {
let temp_file = Builder::new()
.prefix("yt_video_select-")
.suffix(".yts")
diff --git a/crates/yt/src/select/selection_file/duration.rs b/crates/yt/src/select/selection_file/duration.rs
index 668a0b8..e536f18 100644
--- a/crates/yt/src/select/selection_file/duration.rs
+++ b/crates/yt/src/select/selection_file/duration.rs
@@ -20,51 +20,45 @@ const HOUR: u64 = 60 * MINUTE;
const DAY: u64 = 24 * HOUR;
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
-pub struct MaybeDuration {
+pub(crate) struct MaybeDuration {
time: Option<Duration>,
}
impl MaybeDuration {
#[must_use]
- pub fn from_std(d: Duration) -> Self {
+ pub(crate) fn from_std(d: Duration) -> Self {
Self { time: Some(d) }
}
#[must_use]
- pub fn from_secs_f64(d: f64) -> Self {
+ pub(crate) fn from_secs_f64(d: f64) -> Self {
Self {
time: Some(Duration::from_secs_f64(d)),
}
}
#[must_use]
- pub fn from_maybe_secs_f64(d: Option<f64>) -> Self {
+ pub(crate) fn from_maybe_secs_f64(d: Option<f64>) -> Self {
Self {
time: d.map(Duration::from_secs_f64),
}
}
#[must_use]
- pub fn from_secs(d: u64) -> Self {
+ #[cfg(test)]
+ pub(crate) fn from_secs(d: u64) -> Self {
Self {
time: Some(Duration::from_secs(d)),
}
}
- #[must_use]
- pub fn zero() -> Self {
- Self {
- time: Some(Duration::default()),
- }
- }
-
/// Try to return the current duration encoded as seconds.
#[must_use]
- pub fn as_secs(&self) -> Option<u64> {
+ pub(crate) fn as_secs(&self) -> Option<u64> {
self.time.map(|v| v.as_secs())
}
/// Try to return the current duration encoded as seconds and nanoseconds.
#[must_use]
- pub fn as_secs_f64(&self) -> Option<f64> {
+ pub(crate) fn as_secs_f64(&self) -> Option<f64> {
self.time.map(|v| v.as_secs_f64())
}
}
diff --git a/crates/yt/src/select/selection_file/mod.rs b/crates/yt/src/select/selection_file/mod.rs
index f5e0531..36342f8 100644
--- a/crates/yt/src/select/selection_file/mod.rs
+++ b/crates/yt/src/select/selection_file/mod.rs
@@ -14,11 +14,11 @@
use anyhow::{Result, bail};
use shlex::Shlex;
-pub mod duration;
+pub(crate) mod duration;
/// # Panics
/// If internal assertions fail.
-pub fn process_line(line: &str) -> Result<Option<Vec<String>>> {
+pub(crate) fn process_line(line: &str) -> Result<Option<Vec<String>>> {
// Filter out comments and empty lines
if line.starts_with('#') || line.trim().is_empty() {
Ok(None)
diff --git a/crates/yt/src/status/mod.rs b/crates/yt/src/status/mod.rs
index 6883802..f629324 100644
--- a/crates/yt/src/status/mod.rs
+++ b/crates/yt/src/status/mod.rs
@@ -15,14 +15,14 @@ use crate::{
app::App,
download::Downloader,
select::selection_file::duration::MaybeDuration,
- storage::{
- subscriptions,
- video_database::{VideoStatusMarker, get},
+ shared::bytes::Bytes,
+ storage::db::{
+ subscription::Subscriptions,
+ video::{Video, VideoStatusMarker},
},
};
use anyhow::{Context, Result};
-use bytes::Bytes;
macro_rules! get {
($videos:expr, $status:ident) => {
@@ -40,7 +40,7 @@ macro_rules! get {
};
}
-pub async fn show(app: &App) -> Result<()> {
+pub(crate) async fn show(app: &App) -> Result<()> {
let all_videos = get::videos(app, VideoStatusMarker::ALL).await?;
// lengths
@@ -121,7 +121,7 @@ Dropped Videos: {dropped_videos_len}
Ok(())
}
-pub fn config(app: &App) -> Result<()> {
+pub(crate) fn config(app: &App) -> Result<()> {
let config_str = toml::to_string(&app.config)?;
print!("{config_str}");
diff --git a/crates/yt/src/storage/migrate/mod.rs b/crates/yt/src/storage/migrate/mod.rs
index 953d079..4fa39ab 100644
--- a/crates/yt/src/storage/migrate/mod.rs
+++ b/crates/yt/src/storage/migrate/mod.rs
@@ -75,7 +75,7 @@ macro_rules! make_upgrade {
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
-pub enum DbVersion {
+pub(crate) enum DbVersion {
/// The database is not yet initialized.
Empty,
@@ -222,9 +222,10 @@ fn get_current_date() -> i64 {
///
/// # Panics
/// Only if internal assertions fail.
-pub async fn get_version(app: &App) -> Result<DbVersion> {
+pub(crate) async fn get_version(app: &App) -> Result<DbVersion> {
get_version_db(&app.database).await
}
+
/// Return the current database version.
///
/// In contrast to the [`get_version`] function, this function does not
@@ -232,13 +233,19 @@ pub async fn get_version(app: &App) -> Result<DbVersion> {
///
/// # Panics
/// Only if internal assertions fail.
-pub async fn get_version_db(pool: &SqlitePool) -> Result<DbVersion> {
+pub(crate) async fn get_version_db(pool: &SqlitePool) -> Result<DbVersion> {
let version_table_exists = {
let query = query!(
- "SELECT 1 as result FROM sqlite_master WHERE type = 'table' AND name = 'version'"
+ "
+ SELECT 1 as result
+ FROM sqlite_master
+ WHERE type = 'table'
+ AND name = 'version'
+ "
)
.fetch_optional(pool)
.await?;
+
if let Some(output) = query {
assert_eq!(output.result, 1);
true
@@ -246,13 +253,16 @@ pub async fn get_version_db(pool: &SqlitePool) -> Result<DbVersion> {
false
}
};
+
if !version_table_exists {
return Ok(DbVersion::Empty);
}
let current_version = query!(
"
- SELECT namespace, number FROM version WHERE valid_to IS NULL;
+ SELECT namespace, number
+ FROM version
+ WHERE valid_to IS NULL;
"
)
.fetch_one(pool)
@@ -262,7 +272,7 @@ pub async fn get_version_db(pool: &SqlitePool) -> Result<DbVersion> {
DbVersion::from_db(current_version.number, current_version.namespace.as_str())
}
-pub async fn migrate_db(app: &App) -> Result<()> {
+pub(crate) async fn migrate_db(app: &App) -> Result<()> {
let current_version = get_version(app)
.await
.context("Failed to determine initial version")?;
diff --git a/crates/yt/src/storage/mod.rs b/crates/yt/src/storage/mod.rs
index d352b41..2d9133b 100644
--- a/crates/yt/src/storage/mod.rs
+++ b/crates/yt/src/storage/mod.rs
@@ -9,6 +9,6 @@
// You should have received a copy of the License along with this program.
// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
-pub mod migrate;
-pub mod subscriptions;
-pub mod video_database;
+pub(crate) mod migrate;
+pub(crate) mod db;
+pub(crate) mod notify;
diff --git a/crates/yt/src/subscribe/mod.rs b/crates/yt/src/subscribe/mod.rs
index 66797e8..89ea9f7 100644
--- a/crates/yt/src/subscribe/mod.rs
+++ b/crates/yt/src/subscribe/mod.rs
@@ -12,7 +12,6 @@
use std::str::FromStr;
use anyhow::{Context, Result, bail};
-use futures::FutureExt;
use log::{error, warn};
use tokio::io::{AsyncBufRead, AsyncBufReadExt};
use url::Url;
@@ -26,7 +25,7 @@ use crate::{
unreachable::Unreachable,
};
-pub async fn unsubscribe(app: &App, name: String) -> Result<()> {
+pub(crate) async fn unsubscribe(app: &App, name: String) -> Result<()> {
let present_subscriptions = get(app).await?;
if let Some(subscription) = present_subscriptions.0.get(&name) {
@@ -38,7 +37,7 @@ pub async fn unsubscribe(app: &App, name: String) -> Result<()> {
Ok(())
}
-pub async fn import<W: AsyncBufRead + AsyncBufReadExt + Unpin>(
+pub(crate) async fn import<W: AsyncBufRead + AsyncBufReadExt + Unpin>(
app: &App,
reader: W,
force: bool,
@@ -67,7 +66,11 @@ pub async fn import<W: AsyncBufRead + AsyncBufReadExt + Unpin>(
Ok(())
}
-pub async fn subscribe(app: &App, name: Option<String>, url: Url) -> Result<()> {
+pub(crate) async fn subscribe(
+ app: &App,
+ name: Option<String>,
+ url: Url,
+) -> Result<()> {
if !(url.as_str().ends_with("videos")
|| url.as_str().ends_with("streams")
|| url.as_str().ends_with("shorts")
diff --git a/crates/yt/src/update/mod.rs b/crates/yt/src/update/mod.rs
index 7f9bee7..fbe23da 100644
--- a/crates/yt/src/update/mod.rs
+++ b/crates/yt/src/update/mod.rs
@@ -32,7 +32,7 @@ use crate::{
mod updater;
use updater::Updater;
-pub async fn update(
+pub(crate) async fn update(
app: &App,
max_backlog: usize,
subscription_names_to_update: Vec<String>,
@@ -64,7 +64,7 @@ pub async fn update(
}
#[allow(clippy::too_many_lines)]
-pub fn video_entry_to_video(entry: &InfoJson, sub: Option<&Subscription>) -> Result<Video> {
+pub(crate) fn video_entry_to_video(entry: &InfoJson, sub: Option<&Subscription>) -> Result<Video> {
fn fmt_context(date: &str, extended: Option<&str>) -> String {
let f = format!(
"Failed to parse the `upload_date` of the entry ('{date}'). \
diff --git a/crates/yt/src/update/updater.rs b/crates/yt/src/update/updater.rs
index 75d12dc..54dea97 100644
--- a/crates/yt/src/update/updater.rs
+++ b/crates/yt/src/update/updater.rs
@@ -41,7 +41,7 @@ pub(super) struct Updater {
static REACHED_NUMBER: AtomicUsize = const { AtomicUsize::new(1) };
impl Updater {
- pub(super) fn new(max_backlog: usize, hashes: Vec<Hash>) -> Self {
+ pub(super) fn new(max_backlog: usize, hashes: Vec<ExtractorHash>) -> Self {
// TODO(@bpeetz): The number should not be hardcoded. <2025-06-14>
let pool = LocalPoolHandle::new(16);
diff --git a/crates/yt/src/version/mod.rs b/crates/yt/src/version/mod.rs
index 2cc41c7..a3aa7ff 100644
--- a/crates/yt/src/version/mod.rs
+++ b/crates/yt/src/version/mod.rs
@@ -14,7 +14,7 @@ use yt_dlp::options::YoutubeDLOptions;
use crate::{config::Config, storage::migrate::get_version_db};
-pub async fn show(config: &Config) -> Result<()> {
+pub(crate) async fn show(config: &Config) -> Result<()> {
let db_version = {
let options = SqliteConnectOptions::new()
.filename(&config.paths.database_path)
diff --git a/crates/yt/src/videos/display/format_video.rs b/crates/yt/src/videos/display/format_video.rs
index b97acb1..659c3be 100644
--- a/crates/yt/src/videos/display/format_video.rs
+++ b/crates/yt/src/videos/display/format_video.rs
@@ -14,7 +14,10 @@ use anyhow::Result;
use crate::{app::App, comments::output::format_text, storage::video_database::Video};
impl Video {
- pub async fn to_info_display(&self, app: &App) -> Result<String> {
+ pub(crate) async fn to_info_display(
+ &self,
+ app: &App,
+ ) -> Result<String> {
let cache_path = self.cache_path_fmt(app);
let description = self.description_fmt();
let duration = self.duration_fmt(app);
@@ -29,7 +32,7 @@ impl Video {
let title = self.title_fmt(app);
let url = self.url_fmt(app);
let watch_progress = self.watch_progress_fmt(app);
- let video_options = self.video_options_fmt(app).await?;
+ let video_options = self.video_options_fmt(app);
let watched_percentage_fmt = {
if let Some(duration) = self.duration.as_secs() {
diff --git a/crates/yt/src/videos/display/mod.rs b/crates/yt/src/videos/display/mod.rs
index 1188569..89f7575 100644
--- a/crates/yt/src/videos/display/mod.rs
+++ b/crates/yt/src/videos/display/mod.rs
@@ -18,9 +18,7 @@ use crate::{
storage::video_database::{TimeStamp, Video, VideoStatus, get::get_video_opts},
};
-use anyhow::{Context, Result};
-
-pub mod format_video;
+pub(crate) mod format_video;
macro_rules! get {
($value:expr, $key:ident, $name:expr, $code:tt) => {
@@ -44,7 +42,7 @@ where
}
impl Video {
#[must_use]
- pub fn cache_path_fmt(&self, app: &App) -> String {
+ pub(crate) fn cache_path_fmt(&self, app: &App) -> String {
let cache_path = if let VideoStatus::Cached {
cache_path,
is_focused: _,
@@ -58,7 +56,7 @@ impl Video {
}
#[must_use]
- pub fn description_fmt(&self) -> String {
+ pub(crate) fn description_fmt(&self) -> String {
get!(
self,
description,
@@ -68,17 +66,17 @@ impl Video {
}
#[must_use]
- pub fn duration_fmt_no_color(&self) -> String {
+ pub(crate) fn duration_fmt_no_color(&self) -> String {
self.duration.to_string()
}
#[must_use]
- pub fn duration_fmt(&self, app: &App) -> String {
+ pub(crate) fn duration_fmt(&self, app: &App) -> String {
let duration = self.duration_fmt_no_color();
maybe_add_color(app, duration, |v| v.cyan().bold().to_string())
}
#[must_use]
- pub fn watch_progress_fmt(&self, app: &App) -> String {
+ pub(crate) fn watch_progress_fmt(&self, app: &App) -> String {
maybe_add_color(
app,
MaybeDuration::from_std(self.watch_progress).to_string(),
@@ -86,7 +84,7 @@ impl Video {
)
}
- pub async fn extractor_hash_fmt_no_color(&self, app: &App) -> Result<String> {
+ pub(crate) async fn extractor_hash_fmt_no_color(&self, app: &App) -> Result<String> {
let hash = self
.extractor_hash
.into_short_hash(app)
@@ -100,7 +98,7 @@ impl Video {
.to_string();
Ok(hash)
}
- pub async fn extractor_hash_fmt(&self, app: &App) -> Result<String> {
+ pub(crate) async fn extractor_hash_fmt(&self, app: &App) -> Result<String> {
let hash = self.extractor_hash_fmt_no_color(app).await?;
Ok(maybe_add_color(app, hash, |v| {
v.bright_purple().italic().to_string()
@@ -108,7 +106,7 @@ impl Video {
}
#[must_use]
- pub fn in_playlist_fmt(&self, app: &App) -> String {
+ pub(crate) fn in_playlist_fmt(&self, app: &App) -> String {
let output = match &self.status {
VideoStatus::Pick
| VideoStatus::Watch
@@ -126,14 +124,14 @@ impl Video {
maybe_add_color(app, output.to_owned(), |v| v.yellow().italic().to_string())
}
#[must_use]
- pub fn last_status_change_fmt(&self, app: &App) -> String {
+ pub(crate) fn last_status_change_fmt(&self, app: &App) -> String {
maybe_add_color(app, self.last_status_change.to_string(), |v| {
v.bright_cyan().to_string()
})
}
#[must_use]
- pub fn parent_subscription_name_fmt_no_color(&self) -> String {
+ pub(crate) fn parent_subscription_name_fmt_no_color(&self) -> String {
get!(
self,
parent_subscription_name,
@@ -142,18 +140,18 @@ impl Video {
)
}
#[must_use]
- pub fn parent_subscription_name_fmt(&self, app: &App) -> String {
+ pub(crate) fn parent_subscription_name_fmt(&self, app: &App) -> String {
let psn = self.parent_subscription_name_fmt_no_color();
maybe_add_color(app, psn, |v| v.bright_magenta().to_string())
}
#[must_use]
- pub fn priority_fmt(&self) -> String {
+ pub(crate) fn priority_fmt(&self) -> String {
self.priority.to_string()
}
#[must_use]
- pub fn publish_date_fmt_no_color(&self) -> String {
+ pub(crate) fn publish_date_fmt_no_color(&self) -> String {
get!(
self,
publish_date,
@@ -162,25 +160,25 @@ impl Video {
)
}
#[must_use]
- pub fn publish_date_fmt(&self, app: &App) -> String {
+ pub(crate) fn publish_date_fmt(&self, app: &App) -> String {
let date = self.publish_date_fmt_no_color();
maybe_add_color(app, date, |v| v.bright_white().bold().to_string())
}
#[must_use]
- pub fn status_fmt_no_color(&self) -> String {
+ pub(crate) fn status_fmt_no_color(&self) -> String {
// TODO: We might support `.trim()`ing that, as the extra whitespace could be bad in the
// selection file. <2024-10-07>
self.status.as_marker().as_command().to_string()
}
#[must_use]
- pub fn status_fmt(&self, app: &App) -> String {
+ pub(crate) fn status_fmt(&self, app: &App) -> String {
let status = self.status_fmt_no_color();
maybe_add_color(app, status, |v| v.red().bold().to_string())
}
#[must_use]
- pub fn thumbnail_url_fmt(&self) -> String {
+ pub(crate) fn thumbnail_url_fmt(&self) -> String {
get!(
self,
thumbnail_url,
@@ -190,26 +188,26 @@ impl Video {
}
#[must_use]
- pub fn title_fmt_no_color(&self) -> String {
+ pub(crate) fn title_fmt_no_color(&self) -> String {
self.title.replace(['"', '„', '”', '“'], "'")
}
#[must_use]
- pub fn title_fmt(&self, app: &App) -> String {
+ pub(crate) fn title_fmt(&self, app: &App) -> String {
let title = self.title_fmt_no_color();
maybe_add_color(app, title, |v| v.green().bold().to_string())
}
#[must_use]
- pub fn url_fmt_no_color(&self) -> String {
+ pub(crate) fn url_fmt_no_color(&self) -> String {
self.url.as_str().replace('"', "\\\"")
}
#[must_use]
- pub fn url_fmt(&self, app: &App) -> String {
+ pub(crate) fn url_fmt(&self, app: &App) -> String {
let url = self.url_fmt_no_color();
maybe_add_color(app, url, |v| v.italic().to_string())
}
- pub async fn video_options_fmt_no_color(&self, app: &App) -> Result<String> {
+ pub(crate) fn video_options_fmt_no_color(&self, app: &App) -> String {
let video_options = {
let opts = get_video_opts(app, &self.extractor_hash)
.await
@@ -222,7 +220,7 @@ impl Video {
};
Ok(video_options)
}
- pub async fn video_options_fmt(&self, app: &App) -> Result<String> {
+ pub(crate) fn video_options_fmt(&self, app: &App) -> Result<String> {
let opts = self.video_options_fmt_no_color(app).await?;
Ok(maybe_add_color(app, opts, |v| v.bright_green().to_string()))
}
diff --git a/crates/yt/src/videos/mod.rs b/crates/yt/src/videos/mod.rs
index 960340b..092e75c 100644
--- a/crates/yt/src/videos/mod.rs
+++ b/crates/yt/src/videos/mod.rs
@@ -12,7 +12,7 @@
use anyhow::Result;
use futures::{TryStreamExt, stream::FuturesUnordered};
-pub mod display;
+pub(crate) mod display;
use crate::{
app::App,
@@ -23,7 +23,11 @@ async fn to_line_display_owned(video: Video, app: &App) -> Result<String> {
video.to_line_display(app).await
}
-pub async fn query(app: &App, limit: Option<usize>, search_query: Option<String>) -> Result<()> {
+pub(crate) async fn query(
+ app: &App,
+ limit: Option<usize>,
+ search_query: Option<String>,
+) -> Result<()> {
let all_videos = get::videos(app, VideoStatusMarker::ALL).await?;
// turn one video to a color display, to pre-warm the hash shrinking cache
diff --git a/crates/yt/src/watch/mod.rs b/crates/yt/src/watch/mod.rs
index c32a76f..b4c68a0 100644
--- a/crates/yt/src/watch/mod.rs
+++ b/crates/yt/src/watch/mod.rs
@@ -93,7 +93,7 @@ fn init_mpv(app: &App) -> Result<(Mpv, EventContext)> {
Ok((mpv, ev_ctx))
}
-pub async fn watch(app: Arc<App>) -> Result<()> {
+pub(crate) async fn watch(app: Arc<App>) -> Result<()> {
maintain(&app, false).await?;
let (mpv, mut ev_ctx) = init_mpv(&app).context("Failed to initialize mpv instance")?;
diff --git a/crates/yt/src/watch/playlist.rs b/crates/yt/src/watch/playlist.rs
index ff383d0..f456bfd 100644
--- a/crates/yt/src/watch/playlist.rs
+++ b/crates/yt/src/watch/playlist.rs
@@ -34,7 +34,7 @@ fn cache_values(video: &Video) -> (&Path, bool) {
/// # Panics
/// Only if internal assertions fail.
-pub async fn playlist(app: &App, watch: bool) -> Result<()> {
+pub(crate) async fn playlist(app: &App, watch: bool) -> Result<()> {
let mut previous_output_length = 0;
loop {
let playlist = get::playlist(app).await?.to_videos();
diff --git a/crates/yt/src/watch/playlist_handler/mod.rs b/crates/yt/src/watch/playlist_handler/mod.rs
index 29b8f39..8cf50c9 100644
--- a/crates/yt/src/watch/playlist_handler/mod.rs
+++ b/crates/yt/src/watch/playlist_handler/mod.rs
@@ -27,7 +27,7 @@ use log::{debug, info};
mod client_messages;
#[derive(Debug, Clone, Copy)]
-pub enum Status {
+pub(crate) enum Status {
/// There are no videos cached and no more marked to be watched.
/// Waiting is pointless.
NoMoreAvailable,
@@ -213,7 +213,7 @@ pub async fn status(app: &App) -> Result<Status> {
/// # Panics
/// Only if internal assertions fail.
#[allow(clippy::too_many_lines)]
-pub async fn handle_mpv_event(app: &App, mpv: &Mpv, event: &Event<'_>) -> Result<bool> {
+pub(crate) async fn handle_mpv_event(app: &App, mpv: &Mpv, event: &Event<'_>) -> Result<bool> {
match event {
Event::EndFile(r) => match r.reason {
EndFileReason::Eof => {