ligen-core 0.1.0

Language Interface Generator Core
Documentation
use crate::Object;
use crate::Attribute;
use crate::Attributes;

use libloading as lib;

use std::ffi::c_void;

pub struct File {
    pub path : String,
    pub content : String
}

impl File {
    pub fn new(path: String, content: String) -> File {
        File {
            path,
            content
        }
    }
}

pub struct Files {
    pub files : Vec<File>
}

use std::io::Write;
use std::path::Path;

use std::fs;

impl Files {
    pub fn from(files : Vec<File>) -> Files {
        Files {
            files
        }
    }
    pub fn push(&mut self, file : File) {
        self.files.push(file);
    }
    fn save(&self) {
        for file in &self.files {
            let ligen_path = crate::get_path();
            let path = format!("{}/{}", ligen_path, file.path);
            let path = Path::new(&path);
            let dir = path.parent().unwrap();
            match fs::create_dir_all(&dir) { _ => () }
            let mut output = std::fs::File::create(&path).unwrap();
            output.write_all(file.content.as_bytes()).unwrap();
        }
    }
}

pub struct Generator {
    library: lib::Library,
    generator: *mut c_void
}

impl Generator {
    pub fn new(attribute: &Attribute) -> Result<Generator, String> {
        let (name, attributes) = match attribute {
            Attribute::Group(identifier, attributes) => (&identifier.name, attributes),
            Attribute::Named(_, _) => return Result::Err(format!("[1] Wrong attribute")),
            Attribute::Literal(_) => return Result::Err(format!("[2] Wrong attribute"))
        };

        eprintln!("Loading {}", name);

        let library = lib::Library::new(format!("{}/../ligen_{}", crate::get_path(), name));
        match library {
            Ok(library) => {
                let generator = unsafe {
                     let generator_new : lib::Symbol<extern fn(&Attributes) -> *mut c_void> = library.get(b"Generator_new").unwrap();
                     generator_new(&attributes)
                };
                Result::Ok(Generator{library, generator})
            },
            Err(_) => Result::Err(format!("Library file not found"))
        }
    }

    pub fn generate(&self, object: &Object) {
        let generate : lib::Symbol<extern fn(*mut c_void, &Object) -> *mut Files> = unsafe {
             self.library.get(b"Generator_generate").unwrap()
        };
        let files = unsafe {
            &*generate(self.generator, &object)
        };
        files.save();
    }
}