【Rust】6、练习:自己实现 ls

文章目录

  • 一、CLI Utilities

Rust 学完,想找些练手的项目,怎么办?可参考这个文章,列出的 15 个项目。

一、CLI Utilities

github

参考
lsd 项目地址

cargo.toml

[dependencies]
clap = "2"

main.rs

extern crate clap;

use clap::{App, Arg};

fn main() {
    let app = App::new("l")
        .version("1.0.0")
        .author("y")
        .about("this is a l")
        .arg(
            Arg::with_name("all")
                .short("a")
                .help("show all file and dir"),
        )
        .arg(Arg::with_name("long").short("l").help("show file all info"))
        .arg(Arg::with_name("FILE").multiple(true).default_value("."))
        .get_matches();
    let all = app.is_present("all");
    let long = app.is_present("long");
    let files: Vec<&str> = app.values_of("FILE").expect("not get any file").collect();
    println!("all: {}, long: {}, File: {:?}", all, long, files);
}

运行已经可以收到命令行参数了,如下:

# cargo run
all: false, long: false, File: ["."]

# cargo run -- -a -l /tmp /etc
all: true, long: true, File: ["/tmp", "/etc"]

接下来读取某路径下的文件:

extern crate clap;

use std::{fs::read_dir, path::Path};

fn main() {
    let files = vec!["/Users"];
    for file in files {
        let path = Path::new(file);
        if path.is_dir() {
            println!("{} is a directory", file);
            let somes = read_dir(path).expect("not get this path");
            for some in somes {
                if let Ok(ref entry) = some {
                    let name = entry
                        .file_name()
                        .to_str()
                        .expect("file name convert str fail")
                        .to_string();
                    let data = entry.metadata().expect("no metadata");
                    println!("{} {:?}", name, data)
                }
            }
        }
    }
}

接下来把两个程序结合:

extern crate clap;

use clap::{App, Arg};
use std::fs::read_dir;
use std::os::unix::fs::PermissionsExt;
use std::path::Path;

#[derive(Debug)]
pub struct Option {
    display_all: bool,
    display_long: bool,
}

fn main() {
    let app = App::new("l")
        .version("1.0.0")
        .author("lome")
        .about("this is a l")
        .arg(
            Arg::with_name("all")
                .short("a")
                .help("Show all file and dir"),
        )
        .arg(Arg::with_name("long").short("l").help("show file all info"))
        .arg(Arg::with_name("FILE").multiple(true).default_value("."))
        .get_matches();

    let option = Option {
        display_all: app.is_present("all"),
        display_long: app.is_present("long"),
    };

    let files: Vec<&str> = app.values_of("FILE").expect("not get any file").collect();

    for file in files {
        let path = Path::new(file);
        if path.is_dir() {
            println!("{}: ", file);
            let somes = read_dir(path).expect("not get this path");
            for some in somes {
                if let Ok(ref entry) = some {
                    let name = entry
                        .file_name()
                        .to_str()
                        .expect("file name convert str fail")
                        .to_string();
                    let data = entry.metadata().expect("no metadata");
                    if option.display_long {
                        if option.display_all || !name.starts_with(".") {
                            let permission = data.permissions().mode();
                            let systime = data.modified().expect("get system time error");
                            println!(
                                "    {} Permission: {:o}  Systime: {:?}",
                                name, permission, systime
                            );
                        }
                    } else {
                        if option.display_all || !name.starts_with(".") {
                            println!("    {}", name);
                        }
                    }
                }
            }
        }
    }
}

// code result:
Output:
$ ./l  ./test/ ./test/test/
./test/: 
    test.txt
    test
./test/test/: 
    test.txt

$ ./l -a ./test/ ./test/test/
./test/: 
    test.txt
    test
    .test.txt
./test/test/: 
    test.txt

$ ./l -al ./test/ ./test/test/
./test/: 
    test.txt Permission: 100644  Systime: SystemTime { tv_sec: 1573805933, tv_nsec: 470337261 }
    test Permission: 40755  Systime: SystemTime { tv_sec: 1573805940, tv_nsec: 228706396 }
    .test.txt Permission: 100644  Systime: SystemTime { tv_sec: 1573806564, tv_nsec: 333715123 }
./test/test/: 
    test.txt Permission: 100644  Systime: SystemTime { tv_sec: 1573805940, tv_nsec: 228706396 }

你可能感兴趣的:(#,rust,rust,开发语言,后端)