1 pub mod fstype; 2 mod utils; 3 4 use std::{fs, path::PathBuf}; 5 6 use anyhow::Result; 7 use fstype::FsType; 8 use serde::Deserialize; 9 10 /// rootfs配置文件 11 #[derive(Debug, Clone, Copy, Deserialize)] 12 pub struct RootFSConfigFile { 13 pub metadata: RootFSMeta, 14 } 15 16 impl RootFSConfigFile { 17 pub fn load(path: &PathBuf) -> Result<Self> { 18 // 读取文件内容 19 let content = fs::read_to_string(path)?; 20 Self::load_from_str(&content) 21 } 22 23 pub fn load_from_str(content: &str) -> Result<Self> { 24 let config: RootFSConfigFile = toml::from_str(content)?; 25 26 Ok(config) 27 } 28 } 29 30 #[derive(Debug, Clone, Copy, Deserialize)] 31 pub struct RootFSMeta { 32 /// rootfs文件系统类型 33 pub fs_type: FsType, 34 /// rootfs磁盘大小(至少要大于这个值) 35 #[serde(deserialize_with = "utils::size::deserialize_size")] 36 pub size: usize, 37 } 38 39 #[cfg(test)] 40 mod tests { 41 use std::io::Write; 42 43 use super::*; 44 use tempfile::NamedTempFile; 45 46 #[test] 47 fn test_load_from_valid_file() { 48 let config_content = r#" 49 [metadata] 50 fs_type = "fat32" 51 size = "1024M" 52 "#; 53 54 let mut temp_file = NamedTempFile::new().expect("Failed to create temp file"); 55 temp_file 56 .write_all(config_content.as_bytes()) 57 .expect("Failed to write to temp file"); 58 59 let config_path = PathBuf::from(temp_file.path()); 60 let config = RootFSConfigFile::load(&config_path).expect("Failed to load config"); 61 62 assert_eq!(config.metadata.fs_type, FsType::Fat32); 63 assert_eq!(config.metadata.size, 1024 * 1024 * 1024); // Assuming `deserialize_size` converts MB to Bytes 64 } 65 66 #[test] 67 fn test_load_from_valid_str() { 68 let config_content = r#" 69 [metadata] 70 fs_type = "fat32" 71 size = "512M" 72 "#; 73 74 let config = RootFSConfigFile::load_from_str(config_content) 75 .expect("Failed to load config from str"); 76 77 assert_eq!(config.metadata.fs_type, FsType::Fat32); 78 assert_eq!(config.metadata.size, 512 * 1024 * 1024); // Assuming `deserialize_size` converts MB to Bytes 79 } 80 #[test] 81 fn test_load_from_invalid_fs_type() { 82 let config_content = r#" 83 [metadata] 84 fs_type = "ABCDE" 85 size = "512M" 86 "#; 87 assert!(RootFSConfigFile::load_from_str(config_content).is_err()); 88 } 89 90 /// 测试size为int类型的字节大小 91 #[test] 92 fn test_load_from_valid_str_size_integer() { 93 let config_content = r#" 94 [metadata] 95 fs_type = "fat32" 96 size = 1048576 97 "#; 98 99 let config = RootFSConfigFile::load_from_str(config_content) 100 .expect("Failed to load config from str"); 101 102 assert_eq!(config.metadata.fs_type, FsType::Fat32); 103 assert_eq!(config.metadata.size, 1048576); // Assuming `deserialize_size` converts MB to Bytes 104 } 105 #[test] 106 fn test_load_from_valid_str_size_bytes_str() { 107 let config_content = r#" 108 [metadata] 109 fs_type = "fat32" 110 size = "1048576" 111 "#; 112 113 let config = RootFSConfigFile::load_from_str(config_content) 114 .expect("Failed to load config from str"); 115 116 assert_eq!(config.metadata.fs_type, FsType::Fat32); 117 assert_eq!(config.metadata.size, 1048576); // Assuming `deserialize_size` converts MB to Bytes 118 } 119 120 #[test] 121 fn test_load_from_invalid_file() { 122 let temp_file = NamedTempFile::new().expect("Failed to create temp file"); 123 let config_path = PathBuf::from(temp_file.path()); 124 125 assert!(RootFSConfigFile::load(&config_path).is_err()); 126 } 127 128 /// Parse from an incorrect size field (string) 129 #[test] 130 fn test_load_from_invalid_size_str() { 131 let invalid_config_content = r#" 132 [metadata] 133 fs_type = "fat32" 134 size = "not_a_size" 135 "#; 136 137 assert!(RootFSConfigFile::load_from_str(invalid_config_content).is_err()); 138 } 139 140 /// Parse from an incorrect size field (array) 141 #[test] 142 fn test_load_from_invalid_size_array() { 143 // The 'size' field should not be an array 144 let invalid_config_content = r#" 145 [metadata] 146 fs_type = "fat32" 147 size = ["not_a_size"] 148 "#; 149 150 assert!(RootFSConfigFile::load_from_str(invalid_config_content).is_err()); 151 } 152 } 153