Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add storage feature #58

Merged
merged 6 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/rust-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
omdxp marked this conversation as resolved.
Show resolved Hide resolved
- run: cd rust && cargo test --verbose --no-default-features --features storage
ZibanPirate marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
167 changes: 151 additions & 16 deletions rust/src/api/get_node_by_path.rs
Original file line number Diff line number Diff line change
@@ -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<Node, std::io::Error> {
omdxp marked this conversation as resolved.
Show resolved Hide resolved
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};
Expand All @@ -16,47 +28,147 @@ mod test {
let tests = vec![
(
"umkb",
Some(&Node {
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,
}
),
#[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: "كلية العلوم والتكنلوجيا",
#[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,
}
),
#[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")]
omdxp marked this conversation as resolved.
Show resolved Hide resolved
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],
},
},
}
),
#[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,
Expand All @@ -65,19 +177,42 @@ 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);
for tc in tests {
let path = tc.0;
let expected = tc.1;
#[cfg(feature = "const")]
{
let actual = get_node_by_path(path);
assert_eq!(actual, expected);
}
#[cfg(feature = "storage")]
{
let actual = get_node_by_path("../_data", path).ok();
assert_eq!(actual, expected);
}
#[cfg(feature = "serde_derive")]
{
let expected_stringified = test_case.2;
let expected_stringified = tc.2;
let actual = get_node_by_path("../_data", path).ok();
omdxp marked this conversation as resolved.
Show resolved Hide resolved
assert_eq!(
serde_json::to_string(&actual).unwrap(),
expected_stringified
);
}
}
}

#[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());
}
}
}
1 change: 1 addition & 0 deletions rust/src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod get_node_by_path;
mod storage;
15 changes: 15 additions & 0 deletions rust/src/api/storage.rs
Original file line number Diff line number Diff line change
@@ -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<Node, std::io::Error> {
omdxp marked this conversation as resolved.
Show resolved Hide resolved
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::<Node>(info.as_str()) else {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"json was not deserialized",
));
};
Ok(node)
}
2 changes: 2 additions & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#[cfg(feature = "const")]
mod _auto_generated;

omdxp marked this conversation as resolved.
Show resolved Hide resolved
mod api;
mod node;

Expand Down
54 changes: 43 additions & 11 deletions rust/src/node/model.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,73 @@
#[cfg(feature = "serde_derive")]
use serde::Serialize;
use serde::{Deserialize, Serialize};
omdxp marked this conversation as resolved.
Show resolved Hide resolved

#[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,
}
omdxp marked this conversation as resolved.
Show resolved Hide resolved

#[cfg(feature = "storage")]
#[derive(Debug, PartialEq)]
#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#[cfg(feature = "storage")]
#[derive(Debug, PartialEq)]
#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))]
#[cfg(feature = "storage")]
#[derive(Debug, PartialEq, 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"))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need this

Suggested change
#[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")
)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we only need Serialize for feature serde_derive, everything else is needed by storage

Suggested change
#[cfg_attr(
feature = "serde_derive",
derive(Serialize, Deserialize),
serde(tag = "type")
)]
#[cfg_attr(feature = "serde_derive", derive(Serialize))]
#[cfg_attr(feature = "storage", derive(Deserialize), serde(tag = "type"))]
)]

pub enum NodeType {
#[cfg_attr(feature = "serde_derive", serde(rename = "UNIVERSITY"))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can replace all these renamings with one serde(rename_all = "UPPERCASE") on the struct level

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")
)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we only need Serialize for feature serde_derive, everything else is needed by storage

Suggested change
#[cfg_attr(
feature = "serde_derive",
derive(Serialize, Deserialize),
serde(rename_all = "camelCase")
)]
#[cfg_attr(feature = "serde_derive", derive(Serialize))]
#[cfg_attr(
feature = "storage",
derive(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<i32>,
}

#[cfg(any(feature = "const", feature = "storage"))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need this

Suggested change
#[cfg(any(feature = "const", feature = "storage"))]

#[derive(Debug, PartialEq)]
#[cfg_attr(feature = "serde_derive", derive(Serialize))]
#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))]
omdxp marked this conversation as resolved.
Show resolved Hide resolved
pub struct Node {
#[cfg(feature = "const")]
#[cfg_attr(feature = "serde_derive", serde(borrow))]
pub name: NodeName<'static>,
#[cfg(feature = "storage")]
omdxp marked this conversation as resolved.
Show resolved Hide resolved
pub name: NodeName,
#[cfg_attr(feature = "serde_derive", serde(flatten))]
pub r#type: NodeType,
}