]> git.proxmox.com Git - rustc.git/blame - src/test/run-pass/issue-20797.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / test / run-pass / issue-20797.rs
CommitLineData
85aaf69f
SL
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
85aaf69f
SL
11// Regression test for #20797.
12
c34b1796
AL
13// pretty-expanded FIXME #23616
14
54a0048b
SL
15#![feature(question_mark)]
16
85aaf69f 17use std::default::Default;
c34b1796
AL
18use std::io;
19use std::fs;
20use std::path::PathBuf;
21
22pub trait PathExtensions {
23 fn is_dir(&self) -> bool { false }
24}
25
26impl PathExtensions for PathBuf {}
85aaf69f
SL
27
28/// A strategy for acquiring more subpaths to walk.
29pub trait Strategy {
c34b1796
AL
30 type P: PathExtensions;
31 /// Get additional subpaths from a given path.
32 fn get_more(&self, item: &Self::P) -> io::Result<Vec<Self::P>>;
33 /// Determine whether a path should be walked further.
34 /// This is run against each item from `get_more()`.
35 fn prune(&self, p: &Self::P) -> bool;
85aaf69f
SL
36}
37
38/// The basic fully-recursive strategy. Nothing is pruned.
c34b1796 39#[derive(Copy, Clone, Default)]
85aaf69f
SL
40pub struct Recursive;
41
42impl Strategy for Recursive {
c34b1796
AL
43 type P = PathBuf;
44 fn get_more(&self, p: &PathBuf) -> io::Result<Vec<PathBuf>> {
45 Ok(fs::read_dir(p).unwrap().map(|s| s.unwrap().path()).collect())
46 }
85aaf69f 47
c34b1796 48 fn prune(&self, _: &PathBuf) -> bool { false }
85aaf69f
SL
49}
50
51/// A directory walker of `P` using strategy `S`.
52pub struct Subpaths<S: Strategy> {
53 stack: Vec<S::P>,
54 strategy: S,
55}
56
57impl<S: Strategy> Subpaths<S> {
c34b1796
AL
58 /// Create a directory walker with a root path and strategy.
59 pub fn new(p: &S::P, strategy: S) -> io::Result<Subpaths<S>> {
54a0048b 60 let stack = strategy.get_more(p)?;
c34b1796
AL
61 Ok(Subpaths { stack: stack, strategy: strategy })
62 }
85aaf69f
SL
63}
64
65impl<S: Default + Strategy> Subpaths<S> {
c34b1796
AL
66 /// Create a directory walker with a root path and a default strategy.
67 pub fn walk(p: &S::P) -> io::Result<Subpaths<S>> {
68 Subpaths::new(p, Default::default())
69 }
85aaf69f
SL
70}
71
72impl<S: Default + Strategy> Default for Subpaths<S> {
c34b1796
AL
73 fn default() -> Subpaths<S> {
74 Subpaths { stack: Vec::new(), strategy: Default::default() }
75 }
85aaf69f
SL
76}
77
78impl<S: Strategy> Iterator for Subpaths<S> {
c34b1796
AL
79 type Item = S::P;
80 fn next (&mut self) -> Option<S::P> {
81 let mut opt_path = self.stack.pop();
82 while opt_path.is_some() && self.strategy.prune(opt_path.as_ref().unwrap()) {
83 opt_path = self.stack.pop();
84 }
85 match opt_path {
86 Some(path) => {
87 if path.is_dir() {
88 let result = self.strategy.get_more(&path);
89 match result {
62682a34 90 Ok(dirs) => { self.stack.extend(dirs); },
c34b1796
AL
91 Err(..) => { }
92 }
93 }
94 Some(path)
95 }
96 None => None,
85aaf69f 97 }
85aaf69f 98 }
85aaf69f
SL
99}
100
c34b1796
AL
101fn _foo() {
102 let _walker: Subpaths<Recursive> = Subpaths::walk(&PathBuf::from("/home")).unwrap();
85aaf69f 103}
c34b1796
AL
104
105fn main() {}