looklook 0.9.0

Descriptive signal synthesiser.
// Copyright 2026 Gabriel Bjørnager Jensen.
//
// This file is part of LOOKLOOK.
//
// LOOKLOOK is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free Software
// Foundation, either version 3 of the License, or (at your option) any later ver-
// sion.
//
// LOOKLOOK is distributed in the hope that it will be useful, but WITHOUT ANY WAR-
// RANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
// PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License along
// with LOOKLOOK. If not, see <https://www.gnu.org/licenses/>.

//! The [`Builder`] type.

use crate::error::Error;

use std::num::NonZero;

/// An [`Error`] builder.
#[must_use]
#[derive(Clone, Debug)]
#[derive_const(Default)]
pub struct Builder {
	/// The errror message.
	pub(super) message: Option<Box<str>>,

	/// The file offset (if emulation error.)
	pub(super) offset: Option<NonZero<u64>>,
}

impl Builder {
	/// Constructs a new error builder.
	#[inline]
	pub const fn new() -> Self {
		Default::default()
	}

	/// Specifies the error message.
	pub fn message<T: ToString>(mut self, message: T) -> Self {
		self.message = Some(message.to_string().into());
		self
	}

	/// Specifies the file offset.
	///
	/// # Panics
	///
	/// This method will panic if the provided offset is equal to [`u64::MAX`].
	#[inline]
	pub fn offset(mut self, mut offset: u64) -> Self {
		offset = offset.checked_add(1)
			.expect("cannot specify `0xFFFFFFFFFFFFFFFF` as offset");

		// NOTE: This always yields `Some`.
		self.offset = NonZero::new(offset);
		self
	}

	/// Builds the error.
	///
	/// # Panics
	///
	/// This method will panic if an error message isn't specified.
	#[inline]
	pub fn build(self) -> Error {
		Error::from_builder(self)
	}
}