Skip to content

Commit

Permalink
Start of generator rework
Browse files Browse the repository at this point in the history
  • Loading branch information
notdanilo committed Nov 9, 2023
1 parent 4ebafcf commit a15334d
Show file tree
Hide file tree
Showing 16 changed files with 202 additions and 286 deletions.
1 change: 1 addition & 0 deletions ecosystem/rust/cargo/src/exporter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use ligen_traits::prelude::*;
pub struct CargoGenerator;

impl FileGenerator for CargoGenerator {
type Input = Library;
fn base_path(&self) -> PathBuf {
PathBuf::from("rust".to_string())
}
Expand Down
55 changes: 35 additions & 20 deletions ecosystem/rust/importer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,52 @@
pub mod prelude;
use std::{path::PathBuf, str::FromStr};
pub mod module_generator;
pub use module_generator::*;

use ligen_ir::{Module, Library};
use std::path::PathBuf;

use ligen_ir::Library;
use prelude::*;

use ligen_generator::{file_generator::{TemplateRegister, Template, TemplateBasedGenerator}, register_templates};
use ligen_generator::file_generator::{FileGenerator, FileSet, Template};

#[derive(Debug, Default)]
pub struct RustImporter {}
pub struct LibraryGenerator {}

impl TemplateRegister for RustImporter {
fn register_templates(&self, template: &mut Template) -> Result<()> {
register_templates!(template, module);
// register_templates!(template, identifier, arguments, implementation, method, function, module, object, parameters, library);
impl LibraryGenerator {
pub fn generate_project_file(&self, library: &Library, file_set: &mut FileSet) -> Result<()> {
let file = file_set.entry(PathBuf::from("Cargo.toml"));
let mut template = Template::new();
template.register_template("project", include_str!("templates/Cargo.hbs"))?;
let template = template.render("project", &library)?;
let root = file.section("root");
root.write(template);
Ok(())
}

pub fn generate_lib_file(&self, library: &Library, file_set: &mut FileSet) -> Result<()> {
let file = file_set.entry(PathBuf::from("src").join("lib.rs"));
let section = file.section("documentation");
section.writeln(library.metadata.description.split("\n").map(|s| format!("//! {}", s)).collect::<Vec<String>>().join("\n"));
Ok(())
}
}

impl TemplateBasedGenerator for RustImporter {
fn register_functions(&self, _library: &Library, _template: &mut Template) {
//register_functions!(template, mapped_type, marshal_output);
pub fn generate_readme(&self, library: &Library, file_set: &mut FileSet) -> Result<()> {
let file = file_set.entry(PathBuf::from("README.md"));
let root = file.section("root");
root.write(&library.metadata.description);
Ok(())
}
}

impl FileGenerator for LibraryGenerator {
type Input = Library;
fn base_path(&self) -> PathBuf {
PathBuf::from("python".to_string())
PathBuf::from("rust".to_string())
}

fn module_generation_path(&self, library: &Library, module: &Module) -> PathBuf {
let is_root_module = library.root_module == *module;
let name = if is_root_module { "lib.rs" } else { "mod.rs" };
let mut path = PathBuf::from_str("src").unwrap();
path = path.join(PathBuf::from(module.identifier.name.clone()));
path = path.join(name);
path
fn generate_files(&self, library: &Library, file_set: &mut FileSet) -> Result<()> {
self.generate_project_file(library, file_set)?;
self.generate_lib_file(library, file_set)?;
Ok(())
}
}
Empty file.
10 changes: 10 additions & 0 deletions ecosystem/rust/importer/src/templates/Cargo.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "{{identifier.name}}"
version = "{{metadata.version}}"
edition = "2021"
description = "{{metadata.summary}}"
license = "{{metadata.license}}"
homepage = "{{metadata.homepage}}"
authors = [{{#each metadata.authors}}"{{name}} <{{email}}>"{{#unless @last}}, {{/unless}}{{/each}}]
keywords = [{{#each metadata.keywords}}"{{this}}"{{#unless @last}}, {{/unless}}{{/each}}]
readme = "README.md"
129 changes: 0 additions & 129 deletions ecosystem/rust/importer/src/templates/ligen/python/instagrapi/src

This file was deleted.

29 changes: 12 additions & 17 deletions ligen/generator/src/generator/file_generator/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,38 +36,34 @@ pub struct File {
pub path: PathBuf,
/// File sections.
pub sections: BTreeMap<String, FileSection>,
order: Vec<String>
}

impl File {
/// Creates a new file with the specified path and content.
pub fn new(path: impl AsRef<std::path::Path>) -> Self {
let sections = Default::default();
let path = path.as_ref().to_path_buf();
Self { path, sections }
let order = Default::default();
Self { path, sections, order }
}

/// Gets or creates a new section with the specified name.
pub fn section(&mut self, name: impl AsRef<str>) -> &mut FileSection {
self
.sections
.entry(name.as_ref().to_string())
.or_default()
.or_insert_with(|| {
self.order.push(name.as_ref().to_string());
Default::default()
})
}

/// Gets content.
pub fn content(&self) -> String {
let mut content = String::new();
for section in self.sections.values() {
content.push_str(&section.content);
}
content
}

/// Gets content in order.
pub fn content_in_order<S: AsRef<str>, A: AsRef<[S]>>(&self, order: A) -> String {
let mut content = String::new();
for section in order.as_ref() {
if let Some(section) = self.sections.get(section.as_ref()) {
for section in &self.order {
if let Some(section) = self.sections.get(section) {
content.push_str(&section.content);
}
}
Expand Down Expand Up @@ -98,8 +94,8 @@ impl FileSet {
}

/// Returns an existing File assigned to an entry or creates a new one if it isn't present.
pub fn entry(&mut self, path: &Path) -> &mut File {
self.files.entry(path.to_path_buf()).or_insert(File::new(path))
pub fn entry(&mut self, path: impl AsRef<Path>) -> &mut File {
self.files.entry(path.as_ref().to_path_buf()).or_insert(File::new(path))
}
}

Expand All @@ -112,7 +108,6 @@ mod tests {
let mut file = File::new("path");
file.section("b").write("B");
file.section("a").write("A");
assert_eq!(file.content(), "AB");
assert_eq!(file.content_in_order(["b", "a"]), "BA");
assert_eq!(file.content(), "BA");
}
}
18 changes: 9 additions & 9 deletions ligen/generator/src/generator/file_generator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,25 @@ pub use template_based::*;
use crate::prelude::*;
use crate::generator::Generator;

use ligen_ir::Library;
use ligen_utils::fs::write_file;
use std::path::PathBuf;

/// File generator.
pub trait FileGenerator {
type Input;
// TODO: Fetch this from the generator configuration instead and possibly default to something if it doesn't exist.
/// Generation base path.
fn base_path(&self) -> PathBuf;

/// Generate files.
fn generate_files(&self, library: &Library, file_set: &mut FileSet) -> Result<()>;
fn generate_files(&self, input: &Self::Input, file_set: &mut FileSet) -> Result<()>;

/// Saves the file set.
fn save_file_set(&self, library: &Library, file_set: FileSet, folder: &std::path::Path) -> Result<()> {
fn save_file_set(&self, file_set: FileSet, folder: &std::path::Path) -> Result<()> {
let target = folder.to_path_buf();
let target_ligen_dir = target
let library_dir = target
.join("ligen")
.join(self.base_path());
let library_dir = target_ligen_dir.join(library.identifier.clone().to_string());
for (_path, file) in file_set.files {
let file_path = library_dir.join(&file.path);
write_file(&file_path, &file.content())?;
Expand All @@ -37,11 +36,12 @@ pub trait FileGenerator {
}
}

impl <T: FileGenerator> Generator for T {
fn generate(&self, library: &Library, folder: &std::path::Path) -> Result<()> {
impl <I, T: FileGenerator<Input = I>> Generator for T {
type Input = I;
fn generate(&self, input: &Self::Input, folder: &std::path::Path) -> Result<()> {
let mut file_set = FileSet::default();
self.generate_files(library, &mut file_set)?;
self.save_file_set(library, file_set, folder)?;
self.generate_files(input, &mut file_set)?;
self.save_file_set(file_set, folder)?;
Ok(())
}
}
Loading

0 comments on commit a15334d

Please sign in to comment.