structopt, clap のいずれの "validator" としても使える関数の定義方法

structopt の validator として指定する関数は
fn f(v: String) -> Result<...>
である必要があります。
一方、clapのvalidatorは
fn f(v: &str) -> Result<...>
である必要があります。

引数部分の型が違うので AsRef<str> を受け取る関数を作れば、両方のvalidatorとして使えるかと思いした。

しかし、clap側のインターフェースにはライフタイムに関して問題が置きます。
Higher-Order Trait Bound によるライフタイム指定が必要なのかもしれませんが、なかなかうまくいきません。
(そもそも私は Higher-Order Trait Boundに関する詳しくありません。)

以下のコードの structopt, clap 両方の validatorとして使える関数を用意したい場合、以下のコードの validator_for_general をどのように定義すればよいでしょうか?

rust

use clap::Parser;use std::path::PathBuf;use structopt::StructOpt; fn existing_file(pathbuf: PathBuf) -> Result<(), String> { if pathbuf.is_file() { Ok(()) } else { Err(format!("No such file {:?})", pathbuf)) }} pub fn validator_for_general<P>(filepath: P) -> Result<(), String>where P: AsRef<str>,{ let pathbuf = PathBuf::from(filepath.as_ref()); existing_file(pathbuf)} #[derive(Parser)]struct ClapArgs { #[clap(validator = validator_for_general)] file1: PathBuf,} #[derive(StructOpt)]struct StructOptArgs { #[structopt(validator = validator_for_general)] file1: PathBuf,} fn main() {}

error[E0308]: mismatched types | 34 | #[clap(validator = validator_for_general)] | ^^^^^^^^^ lifetime mismatch | = note: expected type `<fn(&str) -> Result<(), std::string::String> {validator_for_general::<&str>} as FnOnce<(&str,)>>` found type `<fn(&str) -> Result<(), std::string::String> {validator_for_general::<&str>} as FnOnce<(&str,)>>` note: the required lifetime does not necessarily outlive the lifetime `'b` as defined here | 29 | #[derive(Parser)] | ^^^^^^ note: the lifetime requirement is introduced here | 1535 | F: FnMut(&str) -> Result<O, E> + Send + 'help, | ^^^^^^^^^^^^ = note: this error originates in the derive macro `Parser` (in Nightly builds, run with -Z macro-backtrace for more info) For more information about this error, try `rustc --explain E0308`. error: could not compile `argumnet_validator_general_interface` due to previous error

各種バージョン

  • rustc 1.60.0 (7737e0b5c 2022-04-04)
  • clap: 3.1.18 (features = ["derive"])
  • structopt: 0.3.26

コメントを投稿

0 コメント