sdk-builder: main function does stuff

This commit is contained in:
Janis 2023-06-29 16:25:31 +02:00
parent c453a63c56
commit 98b8d0378f
2 changed files with 101 additions and 10 deletions

View file

@ -15,3 +15,4 @@ unreal-sdk = {path = "../unreal-sdk"}
quote = "1.0.28" quote = "1.0.28"
proc-macro2 = "1.0.60" proc-macro2 = "1.0.60"
clap = { version = "4.3.9", features = ["derive"] }

View file

@ -1,9 +1,50 @@
use std::{borrow::Cow, collections::BTreeMap}; use std::{borrow::Cow, collections::BTreeMap, path::PathBuf};
use unreal_sdk::sdk::repr::ObjectRef; use clap::{Args, Parser, Subcommand};
use unreal_sdk::sdk::repr::{ObjectRef, Sdk};
fn main() { use crate::rust::Builder;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
pub struct Cli {
#[command(subcommand)]
commands: Option<Commands>,
}
#[derive(Args)]
pub struct Build {
#[arg(short, long)]
in_archive: PathBuf,
/// directory into which the sdk will be dumped.
#[arg(short, long)]
out: Option<PathBuf>,
#[arg(short, long, default_value = "false")]
single_file: bool,
#[arg(short, long, default_value = "true")]
feature_gate: bool,
}
#[derive(Subcommand)]
pub enum Commands {
Build(Build),
}
fn main() -> anyhow::Result<()> {
println!("Hello, world!"); println!("Hello, world!");
let cli = Cli::parse();
if let Some(Commands::Build(build)) = &cli.commands {
let sdk = Sdk::from_path_ron(&build.in_archive)?;
let builder = Builder::new(sdk);
let path = build.out.clone().unwrap_or(std::env::current_dir()?);
builder.build_in_dir(path, build)?;
}
Ok(())
} }
struct SplitResult<'a> { struct SplitResult<'a> {
@ -97,9 +138,10 @@ pub struct CanonicalNames {
} }
pub mod rust { pub mod rust {
use std::{borrow::Cow, collections::BTreeMap}; use std::{borrow::Cow, collections::BTreeMap, path::Path};
use anyhow::Context; use anyhow::Context;
use itertools::Itertools;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote}; use quote::{format_ident, quote};
use unreal_sdk::sdk::repr::{ use unreal_sdk::sdk::repr::{
@ -170,11 +212,18 @@ pub mod rust {
} }
/// returns the absolute path of a type with the assumption that all /// returns the absolute path of a type with the assumption that all
/// packages are children of the path `::crate::sdk` /// packages are children of the path `crate::sdk`
fn get_type_package_path(&self, key: &ObjectRef) -> Option<String> {
let pkg = &self.sdk.packages.get(&key.package)?.name;
Some(format!("crate::sdk::{pkg}"))
}
/// returns the absolute path of a type with the assumption that all
/// packages are children of the path `crate::sdk`
fn get_type_path(&self, key: &ObjectRef) -> Option<String> { fn get_type_path(&self, key: &ObjectRef) -> Option<String> {
let pkg = &self.sdk.packages.get(&key.package)?.name; let pkg = &self.sdk.packages.get(&key.package)?.name;
self.get_type_name(key) self.get_type_name(key)
.map(|name| format!("::crate::sdk::{pkg}::{name}")) .map(|name| format!("crate::sdk::{pkg}::{name}"))
} }
/// returns the precached, prefixed and cannonicalized (for this /// returns the precached, prefixed and cannonicalized (for this
@ -201,11 +250,52 @@ pub mod rust {
} }
} }
pub fn build(self) -> anyhow::Result<()> { pub fn build(self, args: &super::Build) -> anyhow::Result<BTreeMap<String, TokenStream>> {
for pkg in self.sdk.packages.values() { let packages = self
self.generate_package(pkg)?; .sdk
.packages
.values()
.map(|pkg| {
let name = pkg.name.clone();
let tokens = self.generate_package(pkg, args.feature_gate)?;
anyhow::Ok((name, tokens))
})
.collect::<Result<BTreeMap<_, _>, _>>()?;
Ok(packages)
} }
pub fn build_in_dir<P: AsRef<Path>>(
self,
path: P,
args: &super::Build,
) -> anyhow::Result<()> {
let packages = self.build(args)?;
let path = path.as_ref();
std::fs::create_dir_all(&path)?;
let mut mod_rs = TokenStream::new();
for (name, tokens) in packages {
if args.single_file {
mod_rs.extend(quote! {
pub mod #name {
#tokens
}
});
} else {
std::fs::write(path.join(format!("{name}.rs")), tokens.to_string())?;
mod_rs.extend(quote! {
pub mod #name;
});
}
}
std::fs::write(path.join("mod.rs"), mod_rs.to_string())?;
Ok(()) Ok(())
} }