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

//! [Oct]-compatibility for [`NVec`].
//!
//! [Oct]: oct

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

#[cfg(feature = "std")]
use nvec::NVec;

#[cfg(feature = "std")]
use oct::serdes::{Deserialise, MaxSerialisedSize, Serialise, serialise_iter};

#[cfg(feature = "std")]
use std::io::{self, Read, Write};

#[cfg(feature = "std")]
impl<T: Deserialise, const N: usize> Deserialise for NVec<T, N> {
	fn deserialise<R: Read>(r: &mut R) -> io::Result<Self> {
		let len = usize::deserialise(r)?;

		let mut new = Self::try_with_capacity(len)?;

		for _ in 0..len {
			let value = T::deserialise(r)?;

			// NOTE: We have tested that the length is within
			// bounds.
			new.try_push(value).unwrap();
		}

		Ok(new)
	}
}

#[cfg(feature = "std")]
impl<T: MaxSerialisedSize, const N: usize> MaxSerialisedSize for NVec<T, N> {
	const MAX_SERIALISED_SIZE: usize = {
		let elem_size = T::MAX_SERIALISED_SIZE;
		elem_size * N
	};
}

#[cfg(feature = "std")]
impl<T: Serialise, const N: usize> Serialise for NVec<T, N> {
	#[inline]
	fn serialise<W: Write>(&self, w: &mut W) -> io::Result<()> {
		// NOTE: We can't rely on
		// `<[T] as Serialise>::serialise` as it has an
		// unspecified encoding.

		self.len().serialise(w)?;
		serialise_iter(self, w)?;

		Ok(())
	}
}
