initial commit
This commit is contained in:
commit
065844a66b
15 changed files with 9722 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
2037
Cargo.lock
generated
Normal file
2037
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
4
Cargo.toml
Normal file
4
Cargo.toml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[workspace]
|
||||||
|
resolver = "3"
|
||||||
|
members = [ "core","gui"]
|
||||||
|
|
16
core/Cargo.toml
Normal file
16
core/Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "core"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
confique = { version = "0.3.0", features = ["toml"] }
|
||||||
|
derive_more = { version = "2.0.1", features = ["display", "from_str"] }
|
||||||
|
directories = "6.0.0"
|
||||||
|
serde = "1.0.219"
|
||||||
|
toml = "0.8.23"
|
||||||
|
unity_release_api = { git = "https://git.kitsu.cafe/rowan/unity-release-client.git", version = "0.1.0" }
|
||||||
|
osstr_traits = { path = "../../osstr_traits/crates/osstr_traits", version = "0.1.0" }
|
||||||
|
osstr_traits_derive = { path = "../../osstr_traits/crates/osstr_traits_derive", version = "0.1.0" }
|
||||||
|
#osstr_traits = { git = "https://git.kitsu.cafe/rowan/osstr-traits.git", version = "0.1.0" }
|
||||||
|
#osstr_traits_derive = { git = "https://git.kitsu.cafe/rowan/osstr-traits.git", version = "0.1.0" }
|
6355
core/blah.rs
Normal file
6355
core/blah.rs
Normal file
File diff suppressed because it is too large
Load diff
170
core/src/collection.rs
Normal file
170
core/src/collection.rs
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
use std::{
|
||||||
|
borrow::Cow,
|
||||||
|
ffi::{OsStr, OsString},
|
||||||
|
fmt::Display,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
|
use derive_more::Display;
|
||||||
|
use osstr_traits::{OsDisplay, ToOsString};
|
||||||
|
|
||||||
|
type OsStrDisplay<'a> = std::ffi::os_str::Display<'a>;
|
||||||
|
type PathDisplay<'a> = std::path::Display<'a>;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub struct DelimitedVec<T, const D: char = ' '>(Vec<T>);
|
||||||
|
|
||||||
|
impl<T: OsDisplay, const D: char> OsDisplay for DelimitedVec<T, D> {
|
||||||
|
fn fmt_os(&self, f: &mut osstr_traits::OsStringFormatter) -> std::fmt::Result {
|
||||||
|
let mut first = true;
|
||||||
|
|
||||||
|
for item in &self.0 {
|
||||||
|
if !first {
|
||||||
|
f.write_os_str(&D.to_os_string())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.fmt_os(f)?;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Display, const D: char> Display for DelimitedVec<T, D> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let mut first = true;
|
||||||
|
|
||||||
|
for item in &self.0 {
|
||||||
|
if !first {
|
||||||
|
write!(f, "{D}")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
write!(f, "{item}")?;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, const D: char> FromIterator<A> for DelimitedVec<A, D> {
|
||||||
|
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
|
||||||
|
Self(iter.into_iter().collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, const D: char> From<&'a Vec<PathBuf>> for DelimitedVec<PathDisplay<'a>, D> {
|
||||||
|
fn from(value: &'a Vec<PathBuf>) -> Self {
|
||||||
|
let iter = value.iter().map(|s| s.display());
|
||||||
|
Self::from_iter(iter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, const D: char> From<&'a Vec<OsString>> for DelimitedVec<OsStrDisplay<'a>, D> {
|
||||||
|
fn from(value: &'a Vec<OsString>) -> Self {
|
||||||
|
let iter = value.iter().map(|s| s.display());
|
||||||
|
Self::from_iter(iter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub struct CommandArgs<T>(pub Vec<T>);
|
||||||
|
|
||||||
|
impl<T: OsDisplay> OsDisplay for CommandArgs<T> {
|
||||||
|
fn fmt_os(&self, f: &mut osstr_traits::OsStringFormatter) -> std::fmt::Result {
|
||||||
|
let mut first = true;
|
||||||
|
|
||||||
|
for item in &self.0 {
|
||||||
|
if !first {
|
||||||
|
f.write_os_str(OsStr::new(" "))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.fmt_os(f)?;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Display> Display for CommandArgs<T> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let mut first = true;
|
||||||
|
|
||||||
|
for item in &self.0 {
|
||||||
|
if !first {
|
||||||
|
write!(f, " ")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
write!(f, "{item}")?;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Default for CommandArgs<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(Vec::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Deref for CommandArgs<T> {
|
||||||
|
type Target = Vec<T>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> DerefMut for CommandArgs<T> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A> FromIterator<A> for CommandArgs<A> {
|
||||||
|
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
|
||||||
|
Self(iter.into_iter().collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> IntoIterator for CommandArgs<T> {
|
||||||
|
type Item = T;
|
||||||
|
type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.0.into_iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Display)]
|
||||||
|
#[display("{} {}", command.display(), args)]
|
||||||
|
pub struct Command<'a, T> {
|
||||||
|
command: Cow<'a, OsStr>,
|
||||||
|
args: CommandArgs<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Command<'a, T> {
|
||||||
|
pub fn new(command: impl Into<Cow<'a, OsStr>>) -> Self {
|
||||||
|
Self {
|
||||||
|
command: command.into(),
|
||||||
|
args: CommandArgs::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn arg(&mut self, arg: T) {
|
||||||
|
self.args.push(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: AsRef<OsStr>> Command<'a, T> {
|
||||||
|
pub fn into_os_command(self) -> std::process::Command {
|
||||||
|
let mut cmd = std::process::Command::new(self.command);
|
||||||
|
cmd.args(self.args);
|
||||||
|
cmd
|
||||||
|
}
|
||||||
|
}
|
108
core/src/config.rs
Normal file
108
core/src/config.rs
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
use std::{
|
||||||
|
borrow::Cow,
|
||||||
|
env,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
|
use confique::Config;
|
||||||
|
use directories::ProjectDirs;
|
||||||
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
|
|
||||||
|
use crate::error::{Error, ShellExpansionError};
|
||||||
|
|
||||||
|
trait Fallback: Config {
|
||||||
|
fn fallback() -> <Self as Config>::Partial;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn project_dir() -> Option<ProjectDirs> {
|
||||||
|
ProjectDirs::from("cafe", "kitsu", "TormentNexus")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expand_tilde<'a>(path: impl Into<Cow<'a, Path>>) -> Result<Cow<'a, Path>, ShellExpansionError> {
|
||||||
|
let path = path.into();
|
||||||
|
let into_err = || ShellExpansionError::new("~", path.to_str());
|
||||||
|
|
||||||
|
if !path.starts_with("~") {
|
||||||
|
Ok(path)
|
||||||
|
} else if path == Path::new("~") {
|
||||||
|
env::home_dir().map(Cow::Owned).ok_or_else(into_err)
|
||||||
|
} else {
|
||||||
|
let mut home_dir = env::home_dir().ok_or_else(into_err)?;
|
||||||
|
if home_dir == Path::new("/") {
|
||||||
|
let stripped = path.strip_prefix("~").map_err(|_e| into_err())?;
|
||||||
|
Ok(Cow::Owned(stripped.into()))
|
||||||
|
} else {
|
||||||
|
home_dir.push(path.strip_prefix("~/").map_err(|_e| into_err())?);
|
||||||
|
Ok(Cow::Owned(home_dir))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize_path<'de, D: Deserializer<'de>>(de: D) -> Result<PathBuf, D::Error> {
|
||||||
|
let path = PathBuf::deserialize(de)?;
|
||||||
|
if let Ok(expanded_path) = expand_tilde(&path) {
|
||||||
|
Ok(expanded_path.into())
|
||||||
|
} else {
|
||||||
|
Ok(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Config, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct EditorCfg {
|
||||||
|
#[config(deserialize_with = deserialize_path, env = "EDITOR_PATH")]
|
||||||
|
pub path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Fallback for EditorCfg {
|
||||||
|
fn fallback() -> <Self as Config>::Partial {
|
||||||
|
Self::Partial {
|
||||||
|
path: project_dir().map(|d| d.data_local_dir().join("editors/")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Config, Serialize, Deserialize)]
|
||||||
|
pub struct ProjectCfg {
|
||||||
|
#[config(deserialize_with = deserialize_path, env = "PROJECT_MANIFEST_PATH")]
|
||||||
|
pub manifest_path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Fallback for ProjectCfg {
|
||||||
|
fn fallback() -> <Self as Config>::Partial {
|
||||||
|
Self::Partial {
|
||||||
|
manifest_path: project_dir().map(|d| d.data_local_dir().join("manifest.toml")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Debug, Config, Serialize, Deserialize)]
|
||||||
|
pub struct Cfg {
|
||||||
|
#[config(nested)]
|
||||||
|
pub editor: EditorCfg,
|
||||||
|
|
||||||
|
#[config(nested)]
|
||||||
|
pub project: ProjectCfg,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cfg {
|
||||||
|
pub fn from_env() -> Result<Cfg, Error> {
|
||||||
|
let mut builder = Cfg::builder().env();
|
||||||
|
|
||||||
|
if let Some(dir) = project_dir() {
|
||||||
|
builder = builder.file(dir.config_dir().join("config.toml"));
|
||||||
|
}
|
||||||
|
|
||||||
|
builder
|
||||||
|
.preloaded(Self::fallback())
|
||||||
|
.load()
|
||||||
|
.map_err(Into::into)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Fallback for Cfg {
|
||||||
|
fn fallback() -> <Self as Config>::Partial {
|
||||||
|
Self::Partial {
|
||||||
|
editor: EditorCfg::fallback(),
|
||||||
|
project: ProjectCfg::fallback(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
core/src/editor.rs
Normal file
1
core/src/editor.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub struct Editor {}
|
795
core/src/editor_command.rs
Normal file
795
core/src/editor_command.rs
Normal file
|
@ -0,0 +1,795 @@
|
||||||
|
use std::{
|
||||||
|
ffi::OsString,
|
||||||
|
net::IpAddr,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
path::PathBuf,
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
|
use derive_more::Display;
|
||||||
|
use osstr_traits_derive::OsDisplay;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::collection::{CommandArgs, DelimitedVec};
|
||||||
|
|
||||||
|
type OsStrDisplay<'a> = std::ffi::os_str::Display<'a>;
|
||||||
|
type PathDisplay<'a> = std::path::Display<'a>;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Display, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum ConsistencyCheckSourceMode {
|
||||||
|
#[display("local")]
|
||||||
|
Local,
|
||||||
|
#[display("cacheserver")]
|
||||||
|
CacheServer,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Display, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[display("{0} {1}", DelimitedVec::<PathDisplay>::from(exports), path.display())]
|
||||||
|
#[os_display("{exports} {path}", exports = DelimitedVec::<&PathBuf, ' '>::from_iter(exports), path = path)]
|
||||||
|
pub struct ExportPackage {
|
||||||
|
path: PathBuf,
|
||||||
|
exports: Vec<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Display, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum PlatformTextureFormat {
|
||||||
|
#[display("dxt")]
|
||||||
|
Dxt,
|
||||||
|
#[display("pvrtc")]
|
||||||
|
#[deprecated(note = "PVRTC format is deprecated. Use ASTC or ETC format instead.")]
|
||||||
|
Pvrtc,
|
||||||
|
#[display("atc")]
|
||||||
|
Atc,
|
||||||
|
#[display("etc")]
|
||||||
|
Etc,
|
||||||
|
#[display("etc2")]
|
||||||
|
Etc2,
|
||||||
|
#[display("astc")]
|
||||||
|
Astc,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Default, Display, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum TextureCompression {
|
||||||
|
#[default]
|
||||||
|
NoOverride,
|
||||||
|
ForceUncompressed,
|
||||||
|
ForceFastCompressor,
|
||||||
|
ForceNoCrunchCompression,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Display, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum SharedLogLevel {
|
||||||
|
#[display("debug")]
|
||||||
|
Debug,
|
||||||
|
#[display("info")]
|
||||||
|
Info,
|
||||||
|
#[display("notice")]
|
||||||
|
Notice,
|
||||||
|
#[display("fatal")]
|
||||||
|
Fatal,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Display, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[display("-{_variant}")]
|
||||||
|
pub enum PerforceArgument {
|
||||||
|
#[display("vcPerforceHost {0}", _0.display())]
|
||||||
|
#[os_display("vcPerforceHost {_0}")]
|
||||||
|
Host(OsString),
|
||||||
|
#[display("vcSharedLogLevel {_0}")]
|
||||||
|
#[os_display("vcSharedLogLevel {_0}")]
|
||||||
|
SharedLogLevel(SharedLogLevel),
|
||||||
|
#[display("vcPerforceServer {0}", _0.display())]
|
||||||
|
#[os_display("vcPerforceServer {_0}")]
|
||||||
|
Server(OsString),
|
||||||
|
#[display("vcPerforceWorkspace {0}", _0.display())]
|
||||||
|
#[os_display("vcPerforceWorkspace {_0}")]
|
||||||
|
Workspace(OsString),
|
||||||
|
#[display("vcPerforceUsername {0}", _0.display())]
|
||||||
|
#[os_display("vcPerforceUsername {_0}")]
|
||||||
|
Username(OsString),
|
||||||
|
#[display("vcPerforcePassword {0}", _0.display())]
|
||||||
|
#[os_display("vcPerforcePassword {_0}")]
|
||||||
|
Password(OsString),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Display, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum VcsMode {
|
||||||
|
#[display("\"Visible Meta Files\"")]
|
||||||
|
VisibleMetaFiles,
|
||||||
|
#[display("\"Hidden Meta Files\"")]
|
||||||
|
HiddenMetaFiles,
|
||||||
|
#[display("Perforce {_0}")]
|
||||||
|
#[os_display("Perforce {_0}")]
|
||||||
|
Perforce(CommandArgs<PerforceArgument>),
|
||||||
|
#[display("PlasticSCM")]
|
||||||
|
PlasticScm,
|
||||||
|
#[display("{0}", _0.display())]
|
||||||
|
#[os_display("{_0}")]
|
||||||
|
Other(OsString),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Display, Clone, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[display("-{_variant}")]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum ConfigurationArgument {
|
||||||
|
#[display("createProject \"{0}\"", _0.display())]
|
||||||
|
#[os_display("-createProject \"{_0}\"")]
|
||||||
|
CreateProject(PathBuf),
|
||||||
|
#[display("consistencyCheck")]
|
||||||
|
ConsistencyCheck,
|
||||||
|
#[display("consistencyCheckSourceMode {_0}")]
|
||||||
|
ConsistencyCheckSourceMode(ConsistencyCheckSourceMode),
|
||||||
|
#[display("disable-assembly-updater {0}", DelimitedVec::<PathDisplay, ' '>::from(_0))]
|
||||||
|
#[os_display("-disable-assembly-updater {}", DelimitedVec::<&PathBuf, ' '>::from_iter(_0))]
|
||||||
|
DisableAssemblyUpdater(Vec<PathBuf>),
|
||||||
|
#[display("disable-gpu-skinning")]
|
||||||
|
DisableGpuSkinning,
|
||||||
|
#[display("disable-playback-engines {0}", DelimitedVec::<OsStrDisplay, ' '>::from(_0))]
|
||||||
|
#[os_display("-disable-playback-engines {}", DelimitedVec::<&std::ffi::OsString, ' '>::from_iter(_0))]
|
||||||
|
DisablePlaybackEngines(Vec<OsString>),
|
||||||
|
#[display("executeMethod {0}", _0.display())]
|
||||||
|
#[os_display("-executeMethod {_0}")]
|
||||||
|
ExecMethod(OsString),
|
||||||
|
#[display("exportPackage {_0}")]
|
||||||
|
#[os_display("-exportPackage {_0}")]
|
||||||
|
ExportPackage(ExportPackage),
|
||||||
|
#[display("importPackage {0}", _0.display())]
|
||||||
|
#[os_display("-importPackage {_0}")]
|
||||||
|
ImportPackage(PathBuf),
|
||||||
|
#[display("job-worker-count {_0}")]
|
||||||
|
JobWorkerCount(usize),
|
||||||
|
#[display("gc-helper-count {_0}")]
|
||||||
|
GcHelperCount(usize),
|
||||||
|
#[display("logFile {0}", _0.display())]
|
||||||
|
#[os_display("-logFile {_0}")]
|
||||||
|
LogFile(PathBuf),
|
||||||
|
#[display("noUpm")]
|
||||||
|
NoUpm,
|
||||||
|
#[display("openfile {0}", _0.display())]
|
||||||
|
#[os_display("-openfile {_0}")]
|
||||||
|
OpenFile(PathBuf),
|
||||||
|
#[display("password {0}", _0.display())]
|
||||||
|
#[os_display("-password {_0}")]
|
||||||
|
Password(OsString),
|
||||||
|
#[display("projectPath {0}", _0.display())]
|
||||||
|
#[os_display("-projectPath {_0}")]
|
||||||
|
ProjectPath(PathBuf),
|
||||||
|
#[display("quit")]
|
||||||
|
Quit,
|
||||||
|
#[display("releaseCodeOptimization")]
|
||||||
|
ReleaseCodeOptimization,
|
||||||
|
#[display("setDefaultPlatformTextureFormat {_0}")]
|
||||||
|
SetDefaultPlatformTextureFormat(PlatformTextureFormat),
|
||||||
|
#[display("overrideMaxTextureSize {_0}")]
|
||||||
|
OverrideMaxTextureSize(usize),
|
||||||
|
#[display("overrideTextureCompression {_0}")]
|
||||||
|
OverrideTextureCompression(TextureCompression),
|
||||||
|
#[display("silent-crashes")]
|
||||||
|
SilentCrashes,
|
||||||
|
#[display("upmLogFile {0}", _0.display())]
|
||||||
|
#[os_display("-upmLogFile {_0}")]
|
||||||
|
UpmLogFile(PathBuf),
|
||||||
|
#[display("username {0}", _0.display())]
|
||||||
|
#[os_display("-username {_0}")]
|
||||||
|
Username(OsString),
|
||||||
|
#[display("vcsMode {_0}")]
|
||||||
|
VcsMode(VcsMode),
|
||||||
|
#[display("version")]
|
||||||
|
Version,
|
||||||
|
#[display("timestamps")]
|
||||||
|
Timestamps,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Display, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[display("-{_variant}")]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum BatchModeArgument {
|
||||||
|
#[display("accent-apiupdate")]
|
||||||
|
AcceptApiUpdate,
|
||||||
|
#[display("batchmode")]
|
||||||
|
BatchMode,
|
||||||
|
#[display("ignorecompilererrors")]
|
||||||
|
IgnoreCompilerErrors,
|
||||||
|
#[display("nographics")]
|
||||||
|
NoGraphics,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Display, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum BuildTarget {
|
||||||
|
#[display("win64")]
|
||||||
|
Win64,
|
||||||
|
#[display("win")]
|
||||||
|
Win,
|
||||||
|
#[display("osxuniversal")]
|
||||||
|
OsxUniversal,
|
||||||
|
#[display("linux64")]
|
||||||
|
Linux64,
|
||||||
|
#[display("android")]
|
||||||
|
Android,
|
||||||
|
#[display("ios")]
|
||||||
|
IOs,
|
||||||
|
#[display("webgl")]
|
||||||
|
WebGl,
|
||||||
|
#[display("tvos")]
|
||||||
|
TvOs,
|
||||||
|
#[display("windowsstoreapps")]
|
||||||
|
WindowsStoreApps,
|
||||||
|
#[display("cloudrendering")]
|
||||||
|
CloudRendering,
|
||||||
|
#[display("visionos")]
|
||||||
|
VisionOs,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Display, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum BuildSubtarget {
|
||||||
|
Player,
|
||||||
|
Server,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Display, Clone, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[display("-{_variant}")]
|
||||||
|
pub enum BuildArgument {
|
||||||
|
#[display("activeBuildProfile \"{0}\"", _0.display())]
|
||||||
|
#[os_display("activeBuildProfile \"{_0}\"")]
|
||||||
|
ActiveBuildProfile(PathBuf),
|
||||||
|
#[display("build \"{0}\"", _0.display())]
|
||||||
|
#[os_display("build \"{_0}\"")]
|
||||||
|
Build(PathBuf),
|
||||||
|
#[display("buildLinux64Player \"{0}\"", _0.display())]
|
||||||
|
#[os_display("buildLinux64Player \"{_0}\"")]
|
||||||
|
BuildLinux64Player(PathBuf),
|
||||||
|
#[display("buildLinuxHeadlessSimulation \"{0}\"", _0.display())]
|
||||||
|
#[os_display("buildLinuxHeadlessSimulation \"{_0}\"")]
|
||||||
|
BuildLinuxHeadlessSimulation(PathBuf),
|
||||||
|
#[display("buildOSXUniversalPlayer \"{0}\"", _0.display())]
|
||||||
|
#[os_display("buildOSXUniversalPlayer \"{_0}\"")]
|
||||||
|
BuildOsxUniversalPlayer(PathBuf),
|
||||||
|
#[display("buildTarget \"{_0}\"")]
|
||||||
|
BuildTarget(BuildTarget),
|
||||||
|
#[display("standaloneBuildSubtarget \"{_0}\"")]
|
||||||
|
#[os_display("standaloneBuildSubtarget \"{_0}\"")]
|
||||||
|
StandaloneBuildSubtarget(BuildSubtarget),
|
||||||
|
#[display("buildWindowsPlayer \"{0}\"", _0.display())]
|
||||||
|
#[os_display("buildWindowsPlayer \"{_0}\"")]
|
||||||
|
BuildWindowsPlayer(PathBuf),
|
||||||
|
#[display("buildWindows64Player \"{0}\"", _0.display())]
|
||||||
|
#[os_display("buildWindows64Player \"{_0}\"")]
|
||||||
|
BuildWindows64Player(PathBuf),
|
||||||
|
}
|
||||||
|
#[derive(Debug, Display, Clone, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[display("-{_variant}")]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum CacheServerArgument {
|
||||||
|
#[display("EnableCacheServer")]
|
||||||
|
Enable,
|
||||||
|
#[display("cacheServerEndpoint {_0}:{_1}")]
|
||||||
|
Endpoint(IpAddr, u16),
|
||||||
|
#[display("cacheServerNamespacePrefix \"{0}\"", _0.display())]
|
||||||
|
#[os_display("cacheServerNamespacePrefix \"{_0}\"")]
|
||||||
|
NamespacePrefix(OsString),
|
||||||
|
#[display("cacheServerEnableDownload {_0}")]
|
||||||
|
EnableDownload(bool),
|
||||||
|
#[display("cacheServerEnableUpload {_0}")]
|
||||||
|
EnableUpload(bool),
|
||||||
|
#[display("cacheServerWaitForConnection {0}", _0.as_millis())]
|
||||||
|
WaitForConnection(Duration),
|
||||||
|
#[display("cacheServerWaitForUploadCompletion")]
|
||||||
|
WaitForUploadCompletion,
|
||||||
|
#[display("cacheServerDownloadBatchSize {_0}")]
|
||||||
|
DownloadBatchSize(usize),
|
||||||
|
#[display("cacheServerUploadAllRevisions")]
|
||||||
|
UploadAllRevisions,
|
||||||
|
#[display("cacheServerUploadExistingShaderCache")]
|
||||||
|
UploadExistingShaderCache,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum StackTraceLogType {
|
||||||
|
None,
|
||||||
|
#[display("\"Script Only\"")]
|
||||||
|
ScriptOnly,
|
||||||
|
#[default]
|
||||||
|
Full,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[display("-{_variant}")]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum DebugArgument {
|
||||||
|
#[display("disableManagedDebugger")]
|
||||||
|
DisableManagedDebugger,
|
||||||
|
#[display("diag-debug-shader-compiler")]
|
||||||
|
DiagDebugShaderCompiler,
|
||||||
|
#[display("debugCodeOptimization")]
|
||||||
|
DebugCodeOptimization,
|
||||||
|
#[display("enableCodeCoverage")]
|
||||||
|
EnableCodeCoverage,
|
||||||
|
#[display("force-d3d12-debug")]
|
||||||
|
ForceD3d12Debug,
|
||||||
|
#[display("force-d3d12-debug-gbv")]
|
||||||
|
ForceD3d12DebugGbv,
|
||||||
|
#[display("force-vulkan-layers")]
|
||||||
|
ForceVulkanLayers,
|
||||||
|
#[display("StackTraceLogType {_0}")]
|
||||||
|
#[os_display("StackTraceLogType {_0}")]
|
||||||
|
StackTraceLogType(StackTraceLogType),
|
||||||
|
#[display("log-memory-performance-stats")]
|
||||||
|
LogMemoryPerformanceStats,
|
||||||
|
#[display("wait-for-managed-debugger")]
|
||||||
|
WaitForManagedDebugger,
|
||||||
|
#[display("wait-for-native-debugger")]
|
||||||
|
WaitForNativeDebugger,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Display, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[display("-{_variant}")]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum GraphicsApiArgument {
|
||||||
|
#[display("force-clamped")]
|
||||||
|
ForceClamped,
|
||||||
|
#[display("force-d3d11")]
|
||||||
|
ForceD3d11,
|
||||||
|
#[display("force-d3d12")]
|
||||||
|
ForceD3d12,
|
||||||
|
#[display("force-device-index")]
|
||||||
|
ForceDeviceIndex,
|
||||||
|
#[display("force-glcore")]
|
||||||
|
ForceGlCore,
|
||||||
|
#[display("force-glcoreXY")]
|
||||||
|
ForceGlCoreXy,
|
||||||
|
#[display("force-gles")]
|
||||||
|
ForceGlEs,
|
||||||
|
#[display("force-glesXY")]
|
||||||
|
ForceGlEsXy,
|
||||||
|
#[display("force-opengl")]
|
||||||
|
ForceOpenGl,
|
||||||
|
#[display("force-vulkan")]
|
||||||
|
ForceVulkan,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Display, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[display("-{_variant}")]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum LicenseArgument {
|
||||||
|
#[display("createManualActivationFile")]
|
||||||
|
CreateManualActivationFile,
|
||||||
|
#[display("manualLicenseFile {0}", _0.display())]
|
||||||
|
#[os_display("manualLicenseFile {_0}")]
|
||||||
|
ManualLicenseFile(PathBuf),
|
||||||
|
#[display("returnlicense")]
|
||||||
|
ReturnLicense,
|
||||||
|
#[display("serial {0}", _0.display())]
|
||||||
|
#[os_display("serial {_0}")]
|
||||||
|
Serial(OsString),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Display, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[display("-{_variant}")]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum MetalArgument {
|
||||||
|
#[display("force-low-power-device")]
|
||||||
|
ForceLowPowerDevice,
|
||||||
|
#[display("force-metal")]
|
||||||
|
ForceMetal,
|
||||||
|
#[display("enable-metal-capture")]
|
||||||
|
EnableMetalCapture,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Display, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[display("-{_variant}")]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum ProfilerArgument {
|
||||||
|
#[display("deepprofiling")]
|
||||||
|
DeepProfiling,
|
||||||
|
#[display("profiler-enable")]
|
||||||
|
Enable,
|
||||||
|
#[display("profiler-log-file {0}", _0.display())]
|
||||||
|
#[os_display("profiler-log-file {_0}")]
|
||||||
|
LogFile(PathBuf),
|
||||||
|
#[display("profiler-capture-frame-count {_0}")]
|
||||||
|
CaptureFrameCount(usize),
|
||||||
|
#[display("profiler-maxusedmemory {_0}")]
|
||||||
|
MaxUsedMemory(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Display, PartialEq, Eq, PartialOrd, Ord, OsDisplay)]
|
||||||
|
#[display("-{_variant}")]
|
||||||
|
#[os_display(from_display)]
|
||||||
|
pub enum EditorSpecialArgument {
|
||||||
|
#[display("enableIncompatibleAssetDowngrade")]
|
||||||
|
EnableIncompatibleAssetDowngrade,
|
||||||
|
#[display("giCustomCacheLocation {0}", _0.display())]
|
||||||
|
#[os_display("giCustomCacheLocation {_0}")]
|
||||||
|
GiCustomCacheLocation(PathBuf),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub enum UnityArgument {
|
||||||
|
Configuration(ConfigurationArgument),
|
||||||
|
BatchMode(BatchModeArgument),
|
||||||
|
Build(BuildArgument),
|
||||||
|
CacheServer(CacheServerArgument),
|
||||||
|
Debug(DebugArgument),
|
||||||
|
GraphicsApi(GraphicsApiArgument),
|
||||||
|
License(LicenseArgument),
|
||||||
|
Metal(MetalArgument),
|
||||||
|
Profiler(ProfilerArgument),
|
||||||
|
Editor(EditorSpecialArgument),
|
||||||
|
Extra(OsString),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub struct UnityArguments(Vec<UnityArgument>);
|
||||||
|
|
||||||
|
impl Deref for UnityArguments {
|
||||||
|
type Target = Vec<UnityArgument>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for UnityArguments {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for UnityArguments {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(Vec::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! unity_args {
|
||||||
|
() => {
|
||||||
|
UnityArguments::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
($arg:expr $(, $rest:expr)* $(,)?) => {
|
||||||
|
{
|
||||||
|
let mut args = Vec::new();
|
||||||
|
$(
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
match $rest {
|
||||||
|
arg @ ConfigArguments::CreateProject(_) |
|
||||||
|
arg @ ConfigArguments::ConsistencyCheck |
|
||||||
|
arg @ ConfigArguments::ConsistencyCheckSourceMode(_) |
|
||||||
|
arg @ ConfigArguments::DisableAssemblyUpdater(_) |
|
||||||
|
arg @ ConfigArguments::DisableGpuSkinning |
|
||||||
|
arg @ ConfigArguments::DisablePlaybackEngines(_) |
|
||||||
|
arg @ ConfigArguments::ExecMethod(_) |
|
||||||
|
arg @ ConfigArguments::ExportPackage(_) |
|
||||||
|
arg @ ConfigArguments::ImportPackage(_) |
|
||||||
|
arg @ ConfigArguments::JobWorkerCount(_) |
|
||||||
|
arg @ ConfigArguments::GcHelperCount(_) |
|
||||||
|
arg @ ConfigArguments::LogFile(_) |
|
||||||
|
arg @ ConfigArguments::NoUpm |
|
||||||
|
arg @ ConfigArguments::OpenFile(_) |
|
||||||
|
arg @ ConfigArguments::Password(_) |
|
||||||
|
arg @ ConfigArguments::ProjectPath(_) |
|
||||||
|
arg @ ConfigArguments::Quit |
|
||||||
|
arg @ ConfigArguments::ReleaseCodeOptimization |
|
||||||
|
arg @ ConfigArguments::SetDefaultPlatformTextureFormat |
|
||||||
|
arg @ ConfigArguments::OverrideMaxTextureSize(_) |
|
||||||
|
arg @ ConfigArguments::OverrideTextureCompression(_) |
|
||||||
|
arg @ ConfigArguments::SilentCrashes |
|
||||||
|
arg @ ConfigArguments::UpmLogFile(_) |
|
||||||
|
arg @ ConfigArguments::Username(_) |
|
||||||
|
arg @ ConfigArguments::VcsMode |
|
||||||
|
arg @ ConfigArguments::Version |
|
||||||
|
arg @ ConfigArguments::Timestamps => {
|
||||||
|
args.push(UnityArgument::Configuration(arg));
|
||||||
|
},
|
||||||
|
|
||||||
|
arg @ BatchModeArguments::AcceptApiUpdate |
|
||||||
|
arg @ BatchModeArguments::BatchMode |
|
||||||
|
arg @ BatchModeArguments::IgnoreCompileErrors |
|
||||||
|
arg @ BatchModeArguments::NoGraphics => {
|
||||||
|
args.push(UnityArgument::BatchMode(arg));
|
||||||
|
},
|
||||||
|
|
||||||
|
arg @ BuildArguments::ActiveBuildProfile(_) |
|
||||||
|
arg @ BuildArguments::Build(_) |
|
||||||
|
arg @ BuildArguments::BuildLinux64Player(_) |
|
||||||
|
arg @ BuildArguments::BuildLinuxHeadlessSimulation(_) |
|
||||||
|
arg @ BuildArguments::BuildOSXUniversalPlayer(_) |
|
||||||
|
arg @ BuildArguments::BuildTarget(_) |
|
||||||
|
arg @ BuildArguments::StandaloneBuildSubtarget(_) |
|
||||||
|
arg @ BuildArguments::BuildWindowsPlayer(_) |
|
||||||
|
arg @ BuildArguments::BuildWindows64Player(_) => {
|
||||||
|
args.push(UnityArgument::Build(arg));
|
||||||
|
},
|
||||||
|
|
||||||
|
arg @ CacheServerArguments::Enable |
|
||||||
|
arg @ CacheServerArguments::Endpoint(_, _) |
|
||||||
|
arg @ CacheServerArguments::NamespacePrefix(_) |
|
||||||
|
arg @ CacheServerArguments::EnableDownload(_) |
|
||||||
|
arg @ CacheServerArguments::EnableUpload(_) |
|
||||||
|
arg @ CacheServerArguments::WaitForConnection(_) |
|
||||||
|
arg @ CacheServerArguments::WaitForUploadCompletion |
|
||||||
|
arg @ CacheServerArguments::DownloadBatchSize(_) |
|
||||||
|
arg @ CacheServerArguments::UploadAllRevisions |
|
||||||
|
arg @ CacheServerArguments::UploadExistingShaderCache => {
|
||||||
|
args.push(UnityArgument::CacheServer(arg));
|
||||||
|
},
|
||||||
|
|
||||||
|
arg @ DebugArguments::DisableManagedDebugger |
|
||||||
|
arg @ DebugArguments::DiagDebugShaderCompiler |
|
||||||
|
arg @ DebugArguments::DebugCodeOptimization |
|
||||||
|
arg @ DebugArguments::EnableCodeCoverage |
|
||||||
|
arg @ DebugArguments::ForceD3d12Debug |
|
||||||
|
arg @ DebugArguments::ForceD3d12DebugGbv |
|
||||||
|
arg @ DebugArguments::ForceVulkanLayers |
|
||||||
|
arg @ DebugArguments::StackTraceLogType(_) |
|
||||||
|
arg @ DebugArguments::LogMemoryPerformanceStats |
|
||||||
|
arg @ DebugArguments::WaitForManagedDebugger |
|
||||||
|
arg @ DebugArguments::WaitForNativeDebugger => {
|
||||||
|
args.push(UnityArgument::Debug(arg));
|
||||||
|
},
|
||||||
|
|
||||||
|
arg @ GraphicsApiArguments::ForceClamped |
|
||||||
|
arg @ GraphicsApiArguments::ForceD3d11 |
|
||||||
|
arg @ GraphicsApiArguments::ForceD3d12 |
|
||||||
|
arg @ GraphicsApiArguments::ForceDeviceIndex |
|
||||||
|
arg @ GraphicsApiArguments::ForceGlCore |
|
||||||
|
arg @ GraphicsApiArguments::ForceGlCoreXy |
|
||||||
|
arg @ GraphicsApiArguments::ForceGlEs |
|
||||||
|
arg @ GraphicsApiArguments::ForceGlEsXy |
|
||||||
|
arg @ GraphicsApiArguments::ForceOpenGl |
|
||||||
|
arg @ GraphicsApiArguments::ForceVulkan => {
|
||||||
|
args.push(UnityArgument::GraphicsApi(arg));
|
||||||
|
},
|
||||||
|
|
||||||
|
arg @ LicenseArguments::CreateManualActivationFile |
|
||||||
|
arg @ LicenseArguments::ManualLicenseFile(_) |
|
||||||
|
arg @ LicenseArguments::ReturnLicense |
|
||||||
|
arg @ LicenseArguments::Serial(_) => {
|
||||||
|
args.push(UnityArgument::License(arg));
|
||||||
|
},
|
||||||
|
|
||||||
|
arg @ MetalArguments::ForceLowPowerDevice |
|
||||||
|
arg @ MetalArguments::ForceMetal |
|
||||||
|
arg @ MetalArguments::EnableMetalCapture => {
|
||||||
|
args.push(UnityArgument::Metal(arg));
|
||||||
|
},
|
||||||
|
|
||||||
|
arg @ ProfilerArguments::DeepProfiling |
|
||||||
|
arg @ ProfilerArguments::Enable |
|
||||||
|
arg @ ProfilerArguments::LogFile(_) |
|
||||||
|
arg @ ProfilerArguments::CaptureFrameCount(_) |
|
||||||
|
arg @ ProfilerArguments::MaxUsedMemory(_) => {
|
||||||
|
args.push(UnityArgument::Profiler(arg));
|
||||||
|
},
|
||||||
|
|
||||||
|
arg @ EditorSpecialArguments::EnableIncompatibleAssetDowngrade |
|
||||||
|
arg @ EditorSpecialArguments::GiCustomCacheLocation(_) => {
|
||||||
|
args.push(UnityArgument::Editor(arg));
|
||||||
|
},
|
||||||
|
|
||||||
|
arg @ UnityArgument::Configuration(_) |
|
||||||
|
arg @ UnityArgument::BatchMode(_) |
|
||||||
|
arg @ UnityArgument::Build(_) |
|
||||||
|
arg @ UnityArgument::CacheServer(_) |
|
||||||
|
arg @ UnityArgument::Debug(_) |
|
||||||
|
arg @ UnityArgument::GraphicsApi(_) |
|
||||||
|
arg @ UnityArgument::License(_) |
|
||||||
|
arg @ UnityArgument::Metal(_) |
|
||||||
|
arg @ UnityArgument::Profiler(_) |
|
||||||
|
arg @ UnityArgument::Editor(_) |
|
||||||
|
arg @ UnityArgument::Extra(_) => {
|
||||||
|
args.push(arg);
|
||||||
|
},
|
||||||
|
|
||||||
|
s: OsString => {
|
||||||
|
args.push(UnityArgument::Extra(s));
|
||||||
|
},
|
||||||
|
|
||||||
|
_ => compile_error!("Unsupported argument type in unity_args! macro. Ensure it's a valid argument enum variant or a String."),
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
|
||||||
|
UnityArguments(args)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct EditorCommand {}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::{ffi::OsString, path::PathBuf};
|
||||||
|
|
||||||
|
use osstr_traits::ToOsString;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
collection::CommandArgs,
|
||||||
|
editor_command::{
|
||||||
|
ConfigurationArgument, ExportPackage, PerforceArgument, PlatformTextureFormat,
|
||||||
|
SharedLogLevel, TextureCompression, VcsMode,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn config_args() {
|
||||||
|
let arg = ConfigurationArgument::CreateProject(PathBuf::from("./test-project"));
|
||||||
|
assert_eq!(arg.to_os_string(), "-createProject \"./test-project\"");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::ConsistencyCheck;
|
||||||
|
assert_eq!(arg.to_os_string(), "-consistencyCheck");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::ConsistencyCheckSourceMode(
|
||||||
|
super::ConsistencyCheckSourceMode::Local,
|
||||||
|
);
|
||||||
|
assert_eq!(arg.to_os_string(), "-consistencyCheckSourceMode local");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::ConsistencyCheckSourceMode(
|
||||||
|
super::ConsistencyCheckSourceMode::CacheServer,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
arg.to_os_string(),
|
||||||
|
"-consistencyCheckSourceMode cacheserver"
|
||||||
|
);
|
||||||
|
|
||||||
|
let arg =
|
||||||
|
ConfigurationArgument::DisableAssemblyUpdater(vec!["a.dll".into(), "b.dll".into()]);
|
||||||
|
assert_eq!(arg.to_os_string(), "-disable-assembly-updater a.dll b.dll");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::DisableGpuSkinning;
|
||||||
|
assert_eq!(arg.to_os_string(), "-disable-gpu-skinning");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::DisablePlaybackEngines(vec![
|
||||||
|
"AndroidPlayer".into(),
|
||||||
|
"iOSSupport".into(),
|
||||||
|
]);
|
||||||
|
assert_eq!(
|
||||||
|
arg.to_os_string(),
|
||||||
|
"-disable-playback-engines AndroidPlayer iOSSupport"
|
||||||
|
);
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::ExecMethod("NamespaceName.ClassName.MethodName".into());
|
||||||
|
assert_eq!(
|
||||||
|
arg.to_os_string(),
|
||||||
|
"-executeMethod NamespaceName.ClassName.MethodName"
|
||||||
|
);
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::ExportPackage(ExportPackage {
|
||||||
|
path: "export.unitypackage".into(),
|
||||||
|
exports: vec!["Assets/a.asset".into(), "Assets/b.asset".into()],
|
||||||
|
});
|
||||||
|
assert_eq!(
|
||||||
|
arg.to_os_string(),
|
||||||
|
"-exportPackage Assets/a.asset Assets/b.asset export.unitypackage"
|
||||||
|
);
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::ImportPackage(PathBuf::from("./package.unitypackage"));
|
||||||
|
assert_eq!(arg.to_os_string(), "-importPackage ./package.unitypackage");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::JobWorkerCount(8usize);
|
||||||
|
assert_eq!(arg.to_os_string(), "-job-worker-count 8");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::GcHelperCount(12usize);
|
||||||
|
assert_eq!(arg.to_os_string(), "-gc-helper-count 12");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::LogFile(PathBuf::from("/var/log/unity/editor.log"));
|
||||||
|
assert_eq!(arg.to_os_string(), "-logFile /var/log/unity/editor.log");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::NoUpm;
|
||||||
|
assert_eq!(arg.to_os_string(), "-noUpm");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::OpenFile(PathBuf::from("./scene.unity"));
|
||||||
|
assert_eq!(arg.to_os_string(), "-openfile ./scene.unity");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::Password(OsString::from("hunter12"));
|
||||||
|
assert_eq!(arg.to_os_string(), "-password hunter12");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::ProjectPath(PathBuf::from("./my-project/"));
|
||||||
|
assert_eq!(arg.to_os_string(), "-projectPath ./my-project/");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::Quit;
|
||||||
|
assert_eq!(arg.to_os_string(), "-quit");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::ReleaseCodeOptimization;
|
||||||
|
assert_eq!(arg.to_os_string(), "-releaseCodeOptimization");
|
||||||
|
|
||||||
|
let arg =
|
||||||
|
ConfigurationArgument::SetDefaultPlatformTextureFormat(PlatformTextureFormat::Dxt);
|
||||||
|
assert_eq!(arg.to_os_string(), "-setDefaultPlatformTextureFormat dxt");
|
||||||
|
|
||||||
|
let arg =
|
||||||
|
ConfigurationArgument::SetDefaultPlatformTextureFormat(PlatformTextureFormat::Atc);
|
||||||
|
assert_eq!(arg.to_os_string(), "-setDefaultPlatformTextureFormat atc");
|
||||||
|
|
||||||
|
let arg =
|
||||||
|
ConfigurationArgument::SetDefaultPlatformTextureFormat(PlatformTextureFormat::Etc);
|
||||||
|
assert_eq!(arg.to_os_string(), "-setDefaultPlatformTextureFormat etc");
|
||||||
|
|
||||||
|
let arg =
|
||||||
|
ConfigurationArgument::SetDefaultPlatformTextureFormat(PlatformTextureFormat::Etc2);
|
||||||
|
assert_eq!(arg.to_os_string(), "-setDefaultPlatformTextureFormat etc2");
|
||||||
|
|
||||||
|
let arg =
|
||||||
|
ConfigurationArgument::SetDefaultPlatformTextureFormat(PlatformTextureFormat::Pvrtc);
|
||||||
|
assert_eq!(arg.to_os_string(), "-setDefaultPlatformTextureFormat pvrtc");
|
||||||
|
|
||||||
|
let arg =
|
||||||
|
ConfigurationArgument::SetDefaultPlatformTextureFormat(PlatformTextureFormat::Astc);
|
||||||
|
assert_eq!(arg.to_os_string(), "-setDefaultPlatformTextureFormat astc");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::OverrideMaxTextureSize(256usize);
|
||||||
|
assert_eq!(arg.to_os_string(), "-overrideMaxTextureSize 256");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::OverrideTextureCompression(TextureCompression::NoOverride);
|
||||||
|
assert_eq!(arg.to_os_string(), "-overrideTextureCompression NoOverride");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::OverrideTextureCompression(
|
||||||
|
TextureCompression::ForceUncompressed,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
arg.to_os_string(),
|
||||||
|
"-overrideTextureCompression ForceUncompressed"
|
||||||
|
);
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::OverrideTextureCompression(
|
||||||
|
TextureCompression::ForceFastCompressor,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
arg.to_os_string(),
|
||||||
|
"-overrideTextureCompression ForceFastCompressor"
|
||||||
|
);
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::OverrideTextureCompression(
|
||||||
|
TextureCompression::ForceNoCrunchCompression,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
arg.to_os_string(),
|
||||||
|
"-overrideTextureCompression ForceNoCrunchCompression"
|
||||||
|
);
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::SilentCrashes;
|
||||||
|
assert_eq!(arg.to_os_string(), "-silent-crashes");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::UpmLogFile(PathBuf::from("/var/log/unity/upm.log"));
|
||||||
|
assert_eq!(arg.to_os_string(), "-upmLogFile /var/log/unity/upm.log");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::Username(OsString::from("kitsucafe"));
|
||||||
|
assert_eq!(arg.to_os_string(), "-username kitsucafe");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::VcsMode(VcsMode::VisibleMetaFiles);
|
||||||
|
assert_eq!(arg.to_os_string(), "-vcsMode \"Visible Meta Files\"");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::VcsMode(VcsMode::HiddenMetaFiles);
|
||||||
|
assert_eq!(arg.to_os_string(), "-vcsMode \"Hidden Meta Files\"");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::VcsMode(VcsMode::PlasticScm);
|
||||||
|
assert_eq!(arg.to_os_string(), "-vcsMode PlasticSCM");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::VcsMode(VcsMode::Perforce(CommandArgs(vec![
|
||||||
|
PerforceArgument::Workspace("TestWorkspace".into()),
|
||||||
|
PerforceArgument::Host("Hostname".into()),
|
||||||
|
PerforceArgument::Server("8.8.8.8".into()),
|
||||||
|
PerforceArgument::SharedLogLevel(SharedLogLevel::Info),
|
||||||
|
PerforceArgument::Username("kitsucafe".into()),
|
||||||
|
PerforceArgument::Password("hunter12".into()),
|
||||||
|
])));
|
||||||
|
assert_eq!(
|
||||||
|
arg.to_os_string(),
|
||||||
|
"-vcsMode Perforce -vcPerforceWorkspace TestWorkspace -vcPerforceHost Hostname -vcPerforceServer 8.8.8.8 -vcSharedLogLevel info -vcPerforceUsername kitsucafe -vcPerforcePassword hunter12"
|
||||||
|
);
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::Version;
|
||||||
|
assert_eq!(arg.to_os_string(), "-version");
|
||||||
|
|
||||||
|
let arg = ConfigurationArgument::Timestamps;
|
||||||
|
assert_eq!(arg.to_os_string(), "-timestamps");
|
||||||
|
}
|
||||||
|
}
|
113
core/src/error.rs
Normal file
113
core/src/error.rs
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
use std::{error::Error as StdError, fmt::Display, path::PathBuf};
|
||||||
|
use toml::de::Error as TomlError;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ShellExpansionError {
|
||||||
|
variable: String,
|
||||||
|
context: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShellExpansionError {
|
||||||
|
pub fn new(variable: &str, context: Option<&str>) -> Self {
|
||||||
|
Self {
|
||||||
|
variable: variable.into(),
|
||||||
|
context: context.map(Into::into),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for ShellExpansionError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
if let Some(context) = &self.context {
|
||||||
|
write!(f, "Error expanding {} in {}", self.variable, context)
|
||||||
|
} else {
|
||||||
|
write!(f, "Error expanding {}", self.variable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct FileError {
|
||||||
|
path: PathBuf,
|
||||||
|
source: Box<dyn StdError>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FileError {
|
||||||
|
pub fn new(path: impl Into<PathBuf>, source: impl Into<Box<dyn StdError>>) -> Self {
|
||||||
|
Self {
|
||||||
|
path: path.into(),
|
||||||
|
source: source.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for FileError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"Error handling \"{}\": {}",
|
||||||
|
self.path.display(),
|
||||||
|
&self.source
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for FileError {}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ProjectManifestError {
|
||||||
|
Read(FileError),
|
||||||
|
Parse(TomlError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<FileError> for ProjectManifestError {
|
||||||
|
fn from(value: FileError) -> Self {
|
||||||
|
Self::Read(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<TomlError> for ProjectManifestError {
|
||||||
|
fn from(value: TomlError) -> Self {
|
||||||
|
Self::Parse(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for ProjectManifestError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Read(error) => write!(f, "Error reading project manifest: {error}"),
|
||||||
|
Self::Parse(error) => write!(f, "Error parsing project manifest: {error}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for ProjectManifestError {}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
LoadConfig(confique::Error),
|
||||||
|
ProjectManifest(ProjectManifestError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<confique::Error> for Error {
|
||||||
|
fn from(value: confique::Error) -> Self {
|
||||||
|
Self::LoadConfig(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ProjectManifestError> for Error {
|
||||||
|
fn from(value: ProjectManifestError) -> Self {
|
||||||
|
Self::ProjectManifest(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Error::LoadConfig(error) => write!(f, "Couldn't load config: {error}"),
|
||||||
|
Error::ProjectManifest(error) => write!(f, "Couldn't read projects: {error}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for Error {}
|
101
core/src/lib.rs
Normal file
101
core/src/lib.rs
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
#![feature(min_specialization)]
|
||||||
|
|
||||||
|
pub mod collection;
|
||||||
|
pub mod config;
|
||||||
|
pub mod editor;
|
||||||
|
pub mod editor_command;
|
||||||
|
pub mod error;
|
||||||
|
pub mod project;
|
||||||
|
|
||||||
|
use std::{fs, ops::Deref, path::Path};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
config::Cfg,
|
||||||
|
editor::Editor,
|
||||||
|
error::{Error, FileError, ProjectManifestError},
|
||||||
|
project::Project,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Projects {
|
||||||
|
projects: Vec<Project>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Projects {
|
||||||
|
pub fn new(projects: Vec<Project>) -> Self {
|
||||||
|
Self { projects }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<Project>> for Projects {
|
||||||
|
fn from(value: Vec<Project>) -> Self {
|
||||||
|
Self::new(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Projects {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new(Vec::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for Projects {
|
||||||
|
type Target = Vec<Project>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.projects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TormentNexus {
|
||||||
|
config: Cfg,
|
||||||
|
projects: Projects,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TormentNexus {
|
||||||
|
pub fn new(config: Cfg, projects: impl Into<Projects>) -> Self {
|
||||||
|
Self {
|
||||||
|
config,
|
||||||
|
projects: projects.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load() -> Result<Self, Error> {
|
||||||
|
let config = Cfg::from_env()?;
|
||||||
|
let projects = Self::read_projects(&config.project.manifest_path)?;
|
||||||
|
|
||||||
|
Ok(Self::new(config, projects))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_projects(
|
||||||
|
manifest_path: impl AsRef<Path>,
|
||||||
|
) -> Result<Projects, ProjectManifestError> {
|
||||||
|
let content = fs::read_to_string(&manifest_path)
|
||||||
|
.map_err(|err| FileError::new(manifest_path.as_ref(), err))?;
|
||||||
|
|
||||||
|
Ok(toml::from_str::<Projects>(&content)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn installed_editors(&self) -> Vec<Editor> {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn projects(&self) -> &Projects {
|
||||||
|
&self.projects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::TormentNexus;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn without_cfg() {
|
||||||
|
let hub = TormentNexus::load();
|
||||||
|
println!("{hub:?}");
|
||||||
|
assert!(hub.is_ok())
|
||||||
|
}
|
||||||
|
}
|
10
core/src/project.rs
Normal file
10
core/src/project.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Project {
|
||||||
|
pub name: String,
|
||||||
|
pub editor: String,
|
||||||
|
pub path: PathBuf,
|
||||||
|
}
|
6
gui/Cargo.toml
Normal file
6
gui/Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "gui"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
3
gui/src/main.rs
Normal file
3
gui/src/main.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
2
rust-toolchain.toml
Normal file
2
rust-toolchain.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
Loading…
Add table
Reference in a new issue