From 2fbc4ae970850eaddfcc50bb9da04420dedd66bd Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Thu, 4 Jan 2024 23:59:12 +0100 Subject: [PATCH 1/2] generate `src/_data.rs` from `../_data` --- rust/.gitignore | 1 + rust/Cargo.lock | 30 ++++++++++++++++++++++++ rust/Cargo.toml | 5 ++++ rust/gen_data.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ rust/src/lib.rs | 2 ++ 5 files changed, 99 insertions(+) diff --git a/rust/.gitignore b/rust/.gitignore index d20f533..529eb7d 100644 --- a/rust/.gitignore +++ b/rust/.gitignore @@ -1,2 +1,3 @@ target src/_data +src/_data.rs diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 0067692..62cb638 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -2,6 +2,28 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "itoa" version = "1.0.10" @@ -12,10 +34,17 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" name = "kuliya" version = "0.1.0" dependencies = [ + "lazy_static", "serde", "serde_json", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "proc-macro2" version = "1.0.74" @@ -66,6 +95,7 @@ version = "1.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fbd975230bada99c8bb618e0c365c2eefa219158d5c6c29610fd09ff1833257" dependencies = [ + "indexmap", "itoa", "ryu", "serde", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 4144911..aff1b2c 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -7,5 +7,10 @@ build = "gen_data.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +lazy_static = "1.4.0" serde = { version = "1.0.194", features = ["derive"] } serde_json = "1.0.110" + +[build-dependencies] +serde = { version = "1.0.194", features = ["derive"] } +serde_json = { version = "1.0.110", features = ["preserve_order"] } diff --git a/rust/gen_data.rs b/rust/gen_data.rs index df7cc8f..807e873 100644 --- a/rust/gen_data.rs +++ b/rust/gen_data.rs @@ -1,3 +1,4 @@ +use serde_json::{json, Value}; use std::{fs, io, path::Path}; fn copy_dir_all(src: impl AsRef, dst: impl AsRef) -> io::Result<()> { @@ -14,6 +15,66 @@ fn copy_dir_all(src: impl AsRef, dst: impl AsRef) -> io::Result<()> Ok(()) } +fn directory_to_object(dir: impl AsRef) -> Value { + let info_path = dir.as_ref().join("info.json"); + let info_dot_json = match info_path.exists() { + true => { + let info = fs::read_to_string(info_path).unwrap(); + let info: Value = serde_json::from_str(info.as_str()).unwrap(); + let mut info = info.as_object().unwrap().clone(); + info.remove("$schema"); + Value::Object(info) + } + false => Value::Object(serde_json::Map::new()), + }; + + let sub_dirs = fs::read_dir(dir).unwrap(); + let children = sub_dirs + .filter_map(|entry| { + let entry = entry.unwrap(); + let ty = entry.file_type().unwrap(); + if ty.is_dir() { + let file_name = entry.file_name().into_string().unwrap(); + Some((file_name, directory_to_object(entry.path()))) + } else { + None + } + }) + .collect::>(); + + json!({ + "info": info_dot_json, + "children": children, + }) +} + +fn generate_data_file() -> Result<(), io::Error> { + let json_tree = directory_to_object("../_data"); + let json_tree = json_tree.get("children").unwrap(); + + let data = format!( + r##"// This is auto-generated file. Do not edit it manually. + +use lazy_static::lazy_static; +use serde_json::Value; + +lazy_static! {{ + pub static ref DATA: Value = {{ + let data = r#" +{} + "#; + serde_json::from_str(data).unwrap() + }}; +}} +"##, + serde_json::to_string_pretty(json_tree).unwrap() + ); + + fs::write("./src/_data.rs", data)?; + Ok(()) +} + fn main() { + generate_data_file().unwrap(); copy_dir_all(Path::new("../_data"), Path::new("./src/_data")).unwrap(); } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 402f5bc..d802d35 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,3 +1,5 @@ +mod _data; + use std::fs; use serde::{Deserialize, Serialize}; From 8d8fa6daf0f4dd47030b4be1a1c644317a2a2fec Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Thu, 4 Jan 2024 23:59:49 +0100 Subject: [PATCH 2/2] Add get_node_by_path API and test cases --- rust/src/api/get_node_by_path.rs | 37 ++++++++++++++++++++++++++++++++ rust/src/api/mod.rs | 1 + rust/src/lib.rs | 1 + 3 files changed, 39 insertions(+) create mode 100644 rust/src/api/get_node_by_path.rs create mode 100644 rust/src/api/mod.rs diff --git a/rust/src/api/get_node_by_path.rs b/rust/src/api/get_node_by_path.rs new file mode 100644 index 0000000..bb906b6 --- /dev/null +++ b/rust/src/api/get_node_by_path.rs @@ -0,0 +1,37 @@ +use crate::{Schema, _data::DATA}; + +pub fn get_node_by_path(path: &str) -> Option { + let path = path.trim_start_matches('/'); + let path = path.trim_end_matches('/'); + let path = path.split('/').collect::>(); + + let mut node = DATA.clone(); + + for part in path { + node = node.get(part)?.clone(); + } + + let node = node.get("info")?.clone(); + let node: Schema = serde_json::from_value(node).unwrap(); + + Some(node) +} + +#[cfg(test)] +mod test { + use crate::api::get_node_by_path::get_node_by_path; + + #[test] + fn check_umkb_info() { + let result = get_node_by_path("umkb"); + + assert_eq!(format!("{:?}", result), "Some(Schema { name: Name { ar: \"جامعة محمد خيضر بسكرة\", en: \"University of Mohamed Khider Biskra\", fr: \"Université Mohamed Khider Biskra\" }, ty: University, terms: None })"); + } + + #[test] + fn check_non_valid_info() { + let result = get_node_by_path("non-valid"); + + assert_eq!(format!("{:?}", result), "None"); + } +} diff --git a/rust/src/api/mod.rs b/rust/src/api/mod.rs new file mode 100644 index 0000000..eea4aed --- /dev/null +++ b/rust/src/api/mod.rs @@ -0,0 +1 @@ +pub mod get_node_by_path; diff --git a/rust/src/lib.rs b/rust/src/lib.rs index d802d35..c12b4d6 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,4 +1,5 @@ mod _data; +pub mod api; use std::fs;