From 621a1e75172f33c2adb00e4042a9f841a09ff1fc Mon Sep 17 00:00:00 2001 From: omdxp Date: Tue, 9 Jan 2024 20:54:29 +0100 Subject: [PATCH 1/6] feat: add storage feature --- rust/Cargo.toml | 1 + rust/src/api/get_node_by_path.rs | 86 +++++++++++++++++++++++++++----- rust/src/api/mod.rs | 1 + rust/src/api/storage.rs | 15 ++++++ rust/src/lib.rs | 2 + rust/src/node/model.rs | 50 +++++++++++++++---- 6 files changed, 134 insertions(+), 21 deletions(-) create mode 100644 rust/src/api/storage.rs diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 0347a87..cba0419 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" default = ["const"] 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 7076b38..2b5cb98 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}; @@ -18,9 +30,18 @@ mod test { "umkb", Some(&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, }), @@ -31,9 +52,18 @@ mod test { "umkb/fst", Some(&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, }), @@ -44,14 +74,26 @@ mod test { "umkb/fst/dee/sec", Some(&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], }, }, }), @@ -65,19 +107,39 @@ mod test { ), ]; - for test_case in tests { - let path = test_case.0; - let expected = test_case.1; - let actual = get_node_by_path(path); - assert_eq!(actual, expected); - #[cfg(feature = "serde_derive")] + for tc in tests { + #[cfg(feature = "const")] + { + let actual = get_node_by_path(tc.path).unwrap(); + assert_node(&tc.expected, &actual); + } + #[cfg(feature = "storage")] { - let expected_stringified = test_case.2; - assert_eq!( - serde_json::to_string(&actual).unwrap(), - expected_stringified - ); + 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() { + #[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) { + assert_eq!( + expected, actual, + "Expected node to be '{:?}', but got '{:?}'", + expected, actual + ); + } } 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 55b57cc..3fb5454 100644 --- a/rust/src/node/model.rs +++ b/rust/src/node/model.rs @@ -1,41 +1,73 @@ #[cfg(feature = "serde_derive")] use serde::Serialize; +#[cfg(feature = "const")] #[derive(Debug, PartialEq)] -#[cfg_attr(feature = "serde_derive", derive(Serialize))] +#[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(feature = "storage")] +#[derive(Debug, PartialEq)] +#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] pub struct NodeName { - #[cfg(feature = "const")] - pub ar: &'static str, - #[cfg(feature = "const")] - pub en: &'static str, - #[cfg(feature = "const")] - pub fr: &'static str, + 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))] +#[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))] +#[cfg_attr( + feature = "serde_derive", + derive(Serialize, Deserialize), + serde(rename_all = "camelCase") +)] pub struct NodeTerms { pub per_year: usize, #[cfg(feature = "const")] 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))] 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, } From 43aaaf7be0cc4fd2c39a4dc529dad470f650adc9 Mon Sep 17 00:00:00 2001 From: omdxp Date: Tue, 9 Jan 2024 21:33:35 +0100 Subject: [PATCH 2/6] fix: tests & CI --- .github/workflows/rust-checks.yml | 3 +- rust/src/api/get_node_by_path.rs | 115 ++++++++++++++++++++++++------ rust/src/node/model.rs | 4 +- 3 files changed, 98 insertions(+), 24 deletions(-) diff --git a/.github/workflows/rust-checks.yml b/.github/workflows/rust-checks.yml index a6a24c1..525016f 100644 --- a/.github/workflows/rust-checks.yml +++ b/.github/workflows/rust-checks.yml @@ -24,4 +24,5 @@ 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 --features serde_derive + - 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/src/api/get_node_by_path.rs b/rust/src/api/get_node_by_path.rs index 2b5cb98..6fd0c6a 100644 --- a/rust/src/api/get_node_by_path.rs +++ b/rust/src/api/get_node_by_path.rs @@ -28,7 +28,8 @@ mod test { let tests = vec![ ( "umkb", - Some(&Node { + Some( + #[cfg(feature = "const")]&Node { name: NodeName { #[cfg(feature = "const")] ar: "جامعة محمد خيضر بسكرة", @@ -44,13 +45,34 @@ mod test { 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, + } + ), #[cfg(feature = "serde_derive")] - "{\"name\":{\"ar\":\"جامعة محمد خيضر بسكرة\",\"en\":\"University of Mohamed Khider Biskra\",\"fr\":\"Université Mohamed Khider Biskra\"},\"type\":\"University\"}", + "{\"name\":{\"ar\":\"جامعة محمد خيضر بسكرة\",\"en\":\"University of Mohamed Khider Biskra\",\"fr\":\"Université Mohamed Khider Biskra\"},\"type\":\"UNIVERSITY\"}", ), ( "umkb/fst", - Some(&Node { + Some( + #[cfg(feature = "const")] + &Node { name: NodeName { #[cfg(feature = "const")] ar: "كلية العلوم والتكنلوجيا", @@ -66,13 +88,60 @@ mod test { 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, + } + ), #[cfg(feature = "serde_derive")] - "{\"name\":{\"ar\":\"كلية العلوم والتكنلوجيا\",\"en\":\"Faculty of Science and Technology\",\"fr\":\"Faculté des Sciences et de la Technologie\"},\"type\":\"Faculty\"}", + "{\"name\":{\"ar\":\"كلية العلوم والتكنلوجيا\",\"en\":\"Faculty of Science and Technology\",\"fr\":\"Faculté des Sciences et de la Technologie\"},\"type\":\"FACULTY\"}", ), ( "umkb/fst/dee/sec", - Some(&Node { + 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: "تخصص التحكم الكهربائي", @@ -96,9 +165,10 @@ mod test { slots: vec![7, 8, 9, 10], }, }, - }), + } + ), #[cfg(feature = "serde_derive")] - "{\"name\":{\"ar\":\"تخصص التحكم الكهربائي\",\"en\":\"Specialy of Electrical Control\",\"fr\":\"Spécialité de commande électrique\"},\"type\":{\"Specialty\":{\"terms\":{\"per_year\":2,\"slots\":[7,8,9,10]}}}}", + "{\"name\":{\"ar\":\"تخصص التحكم الكهربائي\",\"en\":\"Specialy of Electrical Control\",\"fr\":\"Spécialité de commande électrique\"},\"type\":\"SPECIALTY\",\"terms\":{\"perYear\":2,\"slots\":[7,8,9,10]}}", ), ( "does/not/exist", None, @@ -108,15 +178,26 @@ mod test { ]; for tc in tests { + let path = tc.0; + let expected = tc.1; #[cfg(feature = "const")] { - let actual = get_node_by_path(tc.path).unwrap(); - assert_node(&tc.expected, &actual); + let actual = get_node_by_path(path); + assert_eq!(actual, expected); } #[cfg(feature = "storage")] { - let actual = get_node_by_path("../_data", tc.path).unwrap(); - assert_node(&tc.expected, &actual); + let actual = get_node_by_path("../_data", path).ok(); + 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 + ); } } } @@ -134,12 +215,4 @@ mod test { assert!(res.is_err()); } } - - fn assert_node(expected: &Node, actual: &Node) { - assert_eq!( - expected, actual, - "Expected node to be '{:?}', but got '{:?}'", - expected, actual - ); - } } diff --git a/rust/src/node/model.rs b/rust/src/node/model.rs index 3fb5454..d616c0d 100644 --- a/rust/src/node/model.rs +++ b/rust/src/node/model.rs @@ -1,5 +1,5 @@ #[cfg(feature = "serde_derive")] -use serde::Serialize; +use serde::{Deserialize, Serialize}; #[cfg(feature = "const")] #[derive(Debug, PartialEq)] @@ -61,7 +61,7 @@ pub struct NodeTerms { #[cfg(any(feature = "const", feature = "storage"))] #[derive(Debug, PartialEq)] -#[cfg_attr(feature = "serde_derive", derive(Serialize))] +#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] pub struct Node { #[cfg(feature = "const")] #[cfg_attr(feature = "serde_derive", serde(borrow))] From 811736ffa66a27a21dc75715cc4b333df2acea63 Mon Sep 17 00:00:00 2001 From: omdxp Date: Thu, 11 Jan 2024 21:31:52 +0100 Subject: [PATCH 3/6] chore: address PR comments --- .github/workflows/rust-checks.yml | 4 +- rust/src/api/get_node_by_path.rs | 243 ++++++++++-------------------- rust/src/api/mod.rs | 3 +- rust/src/api/storage.rs | 24 +-- rust/src/lib.rs | 5 +- rust/src/node/mod.rs | 2 +- rust/src/node/model.rs | 50 +++--- 7 files changed, 123 insertions(+), 208 deletions(-) diff --git a/.github/workflows/rust-checks.yml b/.github/workflows/rust-checks.yml index 525016f..448eafa 100644 --- a/.github/workflows/rust-checks.yml +++ b/.github/workflows/rust-checks.yml @@ -20,9 +20,9 @@ jobs: - beta - nightly steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - 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 --features serde_derive storage - run: cd rust && cargo test --verbose --no-default-features --features storage diff --git a/rust/src/api/get_node_by_path.rs b/rust/src/api/get_node_by_path.rs index 6fd0c6a..62a9015 100644 --- a/rust/src/api/get_node_by_path.rs +++ b/rust/src/api/get_node_by_path.rs @@ -5,6 +5,8 @@ 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> { @@ -12,161 +14,95 @@ pub fn get_node_by_path(path: &str) -> Option<&Node> { } #[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]}}", ), @@ -177,23 +113,20 @@ mod test { ), ]; - for tc in tests { - let path = tc.0; - let expected = tc.1; + for test_case in tests { + let path = test_case.0; + let expected = test_case.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: Option<&Node> = actual.as_ref(); + + assert_eq!(actual, expected); #[cfg(feature = "serde_derive")] { - let expected_stringified = tc.2; - let actual = get_node_by_path("../_data", path).ok(); + let expected_stringified = test_case.2; assert_eq!( serde_json::to_string(&actual).unwrap(), expected_stringified @@ -201,18 +134,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()); - } - } -} +} \ No newline at end of file diff --git a/rust/src/api/mod.rs b/rust/src/api/mod.rs index 832fa85..a9579d3 100644 --- a/rust/src/api/mod.rs +++ b/rust/src/api/mod.rs @@ -1,2 +1,3 @@ pub mod get_node_by_path; -mod storage; +#[cfg(feature = "storage")] +pub mod storage; \ No newline at end of file diff --git a/rust/src/api/storage.rs b/rust/src/api/storage.rs index e14b0dc..28b60e4 100644 --- a/rust/src/api/storage.rs +++ b/rust/src/api/storage.rs @@ -1,15 +1,15 @@ -#[cfg(feature = "storage")] +#![cfg(feature = "storage")] + use crate::Node; +use std::path::Path; -#[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) +} \ No newline at end of file diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 3ee6ef9..d80042e 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; -pub use node::model::{Node, NodeName, NodeTerms, NodeType}; +#[cfg(feature = "storage")] +pub use api::storage::StorageError; +pub use node::model::{Node, NodeName, NodeTerms, NodeType}; \ No newline at end of file diff --git a/rust/src/node/mod.rs b/rust/src/node/mod.rs index 65880be..99bbd12 100644 --- a/rust/src/node/mod.rs +++ b/rust/src/node/mod.rs @@ -1 +1 @@ -pub mod model; +pub mod model; \ No newline at end of file diff --git a/rust/src/node/model.rs b/rust/src/node/model.rs index d616c0d..1549e93 100644 --- a/rust/src/node/model.rs +++ b/rust/src/node/model.rs @@ -1,56 +1,53 @@ +#[cfg(feature = "storage")] +use serde::Deserialize; #[cfg(feature = "serde_derive")] -use serde::{Deserialize, Serialize}; +use serde::Serialize; -#[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,15 +56,12 @@ 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, -} +} \ No newline at end of file From 3ff99a567fbbef16d727572d9a5fb3a2d995ea9d Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Fri, 12 Jan 2024 20:48:15 +0100 Subject: [PATCH 4/6] Fix serde_derive feature in cargo test --- .github/workflows/rust-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust-checks.yml b/.github/workflows/rust-checks.yml index 448eafa..61b46ed 100644 --- a/.github/workflows/rust-checks.yml +++ b/.github/workflows/rust-checks.yml @@ -24,5 +24,5 @@ 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 --features serde_derive storage + - run: cd rust && cargo test --verbose --features serde_derive - run: cd rust && cargo test --verbose --no-default-features --features storage From 41b370b1d36ffc12c198b6871b01b47ba782b2e0 Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Fri, 12 Jan 2024 20:48:40 +0100 Subject: [PATCH 5/6] Fix formatting issues in Rust code --- rust/src/api/get_node_by_path.rs | 2 +- rust/src/api/mod.rs | 2 +- rust/src/api/storage.rs | 2 +- rust/src/lib.rs | 2 +- rust/src/node/mod.rs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rust/src/api/get_node_by_path.rs b/rust/src/api/get_node_by_path.rs index 62a9015..76f721f 100644 --- a/rust/src/api/get_node_by_path.rs +++ b/rust/src/api/get_node_by_path.rs @@ -134,4 +134,4 @@ mod test { } } } -} \ No newline at end of file +} diff --git a/rust/src/api/mod.rs b/rust/src/api/mod.rs index a9579d3..1e70324 100644 --- a/rust/src/api/mod.rs +++ b/rust/src/api/mod.rs @@ -1,3 +1,3 @@ pub mod get_node_by_path; #[cfg(feature = "storage")] -pub mod storage; \ No newline at end of file +pub mod storage; diff --git a/rust/src/api/storage.rs b/rust/src/api/storage.rs index 28b60e4..317dfbb 100644 --- a/rust/src/api/storage.rs +++ b/rust/src/api/storage.rs @@ -12,4 +12,4 @@ 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) -} \ No newline at end of file +} diff --git a/rust/src/lib.rs b/rust/src/lib.rs index d80042e..0d34b88 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -6,4 +6,4 @@ 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}; \ No newline at end of file +pub use node::model::{Node, NodeName, NodeTerms, NodeType}; diff --git a/rust/src/node/mod.rs b/rust/src/node/mod.rs index 99bbd12..65880be 100644 --- a/rust/src/node/mod.rs +++ b/rust/src/node/mod.rs @@ -1 +1 @@ -pub mod model; \ No newline at end of file +pub mod model; From 03adf299df8ea2c94f174ab1bda4590fa04e716f Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Fri, 12 Jan 2024 20:48:57 +0100 Subject: [PATCH 6/6] Fix serde_derive attribute in NodeName struct --- rust/src/node/model.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/src/node/model.rs b/rust/src/node/model.rs index 1549e93..b6f681a 100644 --- a/rust/src/node/model.rs +++ b/rust/src/node/model.rs @@ -13,7 +13,7 @@ pub struct NodeName { } #[derive(Debug, PartialEq)] -#[cfg_attr(feature = "storage", derive(Serialize))] +#[cfg_attr(feature = "serde_derive", derive(Serialize))] #[cfg_attr(feature = "storage", derive(Deserialize))] #[cfg(feature = "storage")] pub struct NodeName { @@ -64,4 +64,4 @@ pub struct Node { pub name: NodeName, #[cfg_attr(feature = "serde_derive", serde(flatten))] pub r#type: NodeType, -} \ No newline at end of file +}