xref: /DADK/dadk-config/src/rootfs/mod.rs (revision c6f35e8aa5fda2a3004763828fb91c7762df6087)
11ad837a4SLoGin pub mod fstype;
2*c6f35e8aSLoGin pub mod partition;
3*c6f35e8aSLoGin 
41ad837a4SLoGin mod utils;
5e2cc487bSLoGin 
61ad837a4SLoGin use std::{fs, path::PathBuf};
71ad837a4SLoGin 
81ad837a4SLoGin use anyhow::Result;
91ad837a4SLoGin use fstype::FsType;
10*c6f35e8aSLoGin use partition::PartitionConfig;
111ad837a4SLoGin use serde::Deserialize;
121ad837a4SLoGin 
131ad837a4SLoGin /// rootfs配置文件
14*c6f35e8aSLoGin #[derive(Debug, Clone, Deserialize)]
151ad837a4SLoGin pub struct RootFSConfigFile {
161ad837a4SLoGin     pub metadata: RootFSMeta,
17*c6f35e8aSLoGin     #[serde(default)]
18*c6f35e8aSLoGin     pub partition: PartitionConfig,
191ad837a4SLoGin }
201ad837a4SLoGin 
211ad837a4SLoGin impl RootFSConfigFile {
22*c6f35e8aSLoGin     pub const LBA_SIZE: usize = 512;
231ad837a4SLoGin     pub fn load(path: &PathBuf) -> Result<Self> {
241ad837a4SLoGin         // 读取文件内容
251ad837a4SLoGin         let content = fs::read_to_string(path)?;
261ad837a4SLoGin         Self::load_from_str(&content)
271ad837a4SLoGin     }
281ad837a4SLoGin 
291ad837a4SLoGin     pub fn load_from_str(content: &str) -> Result<Self> {
301ad837a4SLoGin         let config: RootFSConfigFile = toml::from_str(content)?;
311ad837a4SLoGin 
321ad837a4SLoGin         Ok(config)
331ad837a4SLoGin     }
341ad837a4SLoGin }
351ad837a4SLoGin 
361ad837a4SLoGin #[derive(Debug, Clone, Copy, Deserialize)]
371ad837a4SLoGin pub struct RootFSMeta {
381ad837a4SLoGin     /// rootfs文件系统类型
391ad837a4SLoGin     pub fs_type: FsType,
401ad837a4SLoGin     /// rootfs磁盘大小(至少要大于这个值)
41*c6f35e8aSLoGin     /// 单位:字节
421ad837a4SLoGin     #[serde(deserialize_with = "utils::size::deserialize_size")]
431ad837a4SLoGin     pub size: usize,
441ad837a4SLoGin }
451ad837a4SLoGin 
461ad837a4SLoGin #[cfg(test)]
471ad837a4SLoGin mod tests {
481ad837a4SLoGin     use std::io::Write;
491ad837a4SLoGin 
501ad837a4SLoGin     use super::*;
511ad837a4SLoGin     use tempfile::NamedTempFile;
521ad837a4SLoGin 
531ad837a4SLoGin     #[test]
541ad837a4SLoGin     fn test_load_from_valid_file() {
551ad837a4SLoGin         let config_content = r#"
561ad837a4SLoGin             [metadata]
571ad837a4SLoGin             fs_type = "fat32"
581ad837a4SLoGin             size = "1024M"
591ad837a4SLoGin         "#;
601ad837a4SLoGin 
611ad837a4SLoGin         let mut temp_file = NamedTempFile::new().expect("Failed to create temp file");
621ad837a4SLoGin         temp_file
631ad837a4SLoGin             .write_all(config_content.as_bytes())
641ad837a4SLoGin             .expect("Failed to write to temp file");
651ad837a4SLoGin 
661ad837a4SLoGin         let config_path = PathBuf::from(temp_file.path());
671ad837a4SLoGin         let config = RootFSConfigFile::load(&config_path).expect("Failed to load config");
681ad837a4SLoGin 
691ad837a4SLoGin         assert_eq!(config.metadata.fs_type, FsType::Fat32);
701ad837a4SLoGin         assert_eq!(config.metadata.size, 1024 * 1024 * 1024); // Assuming `deserialize_size` converts MB to Bytes
711ad837a4SLoGin     }
721ad837a4SLoGin 
731ad837a4SLoGin     #[test]
741ad837a4SLoGin     fn test_load_from_valid_str() {
751ad837a4SLoGin         let config_content = r#"
761ad837a4SLoGin             [metadata]
771ad837a4SLoGin             fs_type = "fat32"
781ad837a4SLoGin             size = "512M"
791ad837a4SLoGin         "#;
801ad837a4SLoGin 
811ad837a4SLoGin         let config = RootFSConfigFile::load_from_str(config_content)
821ad837a4SLoGin             .expect("Failed to load config from str");
831ad837a4SLoGin 
841ad837a4SLoGin         assert_eq!(config.metadata.fs_type, FsType::Fat32);
851ad837a4SLoGin         assert_eq!(config.metadata.size, 512 * 1024 * 1024); // Assuming `deserialize_size` converts MB to Bytes
861ad837a4SLoGin     }
871ad837a4SLoGin     #[test]
881ad837a4SLoGin     fn test_load_from_invalid_fs_type() {
891ad837a4SLoGin         let config_content = r#"
901ad837a4SLoGin             [metadata]
911ad837a4SLoGin             fs_type = "ABCDE"
921ad837a4SLoGin             size = "512M"
931ad837a4SLoGin         "#;
941ad837a4SLoGin         assert!(RootFSConfigFile::load_from_str(config_content).is_err());
951ad837a4SLoGin     }
961ad837a4SLoGin 
971ad837a4SLoGin     /// 测试size为int类型的字节大小
981ad837a4SLoGin     #[test]
991ad837a4SLoGin     fn test_load_from_valid_str_size_integer() {
1001ad837a4SLoGin         let config_content = r#"
1011ad837a4SLoGin             [metadata]
1021ad837a4SLoGin             fs_type = "fat32"
1031ad837a4SLoGin             size = 1048576
1041ad837a4SLoGin         "#;
1051ad837a4SLoGin 
1061ad837a4SLoGin         let config = RootFSConfigFile::load_from_str(config_content)
1071ad837a4SLoGin             .expect("Failed to load config from str");
1081ad837a4SLoGin 
1091ad837a4SLoGin         assert_eq!(config.metadata.fs_type, FsType::Fat32);
1101ad837a4SLoGin         assert_eq!(config.metadata.size, 1048576); // Assuming `deserialize_size` converts MB to Bytes
1111ad837a4SLoGin     }
1121ad837a4SLoGin     #[test]
1131ad837a4SLoGin     fn test_load_from_valid_str_size_bytes_str() {
1141ad837a4SLoGin         let config_content = r#"
1151ad837a4SLoGin             [metadata]
1161ad837a4SLoGin             fs_type = "fat32"
1171ad837a4SLoGin             size = "1048576"
1181ad837a4SLoGin         "#;
1191ad837a4SLoGin 
1201ad837a4SLoGin         let config = RootFSConfigFile::load_from_str(config_content)
1211ad837a4SLoGin             .expect("Failed to load config from str");
1221ad837a4SLoGin 
1231ad837a4SLoGin         assert_eq!(config.metadata.fs_type, FsType::Fat32);
1241ad837a4SLoGin         assert_eq!(config.metadata.size, 1048576); // Assuming `deserialize_size` converts MB to Bytes
1251ad837a4SLoGin     }
1261ad837a4SLoGin 
1271ad837a4SLoGin     #[test]
1281ad837a4SLoGin     fn test_load_from_invalid_file() {
1291ad837a4SLoGin         let temp_file = NamedTempFile::new().expect("Failed to create temp file");
1301ad837a4SLoGin         let config_path = PathBuf::from(temp_file.path());
1311ad837a4SLoGin 
1321ad837a4SLoGin         assert!(RootFSConfigFile::load(&config_path).is_err());
1331ad837a4SLoGin     }
1341ad837a4SLoGin 
1351ad837a4SLoGin     /// Parse from an incorrect size field (string)
1361ad837a4SLoGin     #[test]
1371ad837a4SLoGin     fn test_load_from_invalid_size_str() {
1381ad837a4SLoGin         let invalid_config_content = r#"
1391ad837a4SLoGin             [metadata]
1401ad837a4SLoGin             fs_type = "fat32"
1411ad837a4SLoGin             size = "not_a_size"
1421ad837a4SLoGin         "#;
1431ad837a4SLoGin 
1441ad837a4SLoGin         assert!(RootFSConfigFile::load_from_str(invalid_config_content).is_err());
1451ad837a4SLoGin     }
1461ad837a4SLoGin 
1471ad837a4SLoGin     /// Parse from an incorrect size field (array)
1481ad837a4SLoGin     #[test]
1491ad837a4SLoGin     fn test_load_from_invalid_size_array() {
1501ad837a4SLoGin         // The 'size' field should not be an array
1511ad837a4SLoGin         let invalid_config_content = r#"
1521ad837a4SLoGin             [metadata]
1531ad837a4SLoGin             fs_type = "fat32"
1541ad837a4SLoGin             size = ["not_a_size"]
1551ad837a4SLoGin         "#;
1561ad837a4SLoGin 
1571ad837a4SLoGin         assert!(RootFSConfigFile::load_from_str(invalid_config_content).is_err());
1581ad837a4SLoGin     }
1591ad837a4SLoGin }
160