sdk-builder: main function does stuff
This commit is contained in:
parent
c453a63c56
commit
98b8d0378f
|
@ -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"] }
|
||||||
|
|
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue