【问题标题】:How can I access a runtime-defined variable in stuctopt definitions?如何在 stuctopt 定义中访问运行时定义的变量?
【发布时间】:2020-04-27 16:22:13
【问题描述】:

我希望能够使用变量的值(或者更好的是,function(arg) 的返回)作为使用 structopt 定义的 CLI 程序的 about 字符串。最终目标是一个完全本地化的 CLI,它可以检测系统语言或 ENV 变量并加载本地化的字符串,这些字符串会被烘焙到 --help 消息等中。

默认情况下它使用文档注释:

/// My about string
#[derive(StructOpt)]
struct Cli {}

我发现我可以传递手动输入的字符串:

#[derive(StructOpt)]
#[structopt(about = "My about string")]
struct Cli {}

这更近了一步,但我真正想做的是传递一个变量:

let about: &str = "My about string";
#[derive(StructOpt)]
#[structopt(about = var!(about))]
struct Cli {}

最后一个块是伪代码,因为我不知道使用什么语法来实现这一点。最后,我需要的不仅仅是一个字符串切片,但我认为这是一个开始的地方。

如何将这样的值传递给 structopt?我是否需要以某种方式访问​​底层的 clap 接口?

【问题讨论】:

    标签: rust localization clap structopt


    【解决方案1】:

    StructOpt 只是在 clap 上添加了一个派生宏和一个相应的特征。 clap crate 有一个set the about message at runtime 的函数,所以我们只需要添加它。如果我们查看 how from_args works,我们可以看到它在将其转换为用户定义的结构之前创建了 clap App 结构。

    因此,做你想做的事:

    use structopt::StructOpt;
    
    fn get_localized_about() -> &'static str {
        "localized string"
    }
    
    #[derive(Debug, StructOpt)]
    struct Foo {}
    
    fn main() {
        let foo = Foo::from_clap(&Foo::clap().about(get_localized_about()).get_matches());
        println!("{:#?}", foo);
    }
    

    【讨论】:

    • 谢谢,这肯定回答了我问的确切问题。不幸的是,我似乎过度简化了这个问题。这对于设置.about() 信息非常有用,但是对于我的选项、子命令及其参数等其他内容,我无法获得相同的效果。我想本地化 all 输出,而不仅仅是 About 字符串。如果我尝试与.arg() 大致相同的方法,我只能看到如何添加参数,而不是更改通过 StructOpt 添加的参数的描述。我在吠叫错误的树吗? StructOpt 看起来很可爱,但也许我应该直接使用 Clap。
    • 听起来您可能想研究 yaml 功能作为 crate 的一部分。您可以在单独的文件中指定所有内容,然后根据系统报告的本地化加载各种文件。这记录在自述文件中here
    • @Tinmidger 我实际上已经阅读了有关 Clap 的 YAML 支持的信息,但是使用它有两个问题。首先,所有文档都表明这是一个编译时选择,您可以在其中使用所需语言构建二进制文件。我想要运行时语言选择,而不是编译时。其次,我的翻译来自 Fluent,我对将它们放入 YAML 并不感到兴奋。如果第一个问题不是阻止程序,我可以自动生成 YAML。
    • 1) load_yaml! 是编译时间(因为它是一个宏),但如果你 look at it's source 很容易让它成为运行时选项。如果您不关心二进制大小,您可以include_str! 所有本地化的 yaml 文件(或者如果您不想要,在运行时使用这些文件),然后选择要使用的文件。然而,翻译来自流利的事实确实让事情变得更加困难。在这种情况下,我会放弃 StructOpt 并只使用 clap,或者使用单个 yaml 文件并根据本地化对其进行模板化
    • 我在这里学习 Rust 大约 3 天,使用宏源将编译时代码移动到运行时听起来可能需要等待一周左右。但感谢您的提示。我肯定想内联二进制文件中的字符串,因为如果我尝试加载资源,我会遇到路径问题。有三个运行场景,我必须做一些路径发现才能在找到 YAML 文件之前找出它是什么,如果这个过程出错,我希望能够显示本地化的错误消息!经典渔获 22。
    猜你喜欢
    • 2018-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 1970-01-01
    相关资源
    最近更新 更多