<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          文盤Rust——起手式,CLI程序

          共 1417字,需瀏覽 3分鐘

           ·

          2022-04-15 00:45

          學(xué)習(xí)一門計(jì)算機(jī)語(yǔ)言和學(xué)習(xí)人類語(yǔ)言有很多共通之處。我們學(xué)習(xí)人類語(yǔ)言是從單個(gè)的詞開始,然后是簡(jiǎn)單句子,通過(guò)不斷的與他人交互練習(xí)掌握語(yǔ)法和語(yǔ)言習(xí)慣。當(dāng)熟練到一定程度就可以表達(dá)思想。計(jì)算的語(yǔ)言也差不多,熟悉關(guān)鍵詞,基本邏輯,標(biāo)準(zhǔn)庫(kù),寫應(yīng)用。只是溝通的對(duì)象是機(jī)器而已。
          既然是學(xué)就不能在開始搞的太難。學(xué)習(xí)本來(lái)就是個(gè)艱苦的差事。上來(lái)就干特別復(fù)雜的事情往往會(huì)堅(jiān)持不下去。天下難事必做于易,從簡(jiǎn)入繁,從易到難,方為正道。
          先聊聊最簡(jiǎn)單的CLI(Command Line Interface)程序。其實(shí)我們每學(xué)習(xí)一門語(yǔ)言的 hello world 程序就是CLI,只是沒(méi)那么多交互而已。
          做命令行程序最繁瑣的事情是處理交互。交互大體分兩種。一種是我們最熟悉shell下的交互模式,每次一個(gè)命令,配合參數(shù)實(shí)現(xiàn)一次處理返回一組結(jié)果。這種模式處理起來(lái)比較容易R(shí)ust也有相當(dāng)優(yōu)秀的第三方lib?(clap)。第二種是領(lǐng)域交互,就像我是使用MySql或者redis的客戶端程序。這種程序可以玩兒的東西就比較多了像如何實(shí)現(xiàn)交互,如何來(lái)做子命令的提示。這些東西 clap 并沒(méi)有提供,需要我們自己來(lái)實(shí)現(xiàn)。
          interactcli-rs是我在工作過(guò)程中做的一個(gè)交互模式命令行腳手架。實(shí)現(xiàn)了一些常用功能。
          下面我們來(lái)看看如何通過(guò)幾個(gè)步驟快速的實(shí)現(xiàn)一個(gè)功能相對(duì)齊全的CLI程序。和做飯一樣,能夠快速獲得成就感的方式是找半成品直接下鍋炒一盤:)。
          下面我們具體看看,如何通過(guò)interactcli-rs實(shí)現(xiàn)一個(gè)功能齊全的命令行程序

          來(lái)點(diǎn)感性認(rèn)識(shí)

          先把項(xiàng)目clone下來(lái)運(yùn)行個(gè)例子
          • clone 項(xiàng)目

            git?clone?https://github.com/jiashiwen/interactcli-rs.git
            cd?interactcli-rs

          • 命令行模式

            cargo?run?requestsample?baidu

          • 交互模式

            cargo?run?--?-i
            interact-rs>?requestsample?baidu

          運(yùn)行上面的命令是通過(guò)http來(lái)請(qǐng)求百度

          四步做個(gè)CLI

          首先我們先來(lái)看看框架的目錄結(jié)構(gòu)

          .
          ├──?examples
          ├──?log
          ├──?logs
          └──?src
          ????├──?cmd
          ????├──?commons
          ????├──?configure
          ????├──?interact
          ????├──?logger
          ????└──?request
          cmd目錄是我們做自己功能時(shí)要?jiǎng)拥闹饕夸洠旅嫖覀円徊揭徊降膶?shí)現(xiàn)requestsample命令。
          • 定義命令 cmd 模塊用于定義命令以及相關(guān)子命令,requestsample.rs 中定義了訪問(wèn)百度的命令

            use?clap::Command;
            ??
            pub?fn?new_requestsample_cmd()?->?Command<'static>?{
            clap::Command::new("requestsample")
            .about("requestsample")
            .subcommand(get_baidu_cmd())
            }

            pub?fn?get_baidu_cmd()?->?Command<'static>?{
            clap::Command::new("baidu").about("request?www.baidu.com")
            }

            new_requestsample_cmd 函數(shù)定義了命令 "requestsample",get_baidu_cmd 函數(shù)定義了 requestsample 的子命令 baidu

          • 注冊(cè)命令 src/cmd/rootcmd.rs 文件中定義了命令樹,可以在此注冊(cè)定義好的子命令

            lazy_static!?{
            ????static?ref?CLIAPP:?clap::Command<'static>?=?clap::Command::new("interact-rs")
            ????????.version("1.0")
            ????????.author("Your?Name.?")
            ????????.about("command?line?sample")
            ????????.arg_required_else_help(true)
            ????????.arg(
            ????????????Arg::new("config")
            ????????????????.short('c')
            ????????????????.long("config")
            ????????????????.value_name("FILE")
            ????????????????.help("Sets?a?custom?config?file")
            ????????????????.takes_value(true)
            ????????)
            ????????.arg(
            ????????????Arg::new("daemon")
            ????????????????.short('d')
            ????????????????.long("daemon")
            ????????????????.help("run?as?daemon")
            ????????)
            ????????.arg(
            ????????????Arg::new("interact")
            ????????????????.short('i')
            ????????????????.long("interact")
            ????????????????.conflicts_with("daemon")
            ????????????????.help("run?as?interact?mod")
            ????????)
            ????????.arg(
            ????????????Arg::new("v")
            ????????????????.short('v')
            ????????????????.multiple_occurrences(true)
            ????????????????.takes_value(true)
            ????????????????.help("Sets?the?level?of?verbosity")
            ????????)
            ????????.subcommand(new_requestsample_cmd())
            ????????.subcommand(new_config_cmd())
            ????????.subcommand(new_multi_cmd())
            ????????.subcommand(new_task_cmd())
            ????????.subcommand(new_loop_cmd())
            ????????.subcommand(
            ????????????clap::Command::new("test")
            ????????????????.about("controls?testing?features")
            ????????????????.version("1.3")
            ????????????????.author("Someone?E.?")
            ????????????????.arg(
            ????????????????????Arg::new("debug")
            ????????????????????????.short('d')
            ????????????????????????.help("print?debug?information?verbosely")
            ????????????????)
            ????????);
            ????static?ref?SUBCMDS:?Vec?=?subcommands();
            }

            pub?fn?run_app()?{
            ????let?matches?=?CLIAPP.clone().get_matches();
            ????if?let?Some(c)?=?matches.value_of("config")?{
            ????????println!("config?path?is:{}",?c);
            ????????set_config_file_path(c.to_string());
            ????}
            ????set_config(&get_config_file_path());
            ????cmd_match(&matches);
            }

            pub?fn?run_from(args:?Vec<String>)?{
            ????match?clap_Command::try_get_matches_from(CLIAPP.to_owned(),?args.clone())?{
            ????????Ok(matches)?=>?{
            ????????????cmd_match(&matches);
            ????????}
            ????????Err(err)?=>?{
            ????????????err.print().expect("Error?writing?Error");
            ????????}
            ????};
            }

            定義好的命令不需其他處理,框架會(huì)在系統(tǒng)運(yùn)行時(shí)生成子命令樹,用于在領(lǐng)域交互模式下命令提示的支持

          • 命令解析 src/cmd/rootcmd.rs 中的 cmd_match 負(fù)責(zé)解析命令,可以把解析邏輯寫在該函數(shù)中

            fn?cmd_match(matches:?&ArgMatches)?{???
            ??if?let?Some(ref?matches)?=?matches.subcommand_matches("requestsample")?{
            ??????if?let?Some(_)?=?matches.subcommand_matches("baidu")?{
            ??????????let?rt?=?tokio::runtime::Runtime::new().unwrap();
            ??????????let?async_req?=?async?{
            ??????????????let?result?=?req::get_baidu().await;
            ??????????????println!("{:?}",?result);
            ??????????};
            ??????????rt.block_on(async_req);
            ??????};
            ??}
            }

          • 修改交互模式的命令提示 提示符可以在src/interact/cli.rs 中定義

            pub?fn?run()?{
            ??
            ??...

            ??loop?{
            ??????let?p?=?format!("{}>?",?"interact-rs");
            ??????rl.helper_mut().expect("No?helper").colored_prompt?=?format!("\x1b[1;32m{}\x1b[0m",?p);

            ??????...
            ??}
            ??
            ??...
            }

          下次為大家介紹一下interactcli-rs各種功能是如何實(shí)現(xiàn)的。

          - End -

          ??更多了解??


          瀏覽 71
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  精品免费国产一区二区三区四区的使用方法 | 亚洲中文字幕剧情 | 小骚逼网站 | 天堂18禁| 操屄免费视频 |