use crate::core::{Result, ColmapError};
use std::path::Path;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum FileFormat {
ColmapBinary,
ColmapText,
Ply,
Obj,
Json,
Yaml,
}
pub fn infer_format_from_extension(path: &Path) -> Option<FileFormat> {
match path.extension()?.to_str()? {
"bin" => Some(FileFormat::ColmapBinary),
"txt" => Some(FileFormat::ColmapText),
"ply" => Some(FileFormat::Ply),
"obj" => Some(FileFormat::Obj),
"json" => Some(FileFormat::Json),
"yaml" | "yml" => Some(FileFormat::Yaml),
_ => None,
}
}
pub fn check_file_readable(path: &Path) -> Result<()> {
if !path.exists() {
return Err(ColmapError::Io(std::io::Error::new(std::io::ErrorKind::NotFound, format!("文件不存在: {:?}", path))));
}
if !path.is_file() {
return Err(ColmapError::Io(std::io::Error::new(std::io::ErrorKind::InvalidInput, format!("路径不是文件: {:?}", path))));
}
std::fs::File::open(path)
.map_err(|e| ColmapError::Io(std::io::Error::new(e.kind(), format!("无法读取文件 {:?}: {}", path, e))))?;
Ok(())
}
pub fn check_dir_writable(path: &Path) -> Result<()> {
if !path.exists() {
std::fs::create_dir_all(path)
.map_err(|e| ColmapError::Io(std::io::Error::new(e.kind(), format!("无法创建目录 {:?}: {}", path, e))))?;
}
if !path.is_dir() {
return Err(ColmapError::Io(std::io::Error::new(std::io::ErrorKind::InvalidInput, format!("路径不是目录: {:?}", path))));
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use std::path::PathBuf;
#[test]
fn test_infer_format() {
assert_eq!(infer_format_from_extension(&PathBuf::from("test.bin")), Some(FileFormat::ColmapBinary));
assert_eq!(infer_format_from_extension(&PathBuf::from("test.txt")), Some(FileFormat::ColmapText));
assert_eq!(infer_format_from_extension(&PathBuf::from("test.ply")), Some(FileFormat::Ply));
assert_eq!(infer_format_from_extension(&PathBuf::from("test.unknown")), None);
}
}