File: defining-use-uncaptured-non-universal-region-2.rs

package info (click to toggle)
rustc 1.85.0%2Bdfsg3-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental, sid, trixie
  • size: 893,396 kB
  • sloc: xml: 158,127; python: 35,830; javascript: 19,497; cpp: 19,002; sh: 17,245; ansic: 13,127; asm: 4,376; makefile: 1,051; perl: 29; lisp: 29; ruby: 19; sql: 11
file content (74 lines) | stat: -rw-r--r-- 2,405 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// issue: #110623
//@ check-pass

use std::{collections::BTreeMap, num::ParseIntError, str::FromStr};

enum FileSystem {
    File(usize),
    Directory(BTreeMap<String, FileSystem>),
}

impl FromStr for FileSystem {
    type Err = ParseIntError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.starts_with("dir") {
            Ok(Self::new_dir())
        } else {
            Ok(Self::File(s.split_whitespace().next().unwrap().parse()?))
        }
    }
}

impl FileSystem {
    fn new_dir() -> FileSystem {
        FileSystem::Directory(BTreeMap::new())
    }

    fn insert(&mut self, name: String, other: FileSystem) -> Option<FileSystem> {
        match self {
            FileSystem::File(_) => panic!("can only insert into directory!"),
            FileSystem::Directory(tree) => tree.insert(name, other),
        }
    }

    // Recursively build a tree from commands. This uses (abuses?)
    // the fact that `cd /` only appears at the start and that
    // subsequent `cd`s can only move ONE level to use the recursion
    // stack as the filesystem stack
    fn build<'a>(
        &mut self,
        mut commands: impl Iterator<Item = &'a str> + 'a,
    ) -> Option<impl Iterator<Item = &'a str> + 'a> {
        let cmd = commands.next()?;
        let mut elements = cmd.lines();
        match elements.next().map(str::trim) {
            Some("cd /") | None => self.build(commands),
            Some("cd ..") => {
                // return to higher scope
                Some(commands)
            }
            Some("ls") => {
                for item in elements {
                    let name = item.split_whitespace().last().unwrap();
                    let prior = self.insert(name.to_string(), item.parse().unwrap());
                    debug_assert!(prior.is_none());
                }
                // continue on
                self.build(commands)
            }
            Some(other_cd) => {
                let name = other_cd
                    .trim()
                    .strip_prefix("cd ")
                    .expect("expected a cd command");
                let mut directory = FileSystem::new_dir();
                let further_commands = directory.build(commands);
                self.insert(name.to_string(), directory);
                self.build(further_commands?) // THIS LINE FAILS TO COMPILE
            }
        }
    }
}

fn main() {}