#![warn(missing_docs)]
pub mod addon;
pub mod lang;
pub mod modifications;
pub mod output;
pub mod pkg;
pub mod util;
pub mod versions;
use std::{fmt::Display, str::FromStr};
use anyhow::anyhow;
#[cfg(feature = "schema")]
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
pub mod later {
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub enum Later<T> {
#[default]
Empty,
Full(T),
}
impl<T> Later<T> {
#[inline(always)]
pub fn new() -> Self {
Self::Empty
}
#[inline(always)]
pub fn fill(&mut self, value: T) {
*self = Self::Full(value);
}
pub fn ensure_full(&mut self, f: impl Fn() -> T) {
if self.is_empty() {
self.fill(f());
}
}
#[inline(always)]
pub fn clear(&mut self) {
*self = Self::Empty;
}
#[must_use]
#[inline(always)]
pub fn is_empty(&self) -> bool {
matches!(self, Self::Empty)
}
#[must_use]
#[inline(always)]
pub fn is_full(&self) -> bool {
matches!(self, Self::Full(..))
}
#[inline(always)]
pub fn get(&self) -> &T {
if let Self::Full(value) = self {
value
} else {
self.fail();
}
}
#[inline(always)]
pub fn get_mut(&mut self) -> &mut T {
if let Self::Full(value) = self {
value
} else {
self.fail();
}
}
#[inline(always)]
pub fn get_val(self) -> T {
if let Self::Full(value) = self {
value
} else {
self.fail();
}
}
#[inline(always)]
pub fn into_option(self) -> Option<T> {
match self {
Self::Empty => None,
Self::Full(val) => Some(val),
}
}
#[cold]
fn fail(&self) -> ! {
panic!("Value in Later<T> does not exist");
}
}
impl<T: Clone> Later<T> {
pub fn get_clone(&self) -> T {
if let Self::Full(value) = self {
value.clone()
} else {
self.fail();
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_later_fill() {
let mut later = Later::new();
later.fill(7);
later.get();
}
#[test]
#[should_panic(expected = "Value in Later<T> does not exist")]
fn test_later_fail() {
let later: Later<i32> = Later::new();
later.get();
}
}
}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(JsonSchema))]
#[serde(rename_all = "snake_case")]
pub enum Side {
Client,
Server,
}
impl Side {
pub fn parse_from_str(string: &str) -> Option<Self> {
match string {
"client" => Some(Self::Client),
"server" => Some(Self::Server),
_ => None,
}
}
}
impl FromStr for Side {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::parse_from_str(s).ok_or(anyhow!("Not a valid side"))
}
}
impl Display for Side {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Client => "client",
Self::Server => "server",
}
)
}
}
pub mod id {
use std::sync::Arc;
pub type InstanceID = Arc<str>;
pub type ProfileID = Arc<str>;
}
#[derive(Clone, Copy, PartialEq, Eq, Debug, PartialOrd, Ord, Serialize, Deserialize, Default)]
#[serde(rename_all = "snake_case")]
pub enum UpdateDepth {
#[default]
Shallow,
Full,
Force,
}