// Copyright 2025-2026 Gabriel Bjørnager Jensen.
//
// SPDX: MIT OR Apache-2.0

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

use core::error::Error;
use core::fmt::{self, Display, Formatter};
use core::mem::forget;
use core::str::Utf8Error;
use nvec::NVec;

/// A malformed UTF-8 sequence was detected.
#[derive(Debug, Eq, PartialEq)]
pub struct FromUtf8Error<const N: usize> {
	/// The error in question.
	pub(super) error: Utf8Error,

	/// The provided UTF-8 octets.
	pub(super) bytes: NVec<u8, N>,
}

impl<const N: usize> FromUtf8Error<N> {
	/// Retrieves the UTF-8 error in question.
	#[inline(always)]
	#[must_use]
	pub const fn utf8_error(&self) -> Utf8Error {
		self.error
	}

	/// Gets a slice over the malformed UTF-8 octets.
	#[inline(always)]
	#[must_use]
	pub const fn as_bytes(&self) -> &[u8] {
		self.bytes.as_slice()
	}

	/// Retrieves the malformed UTF-8 octets.
	#[inline]
	#[must_use]
	pub const fn into_bytes(self) -> NVec<u8, N> {
		let bytes = self.bytes.copied();
		forget(self);

		bytes
	}
}

impl<const N: usize> Display for FromUtf8Error<N> {
	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
		Display::fmt(&self.error, f)
	}
}

impl<const N: usize> Error for FromUtf8Error<N> {
	#[inline]
	fn source(&self) -> Option<&(dyn Error + 'static)> {
		Some(&self.error)
	}
}
