1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use crate::{EngineError, define_new_pill_slotmap_key};
use anyhow::{ Context, Result, Error };
use boolinator::Boolinator;
use std::{ any::type_name, path::PathBuf };
use colored::*;
pub fn get_type_name<T>() -> String {
let full_type_name = type_name::<T>().to_string();
let pure_type_name_start_index = full_type_name.rfind(':').unwrap() + 1;
full_type_name[pure_type_name_start_index..].to_string()
}
pub fn get_value_type_name<T>(_: &T) -> String {
let full_type_name = type_name::<T>().to_string();
let pure_type_name_start_index = full_type_name.rfind(':').unwrap() + 1;
full_type_name[pure_type_name_start_index..].to_string()
}
pub fn enum_variant_eq<T>(a: &T, b: &T) -> bool {
std::mem::discriminant(a) == std::mem::discriminant(b)
}
pub fn get_enum_variant_type_name<T: core::fmt::Debug>(a: &T) -> String {
let full_type_name = format!("{:?}", a);
let pure_type_name_end_index = full_type_name.rfind('(');
match pure_type_name_end_index {
Some(v) => full_type_name[..v].to_string(),
None => full_type_name.to_string(),
}
}
pub trait PillStyle {
fn mobj_style(self) -> ColoredString;
fn gobj_style(self) -> ColoredString;
fn sobj_style(self) -> ColoredString;
fn name_style(self) -> ColoredString;
fn err_style(self) -> ColoredString;
}
impl PillStyle for &str {
#[inline]
fn mobj_style(self) -> ColoredString {
self.color(colored::Color::TrueColor { r: 180, g: 25, b: 100 }).bold()
}
#[inline]
fn gobj_style(self) -> ColoredString {
self.color(colored::Color::BrightCyan)
}
#[inline]
fn sobj_style(self) -> ColoredString {
self.color(colored::Color::TrueColor { r: 95, g: 210, b: 90 })
}
#[inline]
fn name_style(self) -> ColoredString {
format!("\"{}\"", self).color(colored::Color::TrueColor { r: 190, g: 220, b: 160 })
}
#[inline]
fn err_style(self) -> ColoredString {
self.color(colored::Color::Red).bold()
}
}
pub fn validate_asset_path(path: &PathBuf, allowed_formats: &'static [&'static str]) -> Result<()>
{
path.exists().ok_or(Error::new(EngineError::InvalidAssetPath(path.display().to_string())))?;
match path.extension() {
Some(v) => match allowed_formats.contains(&v.to_str().unwrap()) {
true => return Ok(()),
false => return Err(Error::new(EngineError::InvalidAssetFormat(allowed_formats, v.to_str().unwrap().to_string()))),
},
None => return Err(Error::new(EngineError::InvalidAssetPath(path.display().to_string()))),
}
}
#[macro_export] macro_rules! define_component_handle {
( $(#[$outer:meta])* $vis:vis struct $name:ident; $($rest:tt)* ) => {
pill_core::define_new_pill_slotmap_key! { }
};
}
#[inline]
pub fn get_game_error_message(result: Result<()>) -> Option<String> {
if result.is_err() {
let mut message = String::new();
for (i, error) in result.err().unwrap().chain().enumerate() {
let message_part = match i == 0 {
true => format!("Game error: {} \n", error),
false => format!(" {}: {} \n", i - 1, error),
};
message.push_str(message_part.as_str());
}
Some(message)
}
else {
None
}
}