0

我正在学习 Rust,我正在尝试转换一个简单的 Ruby 示例:

  1. 文件展开路径
  2. 文件连接路径
  3. 目录全局
  4. 打印在 Dir glob 中找到的文件

这是 Ruby 示例:

output_path = '~/Documents'
pattern = File.expand_path(File.join(output_path, '*', '**', '*.txt'))

Dir.glob(pattern) do |path|
  puts path
end

奖金 Nim 示例:

import os
import strformat
import glob

var outputPath = expandTilde("~/Documents")
var pattern = joinPath(outputPath, "*", "**", "*.txt")

for path in walkGlob(pattern):
  echo path

到目前为止,这是我对 Rust 所做的,但是,它没有构建:

use std::io;
use std::fs;
use std::path::PathBuf;
use glob::glob;

fn main() {
    let output_path: io::Result<PathBuf> = fs::canonicalize("~/Documents");
    let pattern: PathBuf = [output_path, "*", "**", "*.txt"].iter().collect();
    for entry in glob(pattern).expect("Failed to read glob pattern") {
        match entry {
            Ok(path) => println!("{:?}", path.display()),
            Err(e) => println!("{:?}", e),
        }
    }
}

我尝试了不同的变化,但没有成功。

我不确定fs::canonicalize是否真的扩展了波浪号路径。我发现了一个旧的板条箱:shellexpand::tilde。但是,我不知道如何处理它给出的输出。它不是一个strString

我也不确定是否需要多个级别的matchonResultOption其中一些的返回值。最终glob想要 astr并且在我的所有变体中,第一个output_path值会搞砸,或者我不知道如何将其转换为str.

我错过了什么?这样做的惯用方法是什么?到目前为止,我尝试过的方法似乎过于冗长。有没有一种简单的方法可以做到这一点?

更新

如果我硬编码扩展路径,我最终让它工作:

use std::path::PathBuf;
use glob::glob;

fn main() {
    let pattern_path_buf: PathBuf = ["", "/Users", "ejstembler", "Documents", "*", "**", "*.txt"].iter().collect();
    match pattern_path_buf.to_str() {
        Some(pattern) => {
            println!("{:?}", pattern);
            for entry in glob(pattern).expect("Failed to read glob pattern") {
                match entry {
                    Ok(path) => println!("{:?}", path.display()),
                    Err(e) => println!("{:?}", e),
                }
            }
        },
        None => println!("no pattern_path_buf")
    }
}

一个奇怪的细微差别是,我必须在 PathBuf "" 的开头添加一个空白字符串以使其包含前导正斜杠,否则它将丢失。我发现有std::path::MAIN_SEPARATOR,但是,我不知道如何将 a 转换char为 a &str

无论如何,@Joe_Jingyu提供了可接受的答案shellexpand::tilde。谢谢乔!

4

1 回答 1

1

这是我使用shellexpand::tilde扩展波浪号的代码。

use std::path::PathBuf;
use glob::glob;
use shellexpand;

fn main() {
    let expanded_path = shellexpand::tilde("~/Documents/");
    let pattern : PathBuf = [&expanded_path, "*", "**", "*.txt"].iter().collect();

    for entry in glob(pattern.to_str().unwrap()).expect("Failed to read glob pattern") {
        match entry {
            Ok(path) => println!("{:?}", path.display()),
            Err(e) => println!("{:?}", e),
        }
    }
}

这是一篇关于如何从shellexpand::tilde返回的 Cow 中获取 &str 的帖子。

于 2021-09-19T11:24:35.197 回答