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

Poc of generating _data.rs from ../_data folder #47

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions rust/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
target
src/_data
src/_data.rs
30 changes: 30 additions & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"] }
61 changes: 61 additions & 0 deletions rust/gen_data.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use serde_json::{json, Value};
use std::{fs, io, path::Path};

fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
Expand All @@ -14,6 +15,66 @@ fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()>
Ok(())
}

fn directory_to_object(dir: impl AsRef<Path>) -> 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::<serde_json::Map<String, Value>>();

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();
}
37 changes: 37 additions & 0 deletions rust/src/api/get_node_by_path.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use crate::{Schema, _data::DATA};

pub fn get_node_by_path(path: &str) -> Option<Schema> {
let path = path.trim_start_matches('/');
let path = path.trim_end_matches('/');
let path = path.split('/').collect::<Vec<_>>();

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");
}
}
1 change: 1 addition & 0 deletions rust/src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod get_node_by_path;
3 changes: 3 additions & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
mod _data;
pub mod api;

use std::fs;

use serde::{Deserialize, Serialize};
Expand Down