diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 0347a87..fc70c92 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -4,9 +4,10 @@ version = "0.1.0" edition = "2021" [features] -default = ["const"] +default = ["storage"] const = [] serde_derive = ["dep:serde", "dep:serde_json"] +storage = ["serde_derive"] [dependencies] serde = { version = "1.0.194", features = ["derive"], optional = true } diff --git a/rust/src/api/get_node_by_path.rs b/rust/src/api/get_node_by_path.rs index f8681c8..ced1c2f 100644 --- a/rust/src/api/get_node_by_path.rs +++ b/rust/src/api/get_node_by_path.rs @@ -1,10 +1,22 @@ -use crate::{_auto_generated, node::model::Node}; +use crate::node::model::Node; + +#[cfg(feature = "const")] +use crate::_auto_generated; + +#[cfg(feature = "storage")] +use crate::api::storage; #[cfg(feature = "const")] pub fn get_node_by_path(path: &str) -> Option<&Node> { _auto_generated::data::get_node_by_path(path) } +#[cfg(feature = "storage")] +pub fn get_node_by_path(data_path: &'static str, path: &str) -> Result { + storage::get_node_by_path(data_path, path) +} + +#[cfg(any(feature = "const", feature = "storage"))] #[cfg(test)] mod test { use crate::node::model::{Node, NodeName, NodeTerms, NodeType}; @@ -29,9 +41,18 @@ mod test { "umkb", Node { name: NodeName { + #[cfg(feature = "const")] ar: "جامعة محمد خيضر بسكرة", + #[cfg(feature = "storage")] + ar: "جامعة محمد خيضر بسكرة".to_string(), + #[cfg(feature = "const")] en: "University of Mohamed Khider Biskra", + #[cfg(feature = "storage")] + en: "University of Mohamed Khider Biskra".to_string(), + #[cfg(feature = "const")] fr: "Université Mohamed Khider Biskra", + #[cfg(feature = "storage")] + fr: "Université Mohamed Khider Biskra".to_string(), }, r#type: NodeType::University, }, @@ -40,9 +61,18 @@ mod test { "umkb/fst", Node { name: NodeName { + #[cfg(feature = "const")] ar: "كلية العلوم والتكنلوجيا", + #[cfg(feature = "storage")] + ar: "كلية العلوم والتكنلوجيا".to_string(), + #[cfg(feature = "const")] en: "Faculty of Science and Technology", + #[cfg(feature = "storage")] + en: "Faculty of Science and Technology".to_string(), + #[cfg(feature = "const")] fr: "Faculté des Sciences et de la Technologie", + #[cfg(feature = "storage")] + fr: "Faculté des Sciences et de la Technologie".to_string(), }, r#type: NodeType::Faculty, }, @@ -51,14 +81,26 @@ mod test { "umkb/fst/dee/sec", Node { name: NodeName { + #[cfg(feature = "const")] ar: "تخصص التحكم الكهربائي", + #[cfg(feature = "storage")] + ar: "تخصص التحكم الكهربائي".to_string(), + #[cfg(feature = "const")] en: "Specialy of Electrical Control", + #[cfg(feature = "storage")] + en: "Specialy of Electrical Control".to_string(), + #[cfg(feature = "const")] fr: "Spécialité de commande électrique", + #[cfg(feature = "storage")] + fr: "Spécialité de commande électrique".to_string(), }, r#type: NodeType::Specialty { terms: NodeTerms { per_year: 2, + #[cfg(feature = "const")] slots: &[7, 8, 9, 10], + #[cfg(feature = "storage")] + slots: vec![7, 8, 9, 10], }, }, }, @@ -66,15 +108,31 @@ mod test { ]; for tc in tests { - let actual = get_node_by_path(tc.path).unwrap(); - assert_node(&tc.expected, &actual); + #[cfg(feature = "const")] + { + let actual = get_node_by_path(tc.path).unwrap(); + assert_node(&tc.expected, &actual); + } + #[cfg(feature = "storage")] + { + let actual = get_node_by_path("../_data", tc.path).unwrap(); + assert_node(&tc.expected, &actual); + } } } #[test] fn should_get_none_when_path_does_not_exist() { - let res = get_node_by_path("does/not/exist"); - assert!(res.is_none()); + #[cfg(feature = "const")] + { + let res = get_node_by_path("does/not/exist"); + assert!(res.is_none()); + } + #[cfg(feature = "storage")] + { + let res = get_node_by_path("../_data", "does/not/exist"); + assert!(res.is_err()); + } } fn assert_node(expected: &Node, actual: &Node) { diff --git a/rust/src/api/mod.rs b/rust/src/api/mod.rs index eea4aed..832fa85 100644 --- a/rust/src/api/mod.rs +++ b/rust/src/api/mod.rs @@ -1 +1,2 @@ pub mod get_node_by_path; +mod storage; diff --git a/rust/src/api/storage.rs b/rust/src/api/storage.rs new file mode 100644 index 0000000..e14b0dc --- /dev/null +++ b/rust/src/api/storage.rs @@ -0,0 +1,15 @@ +#[cfg(feature = "storage")] +use crate::Node; + +#[cfg(feature = "storage")] +pub fn get_node_by_path(data_path: &'static str, path: &str) -> Result { + let fs_path = format!("{}/{}/info.json", data_path, path); + let info = std::fs::read_to_string(fs_path)?; + let Ok(node) = serde_json::from_str::(info.as_str()) else { + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + "json was not deserialized", + )); + }; + Ok(node) +} diff --git a/rust/src/lib.rs b/rust/src/lib.rs index f4aea4d..3ee6ef9 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,4 +1,6 @@ +#[cfg(feature = "const")] mod _auto_generated; + mod api; mod node; diff --git a/rust/src/node/model.rs b/rust/src/node/model.rs index 22d1d90..7590533 100644 --- a/rust/src/node/model.rs +++ b/rust/src/node/model.rs @@ -1,43 +1,74 @@ #[cfg(feature = "serde_derive")] use serde::{Deserialize, Serialize}; +#[cfg(feature = "const")] #[derive(Debug, PartialEq)] #[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] pub struct NodeName<'a> { - #[cfg(feature = "const")] pub ar: &'a str, - #[cfg(feature = "const")] pub en: &'a str, - #[cfg(feature = "const")] pub fr: &'a str, } +#[cfg(feature = "storage")] #[derive(Debug, PartialEq)] #[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] +pub struct NodeName { + pub ar: String, + pub en: String, + pub fr: String, +} + +#[cfg(any(feature = "const", feature = "storage"))] +#[derive(Debug, PartialEq)] +#[cfg_attr( + feature = "serde_derive", + derive(Serialize, Deserialize), + serde(tag = "type") +)] pub enum NodeType { + #[cfg_attr(feature = "serde_derive", serde(rename = "UNIVERSITY"))] University, + #[cfg_attr(feature = "serde_derive", serde(rename = "ACADEMY"))] Academy, + #[cfg_attr(feature = "serde_derive", serde(rename = "PRIVATE_SCHOOL"))] PrivateSchool, + #[cfg_attr(feature = "serde_derive", serde(rename = "INSTITUTE"))] Institute, + #[cfg_attr(feature = "serde_derive", serde(rename = "FACULTY"))] Faculty, + #[cfg_attr(feature = "serde_derive", serde(rename = "DEPARTMENT"))] Department, + #[cfg_attr(feature = "serde_derive", serde(rename = "SPECIALTY"))] Specialty { terms: NodeTerms }, + #[cfg_attr(feature = "serde_derive", serde(rename = "SECTOR"))] Sector { terms: NodeTerms }, } #[derive(Debug, PartialEq, Clone)] -#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] +#[cfg_attr( + feature = "serde_derive", + derive(Serialize, Deserialize), + serde(rename_all = "camelCase") +)] pub struct NodeTerms { pub per_year: usize, #[cfg(feature = "const")] #[cfg_attr(feature = "serde_derive", serde(skip_deserializing))] pub slots: &'static [i32], + #[cfg(feature = "storage")] + pub slots: Vec, } +#[cfg(any(feature = "const", feature = "storage"))] #[derive(Debug, PartialEq)] #[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] pub struct Node { + #[cfg(feature = "const")] #[cfg_attr(feature = "serde_derive", serde(borrow))] pub name: NodeName<'static>, + #[cfg(feature = "storage")] + pub name: NodeName, + #[cfg_attr(feature = "serde_derive", serde(flatten))] pub r#type: NodeType, }