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

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

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

#[cfg(feature = "std")]
use nvec::{NString, NVec};

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

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

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

		let mut bytes = NVec::<u8, N>::try_with_capacity(len)?;

		r.read_exact(bytes.as_mut_slice())?;

		Self::from_utf8(bytes)
			.map_err(|_| io::ErrorKind::InvalidData.into())
	}
}

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

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

		self.len().serialise(w)?;
		w.write_all(self.as_bytes())?;

		Ok(())
	}
}
