Skip to content

Commit

Permalink
compile time complete
Browse files Browse the repository at this point in the history
  • Loading branch information
kingwingfly committed Feb 5, 2024
1 parent ac397e6 commit aa2a84c
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ chrono = "0.4.33"

[build-dependencies]
protobuf-codegen = { version = "3" }
clap_complete = "4"
clap = { version = "4.4", features = ["derive"]}

[features]
default = ["bili"]
Expand Down
193 changes: 193 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
//! This is the build script for the project.
//! - It generates the protobuf file for the project.
//! - It generates the completion file for the CLI.
//! Caution:
//! You should copy `Cli` relevant code from `src/cli/mod.rs` to here and `Qn` from `src/proto/data`.
//! So that the completion file can be generated correctly.

use clap::{builder::PossibleValue, CommandFactory, Parser, Subcommand, ValueEnum};
use clap_complete::{generate_to, Shell};

fn main() -> Result<(), Box<dyn std::error::Error>> {
protobuf_codegen::Codegen::new()
.pure()
Expand All @@ -6,5 +16,188 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.out_dir("./src/proto")
.run()
.unwrap();

if let Some(outdir) = std::env::var_os("OUT_DIR") {
let mut cmd = Cli::command();
for &shell in Shell::value_variants() {
let path = generate_to(
shell, &mut cmd, // We need to specify what generator to use
"fav", // We need to specify the bin name manually
&outdir, // We need to specify where to write to
)?;
let filename = path.file_name().unwrap();
let release_path = std::path::PathBuf::from(&outdir)
.parent()
.unwrap()
.parent()
.unwrap()
.parent()
.unwrap()
.join(filename);
std::fs::rename(&path, &release_path).unwrap();
println!("cargo:warning=Completion file is generated: {release_path:?}");
}
}
Ok(())
}

/// The main CLI entry point.
#[derive(Parser)]
#[command(author, version, about)]
pub struct Cli {
#[clap(subcommand)]
pub(crate) subcmd: Commands,
}

#[derive(Subcommand)]
pub(crate) enum Commands {
/// Initialize the folder for fav
Init {
#[arg(value_enum)]
kind: Kind,
/// The path to store the fav
path: Option<std::path::PathBuf>,
},
/// Login your account
Auth {
/// Login method
#[clap(subcommand)]
subcmd: AuthCommands,
},
/// Fetch from remote
Fetch {
/// Prune data no longer on remote
#[arg(long, short)]
prune: bool,
},
/// Show status of local, default to show video status
Status {
/// Show resource status
id: Option<String>,
/// Show all list status
#[arg(long, short)]
list: bool,
/// Show all video status
#[arg(long, short)]
video: bool,
/// Show tracked only
#[arg(long, short)]
tracked: bool,
},
/// Track a remote source
Track {
/// The id of the source to track
id: Vec<String>,
},
/// Untrack a remote source
Untrack {
/// The id of the source to untrack
id: Vec<String>,
},
/// Pull remote data
Pull {
/// The id of the source to pull
id: Option<Vec<String>>,
},
/// Push local data
Push,
/// Like a video
Like {
/// The id of the video to like
bvid: Option<Vec<String>>,
/// Like all videos tracked
#[arg(long, short)]
all: bool,
},
/// Set the path of ffmpeg
Ffmpeg {
/// Set the path of ffmpeg
path: String,
},
/// Interval fetch and pull
Daemon {
/// The interval to fetch and pull (in minutes, greater than 15)
interval: u64,
},
/// Modify resource status
Modify {
/// The id of the resources to modify
id: Vec<String>,
/// Mark saved true or false
#[arg(long, short)]
saved: Option<bool>,
/// modify the clarity
#[arg(long, short, value_enum)]
clarity: Option<Qn>,
},
}

#[derive(Subcommand)]
pub(crate) enum AuthCommands {
/// Login with password
Login,
/// Login with QR code
Logout,
}

#[derive(ValueEnum, Clone, Debug)]
#[cfg_attr(test, derive(PartialEq))]
pub(crate) enum Kind {
#[cfg(feature = "bili")]
Bili,
}

#[derive(Clone)]
enum Qn {
Default = 0,
EightK = 127,
Dolby = 126,
HDR = 125,
FourK = 120,
FullHDHighFrame = 116,
FullHDHighCode = 112,
FullHD = 80,
HDHighFrame = 74,
HD = 64,
SD = 32,
LD = 16,
VLD = 6,
}

impl ValueEnum for Qn {
fn value_variants<'a>() -> &'a [Self] {
&[
Self::Default,
Self::EightK,
Self::Dolby,
Self::HDR,
Self::FourK,
Self::FullHDHighFrame,
Self::FullHDHighCode,
Self::FullHD,
Self::HDHighFrame,
Self::HD,
Self::SD,
Self::LD,
Self::VLD,
]
}

fn to_possible_value(&self) -> Option<PossibleValue> {
match self {
Qn::Default => Some(PossibleValue::new("default")),
Qn::EightK => Some(PossibleValue::new("8k")),
Qn::Dolby => Some(PossibleValue::new("dolby")),
Qn::HDR => Some(PossibleValue::new("hdr")),
Qn::FourK => Some(PossibleValue::new("4k")),
Qn::FullHDHighFrame => Some(PossibleValue::new("1080p60")),
Qn::FullHDHighCode => Some(PossibleValue::new("1080p+")),
Qn::FullHD => Some(PossibleValue::new("1080p")),
Qn::HDHighFrame => Some(PossibleValue::new("720p60")),
Qn::HD => Some(PossibleValue::new("720p")),
Qn::SD => Some(PossibleValue::new("480p")),
Qn::LD => Some(PossibleValue::new("360p")),
Qn::VLD => Some(PossibleValue::new("240p")),
}
}
}
3 changes: 1 addition & 2 deletions src/cli/utils.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::proto::data::Qn;
use clap::{builder::PossibleValue, ValueEnum};
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use std::sync::OnceLock;
Expand All @@ -6,8 +7,6 @@ use tabled::{
settings::{object::Rows, Alignment, Style},
};

use crate::proto::data::Qn;

pub(crate) fn show_table<H, R>(header: H, rows: R)
where
H: IntoIterator,
Expand Down

0 comments on commit aa2a84c

Please sign in to comment.