Skip to main content

omni_dev/cli/transcript/
youtube.rs

1//! YouTube transcript subcommands.
2
3pub mod fetch;
4pub mod info;
5pub mod list_langs;
6pub mod sync;
7
8use anyhow::Result;
9use clap::{Parser, Subcommand};
10
11/// YouTube: fetch captions, list available languages, and inspect video metadata.
12#[derive(Parser)]
13pub struct YoutubeCommand {
14    /// The YouTube subcommand to execute.
15    #[command(subcommand)]
16    pub command: YoutubeSubcommands,
17}
18
19/// YouTube subcommands.
20#[derive(Subcommand)]
21pub enum YoutubeSubcommands {
22    /// Fetches the transcript for a YouTube video.
23    Fetch(fetch::FetchCommand),
24    /// Lists the caption tracks available on a YouTube video.
25    ListLangs(list_langs::ListLangsCommand),
26    /// Shows top-level metadata (title, channel, duration, languages) for a YouTube video.
27    Info(info::InfoCommand),
28    /// Syncs transcripts for all videos in one or more channels to the filesystem.
29    Sync(sync::SyncCommand),
30}
31
32impl YoutubeCommand {
33    /// Executes the YouTube subcommand.
34    pub async fn execute(self) -> Result<()> {
35        match self.command {
36            YoutubeSubcommands::Fetch(cmd) => cmd.execute().await,
37            YoutubeSubcommands::ListLangs(cmd) => cmd.execute().await,
38            YoutubeSubcommands::Info(cmd) => cmd.execute().await,
39            YoutubeSubcommands::Sync(cmd) => cmd.execute().await,
40        }
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47    use crate::cli::transcript::format::CliFormat;
48
49    #[test]
50    fn youtube_subcommands_fetch_variant() {
51        let cmd = YoutubeCommand {
52            command: YoutubeSubcommands::Fetch(fetch::FetchCommand {
53                url: "https://youtu.be/abc".to_string(),
54                lang: "en".to_string(),
55                output: CliFormat::Srt,
56                format: None,
57                auto: false,
58                translate: None,
59                out_file: None,
60            }),
61        };
62        assert!(matches!(cmd.command, YoutubeSubcommands::Fetch(_)));
63    }
64
65    #[test]
66    fn youtube_subcommands_list_langs_variant() {
67        let cmd = YoutubeCommand {
68            command: YoutubeSubcommands::ListLangs(list_langs::ListLangsCommand {
69                url: "https://youtu.be/abc".to_string(),
70                output: list_langs::ListLangsOutput::Table,
71            }),
72        };
73        assert!(matches!(cmd.command, YoutubeSubcommands::ListLangs(_)));
74    }
75
76    #[test]
77    fn youtube_subcommands_sync_variant() {
78        let cmd = YoutubeCommand {
79            command: YoutubeSubcommands::Sync(sync::SyncCommand {
80                channels: vec!["@handle".to_string()],
81                out: std::path::PathBuf::from("/tmp/yt"),
82                lang: "en".to_string(),
83                format: CliFormat::Srt,
84                auto: false,
85                full: false,
86                since: None,
87                refresh_metadata_older_than: None,
88                concurrency: 4,
89                dry_run: false,
90            }),
91        };
92        assert!(matches!(cmd.command, YoutubeSubcommands::Sync(_)));
93    }
94
95    #[test]
96    fn youtube_subcommands_info_variant() {
97        let cmd = YoutubeCommand {
98            command: YoutubeSubcommands::Info(info::InfoCommand {
99                url: "https://youtu.be/abc".to_string(),
100                output: info::InfoOutput::Table,
101            }),
102        };
103        assert!(matches!(cmd.command, YoutubeSubcommands::Info(_)));
104    }
105}