Repository: sxyazi/yazi
File: yazi-core/src/folder/files.rs (Rust)

Code before:
								tx.send(File::from_no_meta(Url::from(item.path()), file_type).await).ok();
							},
						}
					}
				}
			}
		});
		Ok(rx)
	}

	pub async fn from_dir_bulk(url: &Url) -> std::io::Result<Vec<File>> {
		let mut it = fs::read_dir(url).await?;
		let mut items = Vec::with_capacity(5000);
		while let Ok(Some(item)) = it.next_entry().await {
			items.push(item);
		}

		let (first, rest) = items.split_at(items.len() / 3);
		let (second, third) = rest.split_at(items.len() / 3);
		async fn go(entities: &[DirEntry]) -> Vec<File> {
			let mut files = Vec::with_capacity(entities.len() / 3 + 1);
			for entry in entities {
				match entry.metadata().await {
					Ok(meta) => files.push(File::from_meta(Url::from(entry.path()), meta).await),
					Err(_) => {
						let file_type = entry.file_type().await.ok();
						files.push(File::from_no_meta(Url::from(entry.path()), file_type).await);
					}
				}
			}
			files
		}

		Ok(
			futures::future::join_all([go(first), go(second), go(third)])
				.await
				.into_iter()
				.flatten()
				.collect(),
		)
	}

	pub async fn assert_stale(url: &Url, mtime: Option<SystemTime>) -> Option<Metadata> {
		match fs::metadata(url).await {
			Ok(m) if !m.is_dir() => {
				// FIXME: use `ErrorKind::NotADirectory` instead once it gets stabilized
				FilesOp::IOErr(url.clone(), std::io::ErrorKind::AlreadyExists).emit();
			}
			Ok(m) if mtime == m.modified().ok() => {}
			Ok(m) => return Some(m),
			Err(e) => {

Review comment (bug):
I'm wondering if this is necessary - if a file's metadata can't be got, can we just get its filetype? I've never seen a broken file, so I doubt its necessity.

Code after:
				}
			}
		});
		Ok(rx)
	}

	pub async fn from_dir_bulk(url: &Url) -> std::io::Result<Vec<File>> {
		let mut it = fs::read_dir(url).await?;
		let mut items = Vec::with_capacity(5000);
		while let Ok(Some(item)) = it.next_entry().await {
			items.push(item);
		}

		let (first, rest) = items.split_at(items.len() / 3);
		let (second, third) = rest.split_at(items.len() / 3);
		async fn go(entities: &[DirEntry]) -> Vec<File> {
			let mut files = Vec::with_capacity(entities.len() / 3 + 1);
			for entry in entities {
				let url = Url::from(entry.path());
				files.push(match entry.metadata().await {
					Ok(meta) => File::from_meta(url, meta).await,
					Err(_) => File::from_dummy(url, entry.file_type().await.ok()),
				});
			}
			files
		}

		Ok(
			futures::future::join_all([go(first), go(second), go(third)])
				.await
				.into_iter()
				.flatten()
				.collect(),
		)
	}

	pub async fn assert_stale(url: &Url, mtime: Option<SystemTime>) -> Option<Metadata> {
		match fs::metadata(url).await {
			Ok(m) if !m.is_dir() => {
				// FIXME: use `ErrorKind::NotADirectory` instead once it gets stabilized
				FilesOp::IOErr(url.clone(), std::io::ErrorKind::AlreadyExists).emit();
			}
			Ok(m) if mtime == m.modified().ok() => {}
			Ok(m) => return Some(m),
			Err(e) => {
				if maybe_exists(url).await {
					FilesOp::IOErr(url.clone(), e.kind()).emit();
				} else if let Some(p) = url.parent_url() {
					FilesOp::Deleting(p, vec![url.clone()]).emit();
				}
			}