1#![warn(missing_docs)]
2
3pub mod addon;
11pub mod lang;
13pub mod modifications;
15pub mod output;
17pub mod pkg;
19pub mod util;
21pub mod versions;
23
24use std::{fmt::Display, str::FromStr};
25
26use anyhow::anyhow;
27#[cfg(feature = "schema")]
28use schemars::JsonSchema;
29use serde::{Deserialize, Serialize};
30
31pub mod later {
33 #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
36 pub enum Later<T> {
37 #[default]
39 Empty,
40 Full(T),
42 }
43
44 impl<T> Later<T> {
45 #[inline(always)]
47 pub fn new() -> Self {
48 Self::Empty
49 }
50
51 #[inline(always)]
53 pub fn fill(&mut self, value: T) {
54 *self = Self::Full(value);
55 }
56
57 pub fn ensure_full(&mut self, f: impl Fn() -> T) {
59 if self.is_empty() {
60 self.fill(f());
61 }
62 }
63
64 #[inline(always)]
66 pub fn clear(&mut self) {
67 *self = Self::Empty;
68 }
69
70 #[must_use]
72 #[inline(always)]
73 pub fn is_empty(&self) -> bool {
74 matches!(self, Self::Empty)
75 }
76
77 #[must_use]
79 #[inline(always)]
80 pub fn is_full(&self) -> bool {
81 matches!(self, Self::Full(..))
82 }
83
84 #[inline(always)]
86 pub fn get(&self) -> &T {
87 if let Self::Full(value) = self {
88 value
89 } else {
90 self.fail();
91 }
92 }
93
94 #[inline(always)]
96 pub fn get_mut(&mut self) -> &mut T {
97 if let Self::Full(value) = self {
98 value
99 } else {
100 self.fail();
101 }
102 }
103
104 #[inline(always)]
106 pub fn get_val(self) -> T {
107 if let Self::Full(value) = self {
108 value
109 } else {
110 self.fail();
111 }
112 }
113
114 #[inline(always)]
116 pub fn into_option(self) -> Option<T> {
117 match self {
118 Self::Empty => None,
119 Self::Full(val) => Some(val),
120 }
121 }
122
123 #[cold]
124 fn fail(&self) -> ! {
125 panic!("Value in Later<T> does not exist");
126 }
127 }
128
129 impl<T: Clone> Later<T> {
130 pub fn get_clone(&self) -> T {
132 if let Self::Full(value) = self {
133 value.clone()
134 } else {
135 self.fail();
136 }
137 }
138 }
139
140 #[cfg(test)]
141 mod tests {
142 use super::*;
143
144 #[test]
145 fn test_later_fill() {
146 let mut later = Later::new();
147 later.fill(7);
148 later.get();
149 }
150
151 #[test]
152 #[should_panic(expected = "Value in Later<T> does not exist")]
153 fn test_later_fail() {
154 let later: Later<i32> = Later::new();
155 later.get();
156 }
157 }
158}
159
160#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
162#[cfg_attr(feature = "schema", derive(JsonSchema))]
163#[serde(rename_all = "snake_case")]
164pub enum Side {
165 Client,
167 Server,
169}
170
171impl Side {
172 pub fn parse_from_str(string: &str) -> Option<Self> {
174 match string {
175 "client" => Some(Self::Client),
176 "server" => Some(Self::Server),
177 _ => None,
178 }
179 }
180}
181
182impl FromStr for Side {
183 type Err = anyhow::Error;
184
185 fn from_str(s: &str) -> Result<Self, Self::Err> {
186 Self::parse_from_str(s).ok_or(anyhow!("Not a valid side"))
187 }
188}
189
190impl Display for Side {
191 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
192 write!(
193 f,
194 "{}",
195 match self {
196 Self::Client => "client",
197 Self::Server => "server",
198 }
199 )
200 }
201}
202
203pub mod id {
205 use std::sync::Arc;
206
207 pub type InstanceID = Arc<str>;
209
210 pub type ProfileID = Arc<str>;
212}