blob: 8c9385961f7b0bde5e9705cf98359889bdc8b644 [file] [log] [blame]
Janis Danisevskisbf15d732020-12-08 10:35:26 -08001// Copyright 2020, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Janis Danisevskisbf15d732020-12-08 10:35:26 -080015use std::fs::{create_dir, remove_dir_all};
16use std::io::ErrorKind;
Janis Danisevskisa51ccbc2020-11-25 21:04:24 -080017use std::path::{Path, PathBuf};
18use std::{env::temp_dir, ops::Deref};
Janis Danisevskisbf15d732020-12-08 10:35:26 -080019
20#[derive(Debug)]
21pub struct TempDir {
22 path: std::path::PathBuf,
23 do_drop: bool,
24}
25
26impl TempDir {
27 pub fn new(prefix: &str) -> std::io::Result<Self> {
28 let tmp = loop {
29 let mut tmp = temp_dir();
30 let number: u16 = rand::random();
31 tmp.push(format!("{}_{:05}", prefix, number));
32 match create_dir(&tmp) {
33 Err(e) => match e.kind() {
34 ErrorKind::AlreadyExists => continue,
35 _ => return Err(e),
36 },
37 Ok(()) => break tmp,
38 }
39 };
40 Ok(Self { path: tmp, do_drop: true })
41 }
42
43 pub fn path(&self) -> &Path {
44 &self.path
45 }
46
Janis Danisevskisa51ccbc2020-11-25 21:04:24 -080047 pub fn build(&self) -> PathBuilder {
48 PathBuilder(self.path.clone())
49 }
50
Janis Danisevskisbf15d732020-12-08 10:35:26 -080051 /// When a test is failing you can set this to false in order to inspect
52 /// the directory structure after the test failed.
53 #[allow(dead_code)]
54 pub fn do_not_drop(&mut self) {
55 println!("Disabled automatic cleanup for: {:?}", self.path);
56 log::info!("Disabled automatic cleanup for: {:?}", self.path);
57 self.do_drop = false;
58 }
59}
60
61impl Drop for TempDir {
62 fn drop(&mut self) {
63 if self.do_drop {
64 remove_dir_all(&self.path).expect("Cannot delete temporary dir.");
65 }
66 }
67}
Janis Danisevskisa51ccbc2020-11-25 21:04:24 -080068
69pub struct PathBuilder(PathBuf);
70
71impl PathBuilder {
72 pub fn push(mut self, segment: &str) -> Self {
73 self.0.push(segment);
74 self
75 }
76}
77
78impl Deref for PathBuilder {
79 type Target = Path;
80
81 fn deref(&self) -> &Self::Target {
82 &self.0
83 }
84}