refactor: move clap structs into separate files

Lets us avoid unnecessary build dependencies.
This commit is contained in:
Donovan Glover
2024-07-31 15:57:30 -04:00
committed by Ivan Molodetskikh
parent 0521c53640
commit 08d1634aff
5 changed files with 147 additions and 142 deletions

View File

@@ -1,4 +1,3 @@
use std::ffi::OsString;
use std::fs::OpenOptions;
use std::os::unix::ffi::OsStringExt;
@@ -6,99 +5,28 @@ use clap::Parser;
use libc::fork;
use rustix::stdio::{dup2_stdin, dup2_stdout};
use wl_clipboard_rs::copy::{self, clear, ClipboardType, MimeType, Seat, ServeRequests, Source};
use wl_clipboard_rs_tools::wl_copy::Options;
#[derive(Parser)]
#[command(
name = "wl-copy",
version,
about = "Copy clipboard contents on Wayland."
)]
struct Options {
/// Serve only a single paste request and then exit
///
/// This option effectively clears the clipboard after the first paste. It can be used when
/// copying e.g. sensitive data, like passwords. Note however that certain apps may have issues
/// pasting when this option is used, in particular XWayland clients are known to suffer from
/// this.
#[arg(long, short = 'o', conflicts_with = "clear")]
paste_once: bool,
/// Stay in the foreground instead of forking
#[arg(long, short, conflicts_with = "clear")]
foreground: bool,
/// Clear the clipboard instead of copying
#[arg(long, short)]
clear: bool,
/// Use the "primary" clipboard
///
/// Copying to the "primary" clipboard requires the compositor to support the data-control
/// protocol of version 2 or above.
#[arg(long, short)]
primary: bool,
/// Use the regular clipboard
///
/// Set this flag together with --primary to operate on both clipboards at once. Has no effect
/// otherwise (since the regular clipboard is the default clipboard).
#[arg(long, short)]
regular: bool,
/// Trim the trailing newline character before copying
///
/// This flag is only applied for text MIME types.
#[arg(long, short = 'n', conflicts_with = "clear")]
trim_newline: bool,
/// Pick the seat to work with
///
/// By default wl-copy operates on all seats at once.
#[arg(long, short)]
seat: Option<String>,
/// Override the inferred MIME type for the content
#[arg(
name = "MIME/TYPE",
long = "type",
short = 't',
conflicts_with = "clear"
)]
mime_type: Option<String>,
/// Text to copy
///
/// If not specified, wl-copy will use data from the standard input.
#[arg(name = "TEXT TO COPY", conflicts_with = "clear")]
text: Vec<OsString>,
/// Enable verbose logging
#[arg(long, short, action = clap::ArgAction::Count)]
verbose: u8,
}
impl From<Options> for copy::Options {
fn from(x: Options) -> Self {
let mut opts = copy::Options::new();
opts.serve_requests(if x.paste_once {
ServeRequests::Only(1)
fn from_options(x: Options) -> wl_clipboard_rs::copy::Options {
let mut opts = copy::Options::new();
opts.serve_requests(if x.paste_once {
ServeRequests::Only(1)
} else {
ServeRequests::Unlimited
})
.foreground(true) // We fork manually to support background mode.
.clipboard(if x.primary {
if x.regular {
ClipboardType::Both
} else {
ServeRequests::Unlimited
})
.foreground(true) // We fork manually to support background mode.
.clipboard(if x.primary {
if x.regular {
ClipboardType::Both
} else {
ClipboardType::Primary
}
} else {
ClipboardType::Regular
})
.trim_newline(x.trim_newline)
.seat(x.seat.map(Seat::Specific).unwrap_or_default());
opts
}
ClipboardType::Primary
}
} else {
ClipboardType::Regular
})
.trim_newline(x.trim_newline)
.seat(x.seat.map(Seat::Specific).unwrap_or_default());
opts
}
fn main() -> Result<(), anyhow::Error> {
@@ -152,7 +80,7 @@ fn main() -> Result<(), anyhow::Error> {
};
let foreground = options.foreground;
let prepared_copy = copy::Options::from(options).prepare_copy(source, mime_type)?;
let prepared_copy = from_options(options).prepare_copy(source, mime_type)?;
if foreground {
prepared_copy.serve()?;

View File

@@ -10,55 +10,7 @@ use log::trace;
use mime_guess::Mime;
use wl_clipboard_rs::paste::*;
use wl_clipboard_rs::utils::is_text;
#[derive(Parser)]
#[command(
name = "wl-paste",
version,
about = "Paste clipboard contents on Wayland."
)]
struct Options {
/// List the offered MIME types instead of pasting
#[arg(long, short)]
list_types: bool,
/// Use the "primary" clipboard
///
/// Pasting to the "primary" clipboard requires the compositor to support the data-control
/// protocol of version 2 or above.
#[arg(long, short)]
primary: bool,
/// Do not append a newline character
///
/// By default the newline character is appended automatically when pasting text MIME types.
#[arg(long, short, conflicts_with = "list_types")]
no_newline: bool,
/// Pick the seat to work with
///
/// By default the seat used is unspecified (it depends on the order returned by the
/// compositor). This is perfectly fine when only a single seat is present, so for most
/// configurations.
#[arg(long, short)]
seat: Option<String>,
/// Request the given MIME type instead of inferring the MIME type
///
/// As a special case, specifying "text" will look for a number of plain text types,
/// prioritizing ones that are known to give UTF-8 text.
#[arg(
name = "MIME/TYPE",
long = "type",
short = 't',
conflicts_with = "list_types"
)]
mime_type: Option<String>,
/// Enable verbose logging
#[arg(long, short, action = clap::ArgAction::Count)]
verbose: u8,
}
use wl_clipboard_rs_tools::wl_paste::Options;
fn infer_mime_type() -> Option<Mime> {
if let Ok(stdout_path) = read_link(format!("/dev/fd/{}", STDOUT_FILENO)) {

View File

@@ -0,0 +1,2 @@
pub mod wl_copy;
pub mod wl_paste;

View File

@@ -0,0 +1,73 @@
use std::ffi::OsString;
use clap::Parser;
#[derive(Parser)]
#[command(
name = "wl-copy",
version,
about = "Copy clipboard contents on Wayland."
)]
pub struct Options {
/// Serve only a single paste request and then exit
///
/// This option effectively clears the clipboard after the first paste. It can be used when
/// copying e.g. sensitive data, like passwords. Note however that certain apps may have issues
/// pasting when this option is used, in particular XWayland clients are known to suffer from
/// this.
#[arg(long, short = 'o', conflicts_with = "clear")]
pub paste_once: bool,
/// Stay in the foreground instead of forking
#[arg(long, short, conflicts_with = "clear")]
pub foreground: bool,
/// Clear the clipboard instead of copying
#[arg(long, short)]
pub clear: bool,
/// Use the "primary" clipboard
///
/// Copying to the "primary" clipboard requires the compositor to support the data-control
/// protocol of version 2 or above.
#[arg(long, short)]
pub primary: bool,
/// Use the regular clipboard
///
/// Set this flag together with --primary to operate on both clipboards at once. Has no effect
/// otherwise (since the regular clipboard is the default clipboard).
#[arg(long, short)]
pub regular: bool,
/// Trim the trailing newline character before copying
///
/// This flag is only applied for text MIME types.
#[arg(long, short = 'n', conflicts_with = "clear")]
pub trim_newline: bool,
/// Pick the seat to work with
///
/// By default wl-copy operates on all seats at once.
#[arg(long, short)]
pub seat: Option<String>,
/// Override the inferred MIME type for the content
#[arg(
name = "MIME/TYPE",
long = "type",
short = 't',
conflicts_with = "clear"
)]
pub mime_type: Option<String>,
/// Text to copy
///
/// If not specified, wl-copy will use data from the standard input.
#[arg(name = "TEXT TO COPY", conflicts_with = "clear")]
pub text: Vec<OsString>,
/// Enable verbose logging
#[arg(long, short, action = clap::ArgAction::Count)]
pub verbose: u8,
}

View File

@@ -0,0 +1,50 @@
use clap::Parser;
#[derive(Parser)]
#[command(
name = "wl-paste",
version,
about = "Paste clipboard contents on Wayland."
)]
pub struct Options {
/// List the offered MIME types instead of pasting
#[arg(long, short)]
pub list_types: bool,
/// Use the "primary" clipboard
///
/// Pasting to the "primary" clipboard requires the compositor to support the data-control
/// protocol of version 2 or above.
#[arg(long, short)]
pub primary: bool,
/// Do not append a newline character
///
/// By default the newline character is appended automatically when pasting text MIME types.
#[arg(long, short, conflicts_with = "list_types")]
pub no_newline: bool,
/// Pick the seat to work with
///
/// By default the seat used is unspecified (it depends on the order returned by the
/// compositor). This is perfectly fine when only a single seat is present, so for most
/// configurations.
#[arg(long, short)]
pub seat: Option<String>,
/// Request the given MIME type instead of inferring the MIME type
///
/// As a special case, specifying "text" will look for a number of plain text types,
/// prioritizing ones that are known to give UTF-8 text.
#[arg(
name = "MIME/TYPE",
long = "type",
short = 't',
conflicts_with = "list_types"
)]
pub mime_type: Option<String>,
/// Enable verbose logging
#[arg(long, short, action = clap::ArgAction::Count)]
pub verbose: u8,
}