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

//! [Serde]-compatibility for [`NVec`].
//!
//! [Serde]: serde

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

use core::fmt::{self, Formatter};
use core::marker::PhantomData;
use nvec::NVec;
use serde::de::{
	self,
	Deserialize,
	Deserializer,
	SeqAccess,
	Visitor,
};
use serde::ser::{
	Serialize,
	Serializer,
	SerializeSeq,
};

/// The visitor for [`NVec`].
struct NVecVisitor<T, const N: usize> {
	/// The vector.
	_vec: PhantomData<NVec<T, N>>,
}

impl<T, const N: usize> Default for NVecVisitor<T, N> {
	#[inline]
	fn default() -> Self {
		Self { _vec: PhantomData }
	}
}

impl<'de, T: Deserialize<'de>, const N: usize> Visitor<'de> for NVecVisitor<T, N> {
	type Value = NVec<T, N>;

	fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
		write!(formatter, "an n-vector of capacity `{N}`")
	}

	fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
		let mut new = NVec::<T, N>::new();

		while let Some(elem) = seq.next_element()? {
			if new.try_push(elem).is_err() {
				let len = new.len() + 1;
				return Err(de::Error::invalid_length(len, &self));
			}
		}

		Ok(new)
	}
}

impl<'de, T: Deserialize<'de>, const N: usize> Deserialize<'de> for NVec<T, N> {
	fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>  {
		deserializer.deserialize_seq(NVecVisitor::<T, N>::default())
	}
}

impl<T: Serialize, const N: usize> Serialize for NVec<T, N> {
	fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
		let mut seq = serializer.serialize_seq(Some(self.len()))?;

		for elem in self {
			seq.serialize_element(elem)?;
		}

		seq.end()
	}
}
