id3_cli/app/
field.rs

1use crate::{error::Error, run::Run};
2use clap::{Args, Subcommand};
3use std::fmt::Debug;
4
5/// Table of [`Args`] types to used in [`Field`].
6pub trait ArgsTable {
7    /// CLI arguments for text fields.
8    type Text: Args;
9    /// Genre fields.
10    type Genre: Subcommand;
11    /// CLI arguments for the picture field.
12    type Picture: Args;
13    /// CLI arguments for the comment field.
14    type Comment: Args;
15}
16
17/// Field-specific subcommand.
18#[derive(Debug, Subcommand)]
19pub enum Field<Args>
20where
21    Args: ArgsTable,
22    Args::Text: Debug,
23    Args::Genre: Debug,
24    Args::Comment: Debug,
25    Args::Picture: Debug,
26{
27    /// Text field.
28    #[clap(flatten)]
29    Text(Text<Args>),
30    /// Frame field.
31    #[clap(flatten)]
32    Frame(Frame<Args>),
33}
34
35impl<Args> Run for Field<Args>
36where
37    Args: ArgsTable,
38    Args::Text: Debug,
39    Args::Genre: Debug,
40    Args::Comment: Debug,
41    Args::Picture: Debug,
42    Text<Args>: Run,
43    Frame<Args>: Run,
44{
45    fn run(self) -> Result<(), Error> {
46        match self {
47            Field::Text(proc) => proc.run(),
48            Field::Frame(proc) => proc.run(),
49        }
50    }
51}
52
53/// Text field subcommand.
54#[derive(Debug, Subcommand)]
55pub enum Text<Args: ArgsTable> {
56    Title(Args::Text),
57    Artist(Args::Text),
58    Album(Args::Text),
59    AlbumArtist(Args::Text),
60    #[clap(flatten)]
61    Genre(Args::Genre),
62}
63
64/// Frame field subcommand.
65#[derive(Debug, Subcommand)]
66pub enum Frame<Args: ArgsTable> {
67    Comment(Args::Comment),
68    Picture(Args::Picture),
69}
70
71impl<Args> Run for Frame<Args>
72where
73    Args: ArgsTable,
74    Args::Comment: Run,
75    Args::Picture: Run,
76{
77    fn run(self) -> Result<(), Error> {
78        match self {
79            Frame::Comment(proc) => proc.run(),
80            Frame::Picture(proc) => proc.run(),
81        }
82    }
83}