generated from PlexSheep/baserepo
idk why this isn't in master yet #94
|
@ -48,7 +48,7 @@ fn main() -> anyhow::Result<()> {
|
|||
Err(e) => {
|
||||
// if the user requested the help, print in blue, otherwise in red as it's just an
|
||||
// error
|
||||
if let libpt_cli::repl::error::ReplError::Parsing(e) = &e {
|
||||
if let libpt_cli::repl::error::Error::Parsing(e) = &e {
|
||||
if e.kind() == clap::error::ErrorKind::DisplayHelp {
|
||||
println!("{}", style(e).cyan());
|
||||
continue;
|
||||
|
@ -76,7 +76,7 @@ fn main() -> anyhow::Result<()> {
|
|||
if !fancy {
|
||||
println!("{}", text.join(" "))
|
||||
} else {
|
||||
printing::blockprint(text.join(" "), console::Color::Cyan)
|
||||
printing::blockprint(&text.join(" "), console::Color::Cyan)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,6 @@ Author: {author-with-newline}
|
|||
/// # use libpt_cli::args::VerbosityLevel;
|
||||
/// use libpt_log::Level;
|
||||
/// # use clap::Parser;
|
||||
/// use log;
|
||||
///
|
||||
/// # #[derive(Parser, Debug)]
|
||||
/// # pub struct Opts {
|
||||
|
@ -94,8 +93,6 @@ Author: {author-with-newline}
|
|||
/// // Level might be None if the user wants no output at all.
|
||||
/// // for the 'tracing' level:
|
||||
/// let level: Level = opts.verbose.level();
|
||||
/// // for the 'log' level:
|
||||
/// let llevel: log::Level = opts.verbose.level_for_log_crate();
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Parser, Clone, PartialEq, Eq, Hash)]
|
||||
|
|
|
@ -45,10 +45,11 @@ use console::{style, Color};
|
|||
/// use libpt_cli::console::Color;
|
||||
/// use libpt_cli::printing::blockprint;
|
||||
/// # fn main() {
|
||||
/// blockprint("Hello world!".to_string(), Color::Blue);
|
||||
/// blockprint("Hello world!", Color::Blue);
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
#[allow(clippy::needless_pass_by_value)] // we just take an impl, using a &impl is much less ergonomic
|
||||
pub fn blockprint(content: impl ToString, color: Color) {
|
||||
println!("{}", blockfmt(content, color));
|
||||
}
|
||||
|
@ -66,11 +67,12 @@ pub fn blockprint(content: impl ToString, color: Color) {
|
|||
/// use libpt_cli::console::Color;
|
||||
/// use libpt_cli::printing::blockfmt;
|
||||
/// # fn main() {
|
||||
/// let formatted_content = blockfmt("Hello world!".to_string(), Color::Blue);
|
||||
/// let formatted_content = blockfmt("Hello world!", Color::Blue);
|
||||
/// println!("{}", formatted_content);
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
#[allow(clippy::needless_pass_by_value)] // we just take an impl, using a &impl is much less ergonomic
|
||||
pub fn blockfmt(content: impl ToString, color: Color) -> String {
|
||||
blockfmt_advanced(
|
||||
content,
|
||||
|
@ -98,7 +100,7 @@ pub fn blockfmt(content: impl ToString, color: Color) -> String {
|
|||
/// println!(
|
||||
/// "{}",
|
||||
/// blockfmt_advanced(
|
||||
/// "Hello world!".to_string(),
|
||||
/// "Hello world!",
|
||||
/// Some(Color::Blue),
|
||||
/// presets::UTF8_FULL,
|
||||
/// ContentArrangement::DynamicFullWidth,
|
||||
|
@ -120,6 +122,8 @@ pub fn blockfmt(content: impl ToString, color: Color) -> String {
|
|||
/// - `preset`: The preset style for the border
|
||||
/// - `arrangement`: The arrangement of the the border (e.g., stretch to sides, wrap around )
|
||||
/// - `alignment`: The alignment of the content within the cells (e.g., left, center, right)
|
||||
#[allow(clippy::missing_panics_doc)] // we add a row then unwrap it, no panic should be possible
|
||||
#[allow(clippy::needless_pass_by_value)] // we just take an impl, using a &impl is much less ergonomic
|
||||
pub fn blockfmt_advanced(
|
||||
content: impl ToString,
|
||||
color: Option<Color>,
|
||||
|
|
|
@ -56,11 +56,10 @@ use libpt_log::trace;
|
|||
#[embed_doc_image("repl_screenshot", "data/media/repl.png")]
|
||||
#[derive(Parser)]
|
||||
#[command(multicall = true, help_template = REPL_HELP_TEMPLATE)]
|
||||
#[allow(clippy::module_name_repetitions)] // we can't just name it `Default`, that's part of std
|
||||
pub struct DefaultRepl<C>
|
||||
where
|
||||
C: Debug,
|
||||
C: Subcommand,
|
||||
C: strum::IntoEnumIterator,
|
||||
C: Debug + Subcommand + strum::IntoEnumIterator,
|
||||
{
|
||||
/// the command you want to execute, along with its arguments
|
||||
#[command(subcommand)]
|
||||
|
@ -81,18 +80,14 @@ where
|
|||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, PartialOrd, Ord)]
|
||||
struct DefaultReplCompletion<C>
|
||||
where
|
||||
C: Debug,
|
||||
C: Subcommand,
|
||||
C: strum::IntoEnumIterator,
|
||||
C: Debug + Subcommand + strum::IntoEnumIterator,
|
||||
{
|
||||
commands: std::marker::PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C> Repl<C> for DefaultRepl<C>
|
||||
where
|
||||
C: Debug,
|
||||
C: Subcommand,
|
||||
C: strum::IntoEnumIterator,
|
||||
C: Debug + Subcommand + strum::IntoEnumIterator,
|
||||
{
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
|
@ -106,7 +101,7 @@ where
|
|||
fn command(&self) -> &Option<C> {
|
||||
&self.command
|
||||
}
|
||||
fn step(&mut self) -> Result<(), super::error::ReplError> {
|
||||
fn step(&mut self) -> Result<(), super::error::Error> {
|
||||
self.buf.clear();
|
||||
|
||||
// NOTE: display::Input requires some kind of lifetime that would be a bother to store in
|
||||
|
@ -139,9 +134,7 @@ where
|
|||
|
||||
impl<C> Default for DefaultRepl<C>
|
||||
where
|
||||
C: Debug,
|
||||
C: Subcommand,
|
||||
C: strum::IntoEnumIterator,
|
||||
C: Debug + Subcommand + strum::IntoEnumIterator,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
|
@ -150,9 +143,7 @@ where
|
|||
|
||||
impl<C> Debug for DefaultRepl<C>
|
||||
where
|
||||
C: Debug,
|
||||
C: Subcommand,
|
||||
C: strum::IntoEnumIterator,
|
||||
C: Debug + Subcommand + strum::IntoEnumIterator,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("DefaultRepl")
|
||||
|
@ -167,16 +158,15 @@ where
|
|||
|
||||
impl<C> DefaultReplCompletion<C>
|
||||
where
|
||||
C: Debug,
|
||||
C: Subcommand,
|
||||
C: strum::IntoEnumIterator,
|
||||
C: Debug + Subcommand + strum::IntoEnumIterator,
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
/// Make a new [`DefaultReplCompletion`] for the type `C`
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
commands: std::marker::PhantomData::<C>,
|
||||
}
|
||||
}
|
||||
fn commands(&self) -> Vec<String> {
|
||||
fn commands() -> Vec<String> {
|
||||
let mut buf = Vec::new();
|
||||
// every crate has the help command, but it is not part of the enum
|
||||
buf.push("help".to_string());
|
||||
|
@ -199,9 +189,7 @@ where
|
|||
|
||||
impl<C> Default for DefaultReplCompletion<C>
|
||||
where
|
||||
C: Debug,
|
||||
C: Subcommand,
|
||||
C: strum::IntoEnumIterator,
|
||||
C: Debug + Subcommand + strum::IntoEnumIterator,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
|
@ -210,14 +198,11 @@ where
|
|||
|
||||
impl<C> Completion for DefaultReplCompletion<C>
|
||||
where
|
||||
C: Debug,
|
||||
C: Subcommand,
|
||||
C: strum::IntoEnumIterator,
|
||||
C: Debug + Subcommand + strum::IntoEnumIterator,
|
||||
{
|
||||
/// Simple completion implementation based on substring
|
||||
fn get(&self, input: &str) -> Option<String> {
|
||||
let matches = self
|
||||
.commands()
|
||||
let matches = Self::commands()
|
||||
.into_iter()
|
||||
.filter(|option| option.starts_with(input))
|
||||
.collect::<Vec<_>>();
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ReplError {
|
||||
pub enum Error {
|
||||
#[error(transparent)]
|
||||
Parsing(#[from] clap::Error),
|
||||
#[error(transparent)]
|
||||
Input(#[from] dialoguer::Error),
|
||||
#[error(transparent)]
|
||||
Other(#[from] anyhow::Error),
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
use std::fmt::Debug;
|
||||
|
||||
pub mod error;
|
||||
use error::ReplError;
|
||||
use error::Error;
|
||||
mod default;
|
||||
pub use default::*;
|
||||
|
||||
|
@ -25,9 +25,7 @@ use clap::{Parser, Subcommand};
|
|||
/// Unless you want to implement custom features (not just commands), just use [`DefaultRepl`].
|
||||
pub trait Repl<C>: Parser + Debug
|
||||
where
|
||||
C: Debug,
|
||||
C: Subcommand,
|
||||
C: strum::IntoEnumIterator,
|
||||
C: Debug + Subcommand + strum::IntoEnumIterator,
|
||||
{
|
||||
/// create a new repl
|
||||
fn new() -> Self;
|
||||
|
@ -40,5 +38,11 @@ where
|
|||
/// This should be used at the start of your loop.
|
||||
///
|
||||
/// Note that the help menu is an Error: [`clap::error::ErrorKind::DisplayHelp`]
|
||||
fn step(&mut self) -> Result<(), ReplError>;
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// * [`Error::Input`] – [dialoguer] User Input had some kind of I/O Error
|
||||
/// * [`Error::Parsing`] – [clap] could not parse the user input, or user requested help
|
||||
/// * [`Error::Other`] – Any other error with [anyhow], [`DefaultRepl`] does not use this but custom implementations might
|
||||
fn step(&mut self) -> Result<(), Error>;
|
||||
}
|
||||
|
|
Reference in New Issue