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

//! Operators for [`NString`].

use core::ops::{
	Add,
	AddAssign,
	Deref,
	DerefMut,
	Index,
	IndexMut,
};
use core::slice::SliceIndex;
use core::str;
use nvec::NString;

impl<const N: usize> Add<&str> for NString<N> {
	type Output = Self;

	#[track_caller]
	fn add(mut self, rhs: &str) -> Self::Output {
		AddAssign::add_assign(&mut self, rhs);
		self
	}
}

impl<const N: usize> AddAssign<&str> for NString<N> {
	#[track_caller]
	fn add_assign(&mut self, rhs: &str) {
		assert!(
			self.try_push_str(rhs).is_ok(),
			"cannot add substring of length `{}` to `{N}`-string of length `{}`",
			rhs.len(),
			self.capacity(),
		);
	}
}

impl<const N: usize> Deref for NString<N> {
	type Target = str;

	#[inline]
	fn deref(&self) -> &Self::Target {
		self.as_str()
	}
}

impl<const N: usize> DerefMut for NString<N> {
	#[inline]
	fn deref_mut(&mut self) -> &mut Self::Target {
		self.as_mut_str()
	}
}

impl<I: SliceIndex<str>, const N: usize> Index<I> for NString<N> {
	type Output = I::Output;

	#[inline]
	fn index(&self, index: I) -> &Self::Output {
		Index::index(self.as_str(), index)
	}
}

impl<I: SliceIndex<str>, const N: usize> IndexMut<I> for NString<N> {
	#[inline]
	fn index_mut(&mut self, index: I) -> &mut Self::Output {
		IndexMut::index_mut(self.as_mut_str(), index)
	}
}
