]> git.lizzy.rs Git - rust.git/blob - src/test/run-pass/issue-20797.rs
rustdoc: Replace no-pretty-expanded with pretty-expanded
[rust.git] / src / test / run-pass / issue-20797.rs
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 // pretty-expanded FIXME #23616
14
15 #![feature(old_io, old_path)]
16
17 use std::default::Default;
18 use std::io;
19 use std::fs;
20 use std::path::{PathBuf, Path};
21
22 pub trait PathExtensions {
23     fn is_dir(&self) -> bool { false }
24 }
25
26 impl PathExtensions for PathBuf {}
27
28 /// A strategy for acquiring more subpaths to walk.
29 pub trait Strategy {
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;
36 }
37
38 /// The basic fully-recursive strategy. Nothing is pruned.
39 #[derive(Copy, Default)]
40 pub struct Recursive;
41
42 impl Strategy for Recursive {
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     }
47
48     fn prune(&self, _: &PathBuf) -> bool { false }
49 }
50
51 /// A directory walker of `P` using strategy `S`.
52 pub struct Subpaths<S: Strategy> {
53     stack: Vec<S::P>,
54     strategy: S,
55 }
56
57 impl<S: Strategy> Subpaths<S> {
58     /// Create a directory walker with a root path and strategy.
59     pub fn new(p: &S::P, strategy: S) -> io::Result<Subpaths<S>> {
60         let stack = try!(strategy.get_more(p));
61         Ok(Subpaths { stack: stack, strategy: strategy })
62     }
63 }
64
65 impl<S: Default + Strategy> Subpaths<S> {
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     }
70 }
71
72 impl<S: Default + Strategy> Default for Subpaths<S> {
73     fn default() -> Subpaths<S> {
74         Subpaths { stack: Vec::new(), strategy: Default::default() }
75     }
76 }
77
78 impl<S: Strategy> Iterator for Subpaths<S> {
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 {
90                         Ok(dirs) => { self.stack.extend(dirs.into_iter()); },
91                         Err(..) => { }
92                     }
93                 }
94                 Some(path)
95             }
96             None => None,
97         }
98     }
99 }
100
101 fn foo() {
102     let mut walker: Subpaths<Recursive> = Subpaths::walk(&PathBuf::new("/home")).unwrap();
103 }
104
105 fn main() {}