Skip to main content

omni_dev/cli/transcript/youtube/
mod.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                format: CliFormat::Srt,
56                auto: false,
57                translate: None,
58                output: None,
59            }),
60        };
61        assert!(matches!(cmd.command, YoutubeSubcommands::Fetch(_)));
62    }
63
64    #[test]
65    fn youtube_subcommands_list_langs_variant() {
66        let cmd = YoutubeCommand {
67            command: YoutubeSubcommands::ListLangs(list_langs::ListLangsCommand {
68                url: "https://youtu.be/abc".to_string(),
69                output: list_langs::ListLangsOutput::Table,
70            }),
71        };
72        assert!(matches!(cmd.command, YoutubeSubcommands::ListLangs(_)));
73    }
74
75    #[test]
76    fn youtube_subcommands_sync_variant() {
77        let cmd = YoutubeCommand {
78            command: YoutubeSubcommands::Sync(sync::SyncCommand {
79                channels: vec!["@handle".to_string()],
80                out: std::path::PathBuf::from("/tmp/yt"),
81                lang: "en".to_string(),
82                format: CliFormat::Srt,
83                auto: false,
84                full: false,
85                since: None,
86                refresh_metadata_older_than: None,
87                concurrency: 4,
88                dry_run: false,
89            }),
90        };
91        assert!(matches!(cmd.command, YoutubeSubcommands::Sync(_)));
92    }
93
94    #[test]
95    fn youtube_subcommands_info_variant() {
96        let cmd = YoutubeCommand {
97            command: YoutubeSubcommands::Info(info::InfoCommand {
98                url: "https://youtu.be/abc".to_string(),
99                output: info::InfoOutput::Table,
100            }),
101        };
102        assert!(matches!(cmd.command, YoutubeSubcommands::Info(_)));
103    }
104}