Skip to content

Latest commit

 

History

History
47 lines (37 loc) · 1.3 KB

loops.zh.md

File metadata and controls

47 lines (37 loc) · 1.3 KB

查找给定路径的循环

[![same_file-badge]][same_file] [![cat-filesystem-badge]][cat-filesystem]

使用same_file::is_same_file检测给定路径的循环。例如,可以通过符号链接,在 UNIX 系统上,创建一个循环:

mkdir -p /tmp/foo/bar/baz
ln -s /tmp/foo/  /tmp/foo/bar/baz/qux

/tmp/foo/bar/baz/qux == /tmp/foo/ => /tmp/foo/bar/baz => /tmp/foo/bar/baz/qux (重复循环)

下面将断言,存在一个循环。

extern crate same_file;

use std::io;
use std::path::{Path, PathBuf};
use same_file::is_same_file;

fn contains_loop<P: AsRef<Path>>(path: P) -> io::Result<Option<(PathBuf, PathBuf)>> {
    let path = path.as_ref();
    let mut path_buf = path.to_path_buf();
    while path_buf.pop() {
        if is_same_file(&path_buf, path)? {
            return Ok(Some((path_buf, path.to_path_buf())));
        } else if let Some(looped_paths) = contains_loop(&path_buf)? {
            return Ok(Some(looped_paths));
        }
    }
    return Ok(None);
}

fn main() {
    assert_eq!(
        contains_loop("/tmp/foo/bar/baz/qux/bar/baz").unwrap(),
        Some((
            PathBuf::from("/tmp/foo"),
            PathBuf::from("/tmp/foo/bar/baz/qux")
        ))
    );
}