goldforge 0.8.1

Library for handling file formats used by GoldSrc and related engines.
Documentation
// Copyright 2025-2026 Gabriel Bjørnager Jensen.
//
// This Source Code Form is subject to the terms of
// the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, you
// can obtain one at:
// <https://mozilla.org/MPL/2.0/>.

//! The [`BuildError`] error type.

#![cfg(feature = "alloc")]

use core::convert::Infallible;
use core::error::Error;
use core::fmt::{self, Display, Formatter};

/// A WAD file could not be built.
#[derive(Debug)]
pub struct BuildError<'a>(Inner<'a>);

impl<'a> BuildError<'a> {
	/// Constructs a [`LargeSize`](Inner::LargeSize) instance.
	#[inline]
	#[must_use]
	pub(in crate::wad) fn large_size(value: usize) -> Self {
		let inner = Inner::LargeSize { value };
		Self(inner)
	}

	/// Constructs a [`LongLumpName`](Inner::LongLumpName) instance.
	#[inline]
	#[must_use]
	pub(in crate::wad) fn long_lump_name(name: &'a str) -> Self {
		let inner = Inner::LongLumpName { name };
		Self(inner)
	}

	/// Constructs a [`NullLumpName`](Inner::NullLumpName) instance.
	#[inline]
	#[must_use]
	pub(in crate::wad) fn null_lump_name(name: &'a str) -> Self {
		let inner = Inner::NullLumpName { name };
		Self(inner)
	}
}

impl Display for BuildError<'_> {
	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
		match self.0 {
			Inner::LargeSize { value } => {
				write!(f, "size value `{value}` may not be greater than `{}`", i32::MAX)?;
			}

			Inner::LongLumpName { name } => {
				write!(f, "lump name `{}` may not be longer than `8` character", name.escape_default())?;
			}

			Inner::NullLumpName { name } => {
				write!(f, "lump name `{}` may not contain null characters", name.escape_default())?;
			}
		}

		Ok(())
	}
}

impl Error for BuildError<'static> {}

impl From<Infallible> for BuildError<'_> {
	fn from(value: Infallible) -> Self {
		match value {}
	}
}

/// Internal variants of [`BuildError`].
#[non_exhaustive]
#[derive(Clone, Debug)]
enum Inner<'a> {
	/// A size value could not be represented by [`i32`].
	LargeSize {
		/// The size value in question.
		value: usize,
	},

	/// A lump name was longer than `8` characters.
	LongLumpName {
		/// The lump name in question.
		name: &'a str,
	},

	/// A lump name contained null character(s).
	NullLumpName {
		/// The lump name in question.
		name: &'a str,
	},
}