Skip to content

Commit

Permalink
feat(definitions): add initial implementation of data driven entity g…
Browse files Browse the repository at this point in the history
…eneration (#25)
  • Loading branch information
eexsty committed Apr 24, 2022
1 parent 46c3687 commit e4fbc3c
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 10 deletions.
21 changes: 21 additions & 0 deletions definitions/example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
entities:
- name: Player
package: org.hexalite.generation.entity
feature_flag: example
fields:
a:
kind:
kotlin: java.util.UUID
rust: String
sql: 'uuid().not_null().primary_key()'
test_c:
kind:
kotlin: Int
rust: u32
sql: 'integer().not_null().default(0)'
hello_d:
kind:
kotlin: String
rust: String
sql: 'varchar(255).not_null().default("")'
1 change: 1 addition & 0 deletions definitions/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ syn = "^1"
quote = "^1"
serde = { version = "^1", features = ["derive"] }
serde_yaml = "^0.8"
home = "^0"
4 changes: 4 additions & 0 deletions definitions/rust/generated/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@ version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
example = []
default = ["example"]

[dependencies]
definitions-generator = { path = "../" }
3 changes: 2 additions & 1 deletion definitions/rust/generated/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@

#[cfg(feature = "example")]
definitions_generator::generate_entity_definitions!("definitions/example.yml");
70 changes: 69 additions & 1 deletion definitions/rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,69 @@
mod specification;
use std::fs;

use proc_macro::TokenStream;
use quote::format_ident;
use specification::SpecificationRoot;

mod specification;

#[proc_macro]
pub fn generate_entity_definitions(item: TokenStream) -> TokenStream {
let mut path = item.to_string();
path.pop();
path.remove(0);

let code = path
.split("|")
.map(|path| {
let home = home::home_dir().expect("Could not find home directory");

let root = home
.join(".hexalite")
.join("dev")
.canonicalize()
.expect("Could not find ~/.hexalite/dev directory");

let file = root.join(path);
let file = fs::read_to_string(&file)
.expect(format!("Nao achou em {}", file.display()).as_str());

let specification: SpecificationRoot =
serde_yaml::from_str(file.as_str()).expect("Could not parse specification");

let quotes = specification
.entities
.iter()
.map(|specification| {
let struct_fields_name = specification
.fields
.iter()
.map(|(name, _)| format_ident!("{}", name.clone().trim().to_string()))
.collect::<Vec<_>>();
let struct_fields_kind = specification
.fields
.iter()
.map(|(_, field)| format_ident!("{}", field.kind.rust.trim().to_string()))
.collect::<Vec<_>>();
let name = format_ident!("{}", specification.name.trim());

quote::quote! {
#[derive(Debug, Clone)]
pub struct #name {
#(pub #struct_fields_name: #struct_fields_kind),*
}
}
})
.collect::<Vec<_>>();

quote::quote! {
#(#quotes)
*
}
})
.collect::<Vec<_>>();

TokenStream::from(quote::quote! {
#(#code)
*
})
}
22 changes: 14 additions & 8 deletions definitions/rust/src/specification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,27 @@ use serde::Deserialize;

#[derive(Debug, Clone, Deserialize)]
pub struct SpecificationRoot {
pub name: String,
pub location: RustAndKotlinType,
pub feature_flag: String,
pub fields: HashMap<String, SpecificationField>
pub entities: Vec<SpecificationEntity>
}

#[derive(Debug, Clone, Deserialize)]
pub struct RustAndKotlinType {
pub rust: String,
pub kotlin: String
pub struct SpecificationEntity {
pub name: String,
#[serde(rename = "package")]
pub kotlin_package: String,
pub feature_flag: String,
pub fields: HashMap<String, SpecificationField>
}

#[derive(Debug, Clone, Deserialize)]
pub struct SpecificationField {
pub kind: RustAndKotlinType,
pub kind: SpecificationFieldKind,
#[serde(default)]
pub sql: Option<String>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct SpecificationFieldKind {
pub rust: String,
pub kotlin: String
}

0 comments on commit e4fbc3c

Please sign in to comment.