From a2233bb3b4302fe7dc9c2c282e892c87aed09440 Mon Sep 17 00:00:00 2001 From: Janis Date: Tue, 18 Apr 2023 23:24:07 +0200 Subject: [PATCH] enum processing --- src/lib.rs | 57 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2c8e5d7..ae1c35c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,8 @@ pub mod types; pub mod sdk { use std::{ borrow::Cow, - collections::{hash_map::Entry, BTreeSet, HashMap, HashSet}, + collections::{hash_map::Entry, BTreeMap, BTreeSet, HashMap, HashSet}, + fmt::Display, sync::Mutex, }; @@ -158,6 +159,7 @@ pub mod sdk { UAnyType::UProperty(_) => {} UAnyType::UEnum(obj) => { let enm = Self::process_enum(obj)?; + log::info!("enum: {enm}"); } UAnyType::UStruct(_) => {} UAnyType::UFunction(_) => {} @@ -168,12 +170,44 @@ pub mod sdk { } fn process_enum(enm: UEnum) -> anyhow::Result { + // get all the variants let values = enm .get_names() .iter() - .map(|name| name.get_name().unwrap_or("AnonymousVariant".to_string())) - .map(|name| canonicalize_name(&name).to_string()) - .collect::>(); + .enumerate() + // canonicalize the names into valid rust + .map(|(value, name)| { + let name = name.get_name().unwrap_or("AnonymousVariant".to_string()); + let name = canonicalize_name(&name).to_string(); + (value, name) + }) + // store conflicts next to each other + .fold( + HashMap::>::new(), + |mut acc, (value, name)| { + match acc.entry(name) { + Entry::Occupied(mut entry) => { + entry.get_mut().push(value); + } + Entry::Vacant(entry) => { + entry.insert(vec![value]); + } + } + acc + }, + ); + + // sort by value + let mut variants = BTreeMap::new(); + values.into_iter().for_each(|(name, values)| { + if values.len() > 0 { + for (i, value) in values.into_iter().enumerate() { + variants.insert(value, format!("{name}{i}")); + } + } else { + variants.insert(values.into_iter().next().unwrap(), name); + } + }); let name = enm .as_uobject() @@ -181,7 +215,10 @@ pub mod sdk { .context("enum name could not be found")?; let name = canonicalize_name(&name).to_string(); - Ok(Enum { name, values }) + Ok(Enum { + name, + values: variants.into_iter().map(|(_, name)| name).collect(), + }) } } @@ -299,4 +336,14 @@ pub mod sdk { name: String, values: Vec, } + + impl Display for Enum { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "enum {} {{", self.name)?; + for (i, name) in self.values.iter().enumerate() { + writeln!(f, "\t{} = {},", name, i)?; + } + writeln!(f, "}}\n") + } + } }