#![cfg(feature = "osd")]
#[derive(Debug, Default, PartialEq)]
pub struct OsdBufferCursor<'a> {
pub buf: &'a mut [u8],
pub pos: usize,
}
impl OsdBufferCursor<'_> {
pub const U32_MAX_DIGITS: usize = 10;
#[allow(unused)]
pub fn append_bytes(&mut self, bytes: &[u8]) {
let remaining = self.buf.len() - self.pos;
let to_copy = bytes.len().min(remaining);
if to_copy > 0 {
self.buf[self.pos..self.pos + to_copy].copy_from_slice(&bytes[..to_copy]);
self.pos += to_copy;
}
}
#[allow(unused)]
pub fn append_str(&mut self, text: &str) {
self.append_bytes(text.as_bytes());
}
#[allow(unused)]
pub fn append_u32(&mut self, mut value: u32) {
if value == 0 {
self.append_bytes(b"0");
return;
}
let mut temp = [0u8; Self::U32_MAX_DIGITS];
let mut ii = 0;
while value > 0 && ii < temp.len() {
temp[ii] = b'0' + (value % 10) as u8;
value /= 10;
ii += 1;
}
let remaining = self.buf.len() - self.pos;
let to_copy = ii.min(remaining);
for offset in 0..to_copy {
self.buf[self.pos + offset] = temp[ii - 1 - offset];
}
self.pos += to_copy;
}
#[allow(unused)]
pub fn append_str_right_aligned(&mut self, text: &str, field_width: usize) {
let bytes = text.as_bytes();
let remaining = self.buf.len() - self.pos;
let max_width = field_width.min(remaining);
if max_width == 0 {
return;
}
let text_len = bytes.len();
if text_len >= max_width {
let start_idx = text_len - max_width;
let to_copy = &bytes[start_idx..];
self.buf[self.pos..self.pos + max_width].copy_from_slice(to_copy);
self.pos += max_width;
} else {
let spaces_count = max_width - text_len;
self.buf[self.pos..self.pos + spaces_count].fill(b' ');
self.pos += spaces_count;
self.buf[self.pos..self.pos + text_len].copy_from_slice(bytes);
self.pos += text_len;
}
}
#[allow(unused)]
pub fn append_u32_right_aligned(&mut self, mut value: u32, field_width: usize, pad_with_zero: bool) {
let remaining = self.buf.len() - self.pos;
let max_width = field_width.min(remaining).min(Self::U32_MAX_DIGITS);
if max_width == 0 {
return;
}
let mut buf = [0u8; Self::U32_MAX_DIGITS];
let mut digit_count = 0;
if value == 0 {
buf[0] = b'0';
digit_count = 1;
} else {
while value > 0 && digit_count < buf.len() {
buf[digit_count] = b'0' + (value % 10) as u8;
value /= 10;
digit_count += 1;
}
}
let pad_char = if pad_with_zero { b'0' } else { b' ' };
if digit_count >= max_width {
for offset in 0..max_width {
self.buf[self.pos + offset] = buf[max_width - 1 - offset];
}
self.pos += max_width;
} else {
let padding_needed = max_width - digit_count;
self.buf[self.pos..self.pos + padding_needed].fill(pad_char);
self.pos += padding_needed;
for offset in 0..digit_count {
self.buf[self.pos + offset] = buf[digit_count - 1 - offset];
}
self.pos += digit_count;
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn _is_normal<T: Sized + Send + Sync + Unpin>() {}
fn _is_full<T: Sized + Send + Sync + Unpin + Copy + Clone + Default + PartialEq>() {}
fn is_partial<T: Sized + Send + Sync + Unpin + Default + PartialEq>() {}
#[test]
fn normal_types() {
is_partial::<OsdBufferCursor>();
}
}