为了实现重建 GNU 核心实用程序的崇高目标,今天的工具是 mkdir 我们用来在 Linux 上创建目录的工具。让我们开始吧。

Pseudo Code 伪代码
args = command_line_arguments
remove the first element of the args vector
if args.length == 0 {print error_message
}
else if args.contains("--help") {print help_message
} else {for directory_name in args {create_directory(directory_name)}
}Okay that looks simple enough let’s start with new cargo library crate and create a simple struct and a new function
 好吧,看起来很简单,让我们从新的货物库箱开始,创建一个简单的结构体和一个 new 函数
pub struct Config<'a>{pub dir_names: &'a Vec<String>
}impl Config<'_>{pub fn new(args: &Vec<String>) -> Config {Config {dir_names: args}}
}Let’s make our work a little bit easier by creating private functions for help and not_enough_arguments
 让我们为 help 和 not_enough_arguments 创建私有函数,让我们的工作变得更容易一些
impl Config<'_>{pub fn new(args: &Vec<String>) -> Config{Config { dir_names: args }}fn not_enough_arguments(){eprintln!("mkdir: missing operand");eprintln!("For help use: mkdir --help");}fn help(){eprintln!("This is a cheap little clone of the mkdir utility in the GNU core utilities, the catch is that I made it in rust, check out more of my work at medium: https://shafinmurani.medium.com");eprintln!("To use this util: mkdir folder_name1 folder_name2 ... folder_nameN");}}Now that the basics are setup, we will create a binary crate, main.rs
 现在基础知识已经设置完毕,我们将创建一个二进制板条箱, main.rs
use mkdir::Config; //use your cratename::structName here
use std::env;fn main(){let mut args: Vec<String> = env::args.collect();args.remove(0);let config == Config::new(&args);
}This will instantiate our Config struct, now getting to the important part…
 这将实例化我们的 Config 结构,现在进入重要部分......
To create a directory, there are two functions in the fs crate , fs::create_dir() and fs::create_dir_all() . I will leave you with the task to find their differences and why we will be using create_dir_all(). Here’s a resource for you to research it create_dir() and create_dir_all()
 要创建目录, fs crate 中有两个函数, fs::create_dir() 和 fs::create_dir_all() 。我将留给您找出它们的差异以及为什么我们将使用 create_dir_all() 的任务。这里有一个资源供您研究 create_dir() 和 create_dir_all()
Let’s create a function which will create a directory in out impl block…
 让我们创建一个函数,它将在 impl 块中创建一个目录......
fn create_dir(dir: String) -> std::io::Result<()> {fs::create_dir_all(dir)?;Ok(())
}It returns a Result indicating success or failure, As of now here’s what our lib.rs file looks like
 它返回一个 Result 指示成功或失败,到目前为止,这是我们的 lib.rs 文件的样子
pub struct Config<'a>{pub dir_names: &'a Vec<String>
}impl Config<'_>{pub fn new(args: &Vec<String>) -> Config{Config { dir_names: args }}fn not_enough_arguments(){eprintln!("mkdir: missing operand");eprintln!("For help use: mkdir --help");}fn help(){eprintln!("This is a cheap little clone of the mkdir utility in the GNU core utilities, the catch is that I made it in rust, check out more of my work at medium: https://shafinmurani.medium.com");eprintln!("To use this util: mkdir folder_name1 folder_name2 ... folder_nameN");}fn create_dir(dir: String) -> std::io::Result<()> {fs::create_dir_all(dir)?;Ok(())}}Now we have everything we’ll need to make a directory, so let’s make one?
 现在我们已经拥有了制作目录所需的一切,那么让我们制作一个目录吧?
We will create a run function, which takes a reference to self and call our private function in there according to the conditons we specified in out pseudo code
 我们将创建一个 run 函数,它引用 self 并根据我们在伪代码中指定的条件调用我们的私有函数
pub fn run(&self){if self.dir_names.len() == 0 {Self.not_enough_arguments();} else if self.dir_names.contains(&String::from("--help")) {Self.help();} else {for dir in self.dir_names {let result = Self::create_dir(dir.to_string());}}
}This program does work but we don’t really have any error handling taking place here…
 该程序确实有效,但我们实际上没有进行任何错误处理......
Let’s fix that 让我们解决这个问题
pub fn run(&self){if self.dir_names.len() == 0 {Self.not_enough_arguments();} else if self.dir_names.contains(&String::from("--help")) {Self.help();} else {for dir in self.dir_names {let result = Self::create_dir(dir.to_string());match result {Ok(()) => {},Err(e) => {eprintln!("{}",e)},};}}
}Now we can call the run function in our main.rs file…
 现在我们可以在 main.rs 文件中调用 run 函数......
use mkdir::Config;
use std::env;
fn main() {let mut args: Vec<String> = env::args().collect();args.remove(0);let config = Config::new(&args);config.run();
}GitHub 仓库:shafinmurani/gnu-core-utils-rust (github.com)
Summary 概括
Lib.rs 库
- Defines a Rust library module.
 定义 Rust 库模块。
- Contains the Configstruct and its implementation.
 包含Config结构及其实现。
- Configstruct:- Config结构:
- Holds a reference to a vector of strings (dir_names) representing directory names to be created.
 保存对表示要创建的目录名称的字符串向量 (dir_names) 的引用。
Implementation block impl Config<'_>:
 实现块 impl Config<'_> :
- newfunction:- new功能:
- Constructs a new Configinstance, taking a reference to a vector of strings (args) as input.
 构造一个新的Config实例,将对字符串向量 (args) 的引用作为输入。
not_enough_arguments function:  not_enough_arguments 功能:
- Prints an error message to standard error if no directory names are provided as arguments.
 如果没有提供目录名称作为参数,则将错误消息打印到标准错误。
help function:  help 功能:
- Prints a help message to standard error explaining how to use the program.
 将帮助消息打印到标准错误,解释如何使用该程序。
create_dir function:  create_dir 功能:
- Attempts to create a directory specified by the input string using the fs::create_dir_allfunction from the standard library. It returns aResultindicating success or failure.
 尝试使用标准库中的fs::create_dir_all函数创建由输入字符串指定的目录。它返回一个Result指示成功或失败。
run function:  run 功能:
- Executes the logic of the program.
 执行程序的逻辑。
- If no directory names are provided, it prints a “missing operand” error message.
 如果未提供目录名称,则会打印“缺少操作数”错误消息。
- If the --helpargument is provided, it prints the help message.
 如果提供了--help参数,它将打印帮助消息。
- Otherwise, it iterates through the provided directory names, attempting to create each directory and printing any encountered errors.
 否则,它会迭代提供的目录名称,尝试创建每个目录并打印遇到的任何错误。
Main.rs
- Defines the entry point of the program.
 定义程序的入口点。
- Imports the Configstruct from themkdirmodule (defined inlib.rs) usinguse mkdir::Config.
 使用use mkdir::Config从mkdir模块(在lib.rs中定义)导入Config结构体。
- Imports the envmodule from the standard library, used to access command-line arguments.
 从标准库导入env模块,用于访问命令行参数。
- mainfunction:- main功能:
- Retrieves command-line arguments using env::args()and collects them into a vector (args).
 使用env::args()检索命令行参数并将它们收集到向量中 (args)。
- Removes the first argument, which is the name of the program itself, using args.remove(0).
 使用args.remove(0)删除第一个参数,即程序本身的名称。
- Constructs a Configinstance (config) with the remaining arguments usingConfig::new(&args).
 使用Config::new(&args)构造一个Config实例 (config) 以及其余参数。
- Calls the runmethod on theconfiginstance to execute the program's logic.
 调用config实例上的run方法来执行程序的逻辑。