app_path/app_path/directory.rs
1use crate::{AppPath, AppPathError};
2
3impl AppPath {
4 /// Creates parent directories needed for this file path.
5 ///
6 /// This method creates all parent directories for a file path, making it ready
7 /// for file creation. It does not create the file itself.
8 ///
9 /// **Use this when you know the path represents a file and you want to prepare
10 /// the directory structure for writing the file.**
11 ///
12 /// # Examples
13 ///
14 /// ```rust
15 /// use app_path::AppPath;
16 /// use std::env;
17 ///
18 /// let temp_dir = env::temp_dir().join("app_path_parent_example");
19 ///
20 /// // Prepare directories for a log file
21 /// let log_file = AppPath::new(temp_dir.join("logs/2024/app.log"));
22 /// log_file.create_parents()?; // Creates logs/2024/ directories
23 ///
24 /// // Parent directories exist, but file does not
25 /// assert!(temp_dir.join("logs").exists());
26 /// assert!(temp_dir.join("logs/2024").exists());
27 /// assert!(!log_file.exists()); // File not created, only parent dirs
28 ///
29 /// // Now you can write the file
30 /// std::fs::write(&log_file, "Log entry")?;
31 /// assert!(log_file.exists());
32 ///
33 /// # std::fs::remove_dir_all(&temp_dir).ok();
34 /// # Ok::<(), Box<dyn std::error::Error>>(())
35 /// ```
36 ///
37 /// ## Complex Directory Structures
38 ///
39 /// ```rust
40 /// use app_path::AppPath;
41 /// use std::env;
42 ///
43 /// let temp_dir = env::temp_dir().join("app_path_complex_example");
44 ///
45 /// // Create parents for config file
46 /// let config_file = AppPath::new(temp_dir.join("config/database/settings.toml"));
47 /// config_file.create_parents()?; // Creates config/database/ directories
48 ///
49 /// // Create parents for data file
50 /// let data_file = AppPath::new(temp_dir.join("data/users/profiles.db"));
51 /// data_file.create_parents()?; // Creates data/users/ directories
52 ///
53 /// // All parent directories exist
54 /// assert!(temp_dir.join("config").exists());
55 /// assert!(temp_dir.join("config/database").exists());
56 /// assert!(temp_dir.join("data").exists());
57 /// assert!(temp_dir.join("data/users").exists());
58 ///
59 /// # std::fs::remove_dir_all(&temp_dir).ok();
60 /// # Ok::<(), app_path::AppPathError>(())
61 /// ```
62 ///
63 /// # Errors
64 ///
65 /// Returns [`AppPathError::IoError`] if directory creation fails:
66 /// - **Insufficient permissions** - Cannot create directories due to filesystem permissions
67 /// - **Disk space exhausted** - Not enough space to create directory entries
68 /// - **Invalid path characters** - Path contains characters invalid for the target filesystem
69 /// - **Network filesystem issues** - Problems with remote/networked filesystems
70 /// - **Filesystem corruption** - Underlying filesystem errors
71 ///
72 /// The operation is **not atomic** - some parent directories may be created even if the
73 /// operation ultimately fails.
74 #[inline]
75 pub fn create_parents(&self) -> Result<(), AppPathError> {
76 if let Some(parent) = self.full_path.parent() {
77 std::fs::create_dir_all(parent)?;
78 }
79 Ok(())
80 }
81
82 /// Creates this path as a directory, including all parent directories.
83 ///
84 /// This method treats the path as a directory and creates it along with
85 /// all necessary parent directories. The created directory will exist
86 /// after this call succeeds.
87 ///
88 /// **Use this when you know the path represents a directory that should be created.**
89 ///
90 /// # Behavior
91 ///
92 /// - **Creates the directory itself**: Unlike `create_parents()`, this creates the full path as a directory
93 /// - **Creates all parents**: Any missing parent directories are created automatically
94 /// - **Idempotent**: Safe to call multiple times - won't fail if directory already exists
95 /// - **Atomic-like**: Either all directories are created or the operation fails
96 ///
97 /// # Examples
98 ///
99 /// ## Basic Directory Creation
100 ///
101 /// ```rust
102 /// use app_path::AppPath;
103 /// use std::env;
104 ///
105 /// let temp_dir = env::temp_dir().join("app_path_dir_example");
106 ///
107 /// // Create a cache directory
108 /// let cache_dir = AppPath::new(temp_dir.join("cache"));
109 /// cache_dir.create_dir()?; // Creates cache/ directory
110 /// assert!(cache_dir.exists());
111 /// assert!(cache_dir.is_dir());
112 ///
113 /// # std::fs::remove_dir_all(&temp_dir).ok();
114 /// # Ok::<(), Box<dyn std::error::Error>>(())
115 /// ```
116 ///
117 /// ## Nested Directory Structures
118 ///
119 /// ```rust
120 /// use app_path::AppPath;
121 /// use std::env;
122 ///
123 /// let temp_dir = env::temp_dir().join("app_path_nested_example");
124 ///
125 /// // Create deeply nested directories
126 /// let deep_dir = AppPath::new(temp_dir.join("data/backups/daily"));
127 /// deep_dir.create_dir()?; // Creates data/backups/daily/ directories
128 /// assert!(deep_dir.exists());
129 /// assert!(deep_dir.is_dir());
130 ///
131 /// // All parent directories are also created
132 /// let backups_dir = AppPath::new(temp_dir.join("data/backups"));
133 /// assert!(backups_dir.exists());
134 /// assert!(backups_dir.is_dir());
135 ///
136 /// # std::fs::remove_dir_all(&temp_dir).ok();
137 /// # Ok::<(), Box<dyn std::error::Error>>(())
138 /// ```
139 ///
140 /// ## Practical Application Setup
141 ///
142 /// ```rust
143 /// use app_path::AppPath;
144 /// use std::env;
145 ///
146 /// let temp_dir = env::temp_dir().join("app_setup_example");
147 ///
148 /// // Set up application directory structure
149 /// let config_dir = AppPath::new(temp_dir.join("config"));
150 /// let data_dir = AppPath::new(temp_dir.join("data"));
151 /// let cache_dir = AppPath::new(temp_dir.join("cache"));
152 /// let logs_dir = AppPath::new(temp_dir.join("logs"));
153 ///
154 /// // Create all directories
155 /// config_dir.create_dir()?;
156 /// data_dir.create_dir()?;
157 /// cache_dir.create_dir()?;
158 /// logs_dir.create_dir()?;
159 ///
160 /// // Now create subdirectories
161 /// let daily_logs = logs_dir.join("daily");
162 /// daily_logs.create_dir()?;
163 ///
164 /// // Verify structure
165 /// assert!(config_dir.is_dir());
166 /// assert!(data_dir.is_dir());
167 /// assert!(cache_dir.is_dir());
168 /// assert!(logs_dir.is_dir());
169 /// assert!(daily_logs.is_dir());
170 ///
171 /// # std::fs::remove_dir_all(&temp_dir).ok();
172 /// # Ok::<(), Box<dyn std::error::Error>>(())
173 /// ```
174 ///
175 /// ## Comparison with `create_parents()`
176 ///
177 /// ```rust
178 /// use app_path::AppPath;
179 /// use std::env;
180 ///
181 /// let temp_dir = env::temp_dir().join("app_comparison_example");
182 ///
183 /// let file_path = AppPath::new(temp_dir.join("logs/app.log"));
184 /// let dir_path = AppPath::new(temp_dir.join("logs"));
185 ///
186 /// // For files: prepare parent directories
187 /// file_path.create_parents()?; // Creates logs/ directory
188 /// assert!(dir_path.exists()); // logs/ directory exists
189 /// assert!(!file_path.exists()); // app.log file does NOT exist
190 ///
191 /// // For directories: create the directory itself
192 /// dir_path.create_dir()?; // Creates logs/ directory (idempotent)
193 /// assert!(dir_path.exists()); // logs/ directory exists
194 /// assert!(dir_path.is_dir()); // and it's definitely a directory
195 ///
196 /// # std::fs::remove_dir_all(&temp_dir).ok();
197 /// # Ok::<(), app_path::AppPathError>(())
198 /// ```
199 ///
200 /// # Errors
201 ///
202 /// Returns [`AppPathError::IoError`] if directory creation fails:
203 /// - **Insufficient permissions** - Cannot create directories due to filesystem permissions
204 /// - **Disk space exhausted** - Not enough space to create directory entries
205 /// - **Invalid path characters** - Path contains characters invalid for the target filesystem
206 /// - **Network filesystem issues** - Problems with remote/networked filesystems
207 /// - **Path already exists as file** - A file already exists at this path (not a directory)
208 /// - **Filesystem corruption** - Underlying filesystem errors
209 ///
210 /// The operation creates parent directories as needed, but is **not atomic** - some
211 /// parent directories may be created even if the final directory creation fails.
212 #[inline]
213 pub fn create_dir(&self) -> Result<(), AppPathError> {
214 std::fs::create_dir_all(self.path())?;
215 Ok(())
216 }
217}