diff --git a/.github/workflows/rust-checks.yml b/.github/workflows/rust-checks.yml index 525016f..9d35d97 100644 --- a/.github/workflows/rust-checks.yml +++ b/.github/workflows/rust-checks.yml @@ -24,5 +24,4 @@ jobs: - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} - run: cd rust && cargo build --verbose - run: cd rust && cargo test --verbose - - run: cd rust && cargo test --verbose --no-default-features --features const - run: cd rust && cargo test --verbose --no-default-features --features storage diff --git a/rust/Cargo.toml b/rust/Cargo.toml index cba0419..fc70c92 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [features] -default = ["const"] +default = ["storage"] const = [] serde_derive = ["dep:serde", "dep:serde_json"] storage = ["serde_derive"] diff --git a/rust/src/api/get_node_by_path.rs b/rust/src/api/get_node_by_path.rs index 6fd0c6a..b6c0827 100644 --- a/rust/src/api/get_node_by_path.rs +++ b/rust/src/api/get_node_by_path.rs @@ -6,167 +6,104 @@ use crate::_auto_generated; #[cfg(feature = "storage")] use crate::api::storage; +#[cfg(feature = "storage")] +use std::path::Path; + #[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) +pub fn get_node_by_path(path: impl AsRef) -> Result { + storage::get_node_by_path(path) } -#[cfg(any(feature = "const", feature = "storage"))] #[cfg(test)] mod test { - use crate::node::model::{Node, NodeName, NodeTerms, NodeType}; - use super::get_node_by_path; + use crate::node::model::{Node, NodeName, NodeTerms, NodeType}; + #[cfg(feature = "storage")] + use std::path::Path; #[test] fn check_three_schemas_and_non_existent() { + let 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, + }; + let 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], + }, + }, + }; + let 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, + }; + let tests = vec![ ( "umkb", - Some( - #[cfg(feature = "const")]&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, - }, - #[cfg(feature = "storage")] - 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, - } - ), + Some(&umkb), #[cfg(feature = "serde_derive")] "{\"name\":{\"ar\":\"جامعة محمد خيضر بسكرة\",\"en\":\"University of Mohamed Khider Biskra\",\"fr\":\"Université Mohamed Khider Biskra\"},\"type\":\"UNIVERSITY\"}", ), ( "umkb/fst", - Some( - #[cfg(feature = "const")] - &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, - }, - #[cfg(feature = "storage")] - 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, - } - ), + Some(&fst), #[cfg(feature = "serde_derive")] "{\"name\":{\"ar\":\"كلية العلوم والتكنلوجيا\",\"en\":\"Faculty of Science and Technology\",\"fr\":\"Faculté des Sciences et de la Technologie\"},\"type\":\"FACULTY\"}", ), ( "umkb/fst/dee/sec", - Some( - #[cfg(feature = "const")] - &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], - }, - }, - }, - #[cfg(feature = "storage")] - 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], - }, - }, - } - ), + Some(&sec), #[cfg(feature = "serde_derive")] "{\"name\":{\"ar\":\"تخصص التحكم الكهربائي\",\"en\":\"Specialy of Electrical Control\",\"fr\":\"Spécialité de commande électrique\"},\"type\":\"SPECIALTY\",\"terms\":{\"perYear\":2,\"slots\":[7,8,9,10]}}", ), @@ -179,21 +116,20 @@ mod test { for tc in tests { let path = tc.0; + #[cfg(any(feature = "const", feature = "storage"))] let expected = tc.1; #[cfg(feature = "const")] - { - let actual = get_node_by_path(path); - assert_eq!(actual, expected); - } + let actual = get_node_by_path(path); #[cfg(feature = "storage")] - { - let actual = get_node_by_path("../_data", path).ok(); - assert_eq!(actual, expected); - } + let actual = get_node_by_path(Path::new("../_data").join(path)).ok(); + #[cfg(feature = "storage")] + let actual = actual.as_ref(); + + #[cfg(any(feature = "const", feature = "storage"))] + assert_eq!(actual, expected); #[cfg(feature = "serde_derive")] { let expected_stringified = tc.2; - let actual = get_node_by_path("../_data", path).ok(); assert_eq!( serde_json::to_string(&actual).unwrap(), expected_stringified @@ -201,18 +137,4 @@ mod test { } } } - - #[test] - fn should_get_none_when_path_does_not_exist() { - #[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()); - } - } } diff --git a/rust/src/api/mod.rs b/rust/src/api/mod.rs index 832fa85..582fae6 100644 --- a/rust/src/api/mod.rs +++ b/rust/src/api/mod.rs @@ -1,2 +1,2 @@ pub mod get_node_by_path; -mod storage; +pub mod storage; diff --git a/rust/src/api/storage.rs b/rust/src/api/storage.rs index e14b0dc..ab2236e 100644 --- a/rust/src/api/storage.rs +++ b/rust/src/api/storage.rs @@ -1,15 +1,13 @@ -#[cfg(feature = "storage")] +#![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) +pub enum StorageError { + Io(std::io::Error), + Json(serde_json::Error), +} + +pub fn get_node_by_path(path: impl AsRef) -> Result { + let json_file_path = path.as_ref().join("info.json"); + let json_file_content = std::fs::read_to_string(json_file_path).map_err(StorageError::Io)?; + serde_json::from_str::(json_file_content.as_str()).map_err(StorageError::Json) } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 3ee6ef9..0d34b88 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,8 +1,9 @@ #[cfg(feature = "const")] mod _auto_generated; - mod api; mod node; pub use api::get_node_by_path::get_node_by_path; +#[cfg(feature = "storage")] +pub use api::storage::StorageError; pub use node::model::{Node, NodeName, NodeTerms, NodeType}; diff --git a/rust/src/node/model.rs b/rust/src/node/model.rs index d616c0d..2cd0671 100644 --- a/rust/src/node/model.rs +++ b/rust/src/node/model.rs @@ -1,56 +1,54 @@ #[cfg(feature = "serde_derive")] -use serde::{Deserialize, Serialize}; +use serde::Serialize; + +#[cfg(feature = "storage")] +use serde::Deserialize; -#[cfg(feature = "const")] #[derive(Debug, PartialEq)] -#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] -pub struct NodeName<'a> { - pub ar: &'a str, - pub en: &'a str, - pub fr: &'a str, +#[cfg_attr(feature = "serde_derive", derive(Serialize))] +#[cfg(feature = "const")] +pub struct NodeName { + pub ar: &'static str, + pub en: &'static str, + pub fr: &'static str, } -#[cfg(feature = "storage")] #[derive(Debug, PartialEq)] -#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "storage", derive(Serialize))] +#[cfg_attr(feature = "storage", derive(Deserialize))] +#[cfg(feature = "storage")] 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") + derive(Serialize), + serde(tag = "type"), + serde(rename_all = "UPPERCASE") )] +#[cfg_attr(feature = "storage", derive(Deserialize))] 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), + derive(Serialize), serde(rename_all = "camelCase") )] +#[cfg_attr(feature = "storage", derive(Deserialize))] pub struct NodeTerms { pub per_year: usize, #[cfg(feature = "const")] @@ -59,14 +57,10 @@ pub struct NodeTerms { pub slots: Vec, } -#[cfg(any(feature = "const", feature = "storage"))] #[derive(Debug, PartialEq)] -#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde_derive", derive(Serialize))] +#[cfg_attr(feature = "storage", derive(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,