allsorts_subset_browser/cff/charstring/
argstack.rs1use std::fmt::Debug;
5
6use crate::cff::CFFError;
7
8pub struct ArgumentsStack<'a, T>
10where
11 T: Debug,
12{
13 pub data: &'a mut [T],
14 pub len: usize,
15 pub max_len: usize,
16}
17
18impl<'a, T> ArgumentsStack<'a, T>
19where
20 T: Copy + Debug,
21{
22 pub fn len(&self) -> usize {
23 self.len
24 }
25
26 pub fn is_empty(&self) -> bool {
27 self.len == 0
28 }
29
30 pub fn push(&mut self, n: T) -> Result<(), CFFError> {
31 if self.len == self.max_len {
32 Err(CFFError::ArgumentsStackLimitReached)
33 } else {
34 self.data[self.len] = n;
35 self.len += 1;
36 Ok(())
37 }
38 }
39
40 #[cfg(feature = "outline")]
41 pub fn at(&self, index: usize) -> T {
42 self.data[index]
43 }
44
45 pub fn pop(&mut self) -> T {
46 debug_assert!(!self.is_empty());
47 self.len -= 1;
48 self.data[self.len]
49 }
50
51 pub fn pop_n(&mut self, n: usize) -> &[T] {
53 debug_assert!(n <= self.len);
54 self.len -= n;
55 &self.data[self.len..]
56 }
57
58 pub fn pop_all(&mut self) -> &[T] {
59 let len = self.len;
60 self.len = 0;
61 &self.data[..len]
62 }
63
64 pub fn all(&self) -> &[T] {
65 &self.data[..self.len]
66 }
67
68 pub fn offset<E>(
69 &mut self,
70 offset: usize,
71 mut func: impl FnMut(&ArgumentsStack<'_, T>) -> Result<(), E>,
72 ) -> Result<(), E> {
73 debug_assert!(offset <= self.len);
74 let temporary_stack = ArgumentsStack {
75 data: &mut self.data[offset..],
76 len: self.len - offset,
77 max_len: self.max_len - offset,
78 };
79 func(&temporary_stack)
80 }
81
82 #[cfg(feature = "outline")]
83 pub fn reverse(&mut self) {
84 if self.is_empty() {
85 return;
86 }
87
88 let (first, _) = self.data.split_at_mut(self.len);
90 first.reverse();
91 }
92
93 pub fn clear(&mut self) {
94 self.len = 0;
95 }
96
97 #[cfg(feature = "outline")]
98 pub(crate) fn clone_into(&self, data: &'a mut [T]) -> Self {
99 data[..self.len].clone_from_slice(&self.data[..self.len]);
100 ArgumentsStack {
101 data,
102 len: self.len,
103 max_len: self.max_len,
104 }
105 }
106}
107
108impl<T: Debug> Debug for ArgumentsStack<'_, T> {
109 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
110 f.debug_list().entries(&self.data[..self.len]).finish()
111 }
112}