#![expect(dead_code)]
use std::{
fmt,
marker::PhantomData,
ops::{Bound, RangeBounds},
ptr::NonNull,
slice,
};
use crate::{
grid::Grid,
output::StyledChar,
pos::{Coord, Size, X, Y},
};
#[derive(Clone)]
pub struct CgPtr<'b> {
pub chars: NonNull<StyledChar>,
pub size: Size,
life: PhantomData<&'b mut ()>,
}
impl fmt::Debug for CgPtr<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
(..).fmt(f)
}
}
impl<'b> CgPtr<'b> {
pub fn new(cg: &'b mut Grid<StyledChar>) -> Self {
let ptr = unsafe { NonNull::new_unchecked(cg.all_cells().as_mut_ptr() as *mut _) };
Self { chars: ptr, size: cg.size(), life: PhantomData }
}
pub unsafe fn cell(&mut self, x: X, y: Y) -> &mut StyledChar {
assert!(x < self.size.width, "x={x} is out of bounds ({})", self.size.width);
assert!(y < self.size.height, "y={y} is out of bounds ({})", self.size.height);
unsafe {
let mut ptr = self.chars.add((y.0 * self.size.width.0) + x.0);
ptr.as_mut()
}
}
pub unsafe fn slice(&mut self, x: impl RangeBounds<Coord>, y: Y) -> &mut [StyledChar] {
let start = match x.start_bound() {
Bound::Included(s) => *s,
Bound::Excluded(s) => s + 1,
Bound::Unbounded => 0,
};
let end = match x.end_bound() {
Bound::Included(s) => s + 1,
Bound::Excluded(s) => *s,
Bound::Unbounded => self.size.width.0,
};
assert!(start < self.size.width.0, "s={start} is out of bounds ({})", self.size.width);
assert!(end <= self.size.width.0, "e={end} is out of bounds ({})", self.size.width);
assert!(y < self.size.height, "y={y} is out of bounds ({})", self.size.height);
unsafe {
let ptr = self.chars.add((y.0 * self.size.width.0) + start);
let len = end - start;
slice::from_raw_parts_mut(ptr.as_ptr(), len)
}
}
}