Skip to content

Commit 1138579

Browse files
committed
Add regression test for #20797. Fixes #20797.
1 parent b7ef34d commit 1138579

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

src/test/run-pass/issue-20797.rs

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Regression test for #20797.
12+
13+
use std::default::Default;
14+
use std::io::IoResult;
15+
use std::io::fs;
16+
use std::io::fs::PathExtensions;
17+
18+
/// A strategy for acquiring more subpaths to walk.
19+
pub trait Strategy {
20+
type P: PathExtensions;
21+
/// Get additional subpaths from a given path.
22+
fn get_more(&self, item: &Self::P) -> IoResult<Vec<Self::P>>;
23+
/// Determine whether a path should be walked further.
24+
/// This is run against each item from `get_more()`.
25+
fn prune(&self, p: &Self::P) -> bool;
26+
}
27+
28+
/// The basic fully-recursive strategy. Nothing is pruned.
29+
#[derive(Copy, Default)]
30+
pub struct Recursive;
31+
32+
impl Strategy for Recursive {
33+
type P = Path;
34+
fn get_more(&self, p: &Path) -> IoResult<Vec<Path>> { fs::readdir(p) }
35+
36+
fn prune(&self, _: &Path) -> bool { false }
37+
}
38+
39+
/// A directory walker of `P` using strategy `S`.
40+
pub struct Subpaths<S: Strategy> {
41+
stack: Vec<S::P>,
42+
strategy: S,
43+
}
44+
45+
impl<S: Strategy> Subpaths<S> {
46+
/// Create a directory walker with a root path and strategy.
47+
pub fn new(p: &S::P, strategy: S) -> IoResult<Subpaths<S>> {
48+
let stack = try!(strategy.get_more(p));
49+
Ok(Subpaths { stack: stack, strategy: strategy })
50+
}
51+
}
52+
53+
impl<S: Default + Strategy> Subpaths<S> {
54+
/// Create a directory walker with a root path and a default strategy.
55+
pub fn walk(p: &S::P) -> IoResult<Subpaths<S>> {
56+
Subpaths::new(p, Default::default())
57+
}
58+
}
59+
60+
impl<S: Default + Strategy> Default for Subpaths<S> {
61+
fn default() -> Subpaths<S> {
62+
Subpaths { stack: Vec::new(), strategy: Default::default() }
63+
}
64+
}
65+
66+
impl<S: Strategy> Iterator for Subpaths<S> {
67+
type Item = S::P;
68+
fn next (&mut self) -> Option<S::P> {
69+
let mut opt_path = self.stack.pop();
70+
while opt_path.is_some() && self.strategy.prune(opt_path.as_ref().unwrap()) {
71+
opt_path = self.stack.pop();
72+
}
73+
match opt_path {
74+
Some(path) => {
75+
if PathExtensions::is_dir(&path) {
76+
let result = self.strategy.get_more(&path);
77+
match result {
78+
Ok(dirs) => { self.stack.extend(dirs.into_iter()); },
79+
Err(..) => { }
80+
}
81+
}
82+
Some(path)
83+
}
84+
None => None,
85+
}
86+
}
87+
}
88+
89+
fn main() {
90+
let mut walker: Subpaths<Recursive> = Subpaths::walk(&Path::new("/home")).unwrap();
91+
}

0 commit comments

Comments
 (0)