use std::ffi::NulError;
use thiserror::Error;
#[expect(dead_code, reason = "We might use this in the future.")]
pub(crate) const C_STRING_FAILURE: &str =
"Provided an invalid CString, check if your string contains null bytes in the middle.";
pub(crate) const C_STR_FAILURE: &str = "Converting a CStr to an &str is failed.";
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum PdError {
#[error(transparent)]
InitializationError(#[from] InitializationError),
#[error(transparent)]
AudioInitializationError(#[from] AudioInitializationError),
#[error(transparent)]
PatchLifeCycleError(#[from] PatchLifeCycleError),
#[error(transparent)]
GuiLifeCycleError(#[from] GuiLifeCycleError),
#[error(transparent)]
IoError(#[from] IoError),
#[error(transparent)]
SendError(#[from] SendError),
#[error(transparent)]
SubscriptionError(#[from] SubscriptionError),
#[error(transparent)]
SizeError(#[from] SizeError),
#[error(transparent)]
ArrayError(#[from] ArrayError),
#[error(transparent)]
InstanceError(#[from] InstanceError),
#[error(transparent)]
StringConversion(#[from] StringConversionError),
}
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum InitializationError {
#[error("Failed to initialize ring buffers which are needed for the message queue.")]
RingBufferInitializationError,
#[error("An unknown error occurred in Pure Data initialization.")]
InitializationFailed,
}
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum AudioInitializationError {
#[error("An unknown error occurred in Pure Data audio initialization.")]
InitializationFailed,
}
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum PatchLifeCycleError {
#[error("Failed to open patch.")]
FailedToOpenPatch,
#[error("Failed to close patch, because the handle which was provided is null.")]
FailedToClosePatch,
#[error("The string which is passed could not be evaluated as a patch.")]
FailedToEvaluateAsPatch { content: String, msg: String },
#[error("The patch which is trying to be communicated with is not open.")]
PatchIsNotOpen,
#[error("The path you have provided does not exist in the file system. Path: {0}")]
PathDoesNotExist(String),
#[error(transparent)]
StringConversion(#[from] StringConversionError),
}
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum GuiLifeCycleError {
#[error("Failed to open gui, please provide a valid path to the pd binary.")]
FailedToOpenGui,
#[error(transparent)]
StringConversion(#[from] StringConversionError),
}
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum IoError {
#[error("The path you have provided does not exist in the file system. Path: {0}")]
PathDoesNotExist(String),
#[error(transparent)]
StringConversion(#[from] StringConversionError),
}
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum SendError {
#[error("No destination found for receiver: `{0}` in loaded pd patch.")]
MissingDestination(String),
#[error("Values which are being sent are out of range.")]
OutOfRange,
#[error(transparent)]
StringConversion(#[from] StringConversionError),
}
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum SubscriptionError {
#[error("Failed to subscribe to sender: `{0}` in loaded pd patch.")]
FailedToSubscribeToSender(String),
#[error(transparent)]
StringConversion(#[from] StringConversionError),
}
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum SizeError {
#[error("The maximum size specified is too large.")]
TooLarge,
#[error("Could not determine the size.")]
CouldNotDetermine,
#[error(transparent)]
StringConversion(#[from] StringConversionError),
}
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum ArrayError {
#[error("The array which you're trying to access doesn't exist.")]
FailedToFindArray,
#[error("The position in array which you're trying to write is out of bounds.")]
OutOfBounds,
#[error(transparent)]
StringConversion(#[from] StringConversionError),
}
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum InstanceError {
#[error("The instance {0} already created and exists.")]
InstanceAlreadyExists(String),
#[error("The instance {0} does not exist.")]
InstanceDoesNotExist(String),
#[error("The instance failed to create. Error: {0}")]
InstanceFailedToCreate(String),
#[error("There is no pd instance set for the current thread.")]
NoCurrentInstanceSet,
}
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum StringConversionError {
#[error("An interior null byte was found at position {pos} while converting to CString. Original string: '{string}' (bytes: {bytes:?})",
pos = .0,
string = String::from_utf8_lossy(.1),
bytes = .1
)]
NullTerminatedString(usize, Vec<u8>),
}
impl From<NulError> for StringConversionError {
fn from(err: NulError) -> Self {
Self::NullTerminatedString(err.nul_position(), err.into_vec())
}
}