colmap 0.1.2

A comprehensive Rust library for COLMAP-style computer vision and 3D reconstruction
Documentation
//! 输入输出模块
//!
//! 这个模块处理各种文件格式的读写,包括:
//! - COLMAP 格式文件
//! - 图像文件
//! - 点云文件
//! - 配置文件

// TODO: 实现这些模块
// pub mod colmap_format;
// pub mod image;
// pub mod pointcloud;
// pub mod config;
// pub mod database;

// 重新导出主要类型
// pub use colmap_format::*;
// pub use image::*;
// pub use pointcloud::*;
// pub use config::*;
// pub use database::*;

use crate::core::{Result, ColmapError};
use std::path::Path;
use serde::{Deserialize, Serialize};

/// 支持的文件格式
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum FileFormat {
    /// COLMAP 二进制格式
    ColmapBinary,
    /// COLMAP 文本格式
    ColmapText,
    /// PLY 点云格式
    Ply,
    /// OBJ 网格格式
    Obj,
    /// JSON 配置格式
    Json,
    /// YAML 配置格式
    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);
    }
}