1use std::convert::Into;
9use std::fmt::{Display, Formatter, Debug};
10use std::hash::Hash;
11use std::marker::PhantomData;
12use std::vec::IntoIter;
13use crate::tex::catcodes::{CategoryCodeScheme, STARTING_SCHEME_U8};
14use crate::utils::Ptr;
15
16
17
18pub trait CharType:Copy+PartialEq+Eq+Hash+Display+Debug+'static+From<u8>+Default {
24 type Allchars<A:Default> : AllCharsTrait<Self,A>;
26
27 const MAX:Self;
29
30 fn from_u8_iter(iter:&mut IntoIter<u8>) -> Option<Self>;
32 fn from_str(s:&str) -> TeXStr<Self>;
34
35 fn is_eol(self) -> Option<bool>;
44
45 fn is_eol_pair(self,next:Self) -> bool;
50
51 fn par_token() -> TeXStr<Self>;
53
54 fn relax_token() -> TeXStr<Self>;
56
57 fn empty_str() -> TeXStr<Self>;
59
60 fn starting_catcode_scheme() -> CategoryCodeScheme<Self>;
62
63 fn newline() -> Self;
64 fn carriage_return() -> Self;
65 fn backslash() -> Self;
66 fn zeros() -> Self::Allchars<Self>;
67 fn ident() -> Self::Allchars<Self>;
68 fn rep_field<A:Clone+Default>(a:A) -> Self::Allchars<A>;
69
70 fn display_str(str:&TeXStr<Self>, f: &mut Formatter<'_>) -> std::fmt::Result {
72 for u in &*str.0 { write!(f,"{}",u.char_str())?; }
73 Ok(())
74 }
75 fn char_str(&self) -> String;
76 fn as_bytes(&self) -> Vec<u8>;
77
78 fn from_i64(i:i64) -> Option<Self>;
79 fn to_usize(self) -> usize;
80}
81
82thread_local! {
83 pub static PAR_U8: TeXStr<u8> = "par".into();
85 pub static RELAX_U8: TeXStr<u8> = "relax".into();
87 pub static EMPTY_U8: TeXStr<u8> = "".into();
89}
90
91impl CharType for u8 {
92 type Allchars<A:Default> = [A;256];
93 const MAX:Self=255;
94 fn from_u8_iter(iter: &mut IntoIter<u8>) -> Option<Self> { iter.next() }
95 fn newline() -> Self { b'\n' }
96 fn carriage_return() -> Self {b'\r'}
97 fn backslash() -> Self { b'\\' }
98 fn is_eol(self) -> Option<bool> {
100 match self {
101 b'\n' => Some(true),
102 b'\r' => None,
103 _ => Some(false)
104 }
105 }
106 fn from_str(s: &str) -> TeXStr<Self> {
107 TeXStr(Ptr::new(s.as_bytes().to_vec()))
108 }
109 fn is_eol_pair(self, next: Self) -> bool {
111 next == b'\n'
113 }
114 fn par_token() -> TeXStr<Self> { PAR_U8.with(|p| p.clone()) }
115 fn relax_token() -> TeXStr<Self> { RELAX_U8.with(|p| p.clone()) }
116 fn empty_str() -> TeXStr<Self> {EMPTY_U8.with(|p| p.clone()) }
117 fn starting_catcode_scheme() -> CategoryCodeScheme<Self> {
119 STARTING_SCHEME_U8.clone()
120 }
121 fn as_bytes(&self) -> Vec<u8> { vec![*self] }
122
123 fn char_str(&self) -> String {
125 match *self {
126 0 => "\\u0000".to_string(),
127 b'\n' => "\\n".to_string(),
128 b'\r' => "\\r".to_string(),
129 o if is_ascii(o) => (o as char).to_string(), o => format!("\\u00{:X}",o)
131 }
132 }
133 fn zeros() -> Self::Allchars<Self> {
134 [0;256]
135 }
136 fn ident() -> Self::Allchars<Self> {
137 let mut a = [0;256];
138 for i in 0..256 { a[i] = i as u8; }
139 a
140 }
141 fn rep_field<A: Clone+Default>(a: A) -> Self::Allchars<A> {
142 [ a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
144 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
145 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
146 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
147 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
148 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
149 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
150 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
151 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
152 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
153 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
154 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
155 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
156 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
157 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
158 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
159 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
160 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
161 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
162 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
163 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
164 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
165 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
166 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
167 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
168 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
169 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
170 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
171 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
172 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
173 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),
174 a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone(),a.clone()
175 ]
176 }
177
178 fn from_i64(i: i64) -> Option<Self> {
179 if i == -1 {Some(255)} else if i < 0 || i > 255 { None } else { Some(i as u8) }
180 }
181 fn to_usize(self) -> usize { self as usize }
182}
183
184pub trait AllCharsTrait<C:CharType,A> {
187 fn get(&self, u: C) -> &A;
189 fn set(&mut self, u: C, v:A);
191 fn replace(&mut self, u: C, v:A) -> A;
193}
194impl<A> AllCharsTrait<u8,A> for [A;256] {
195 fn get(&self, u:u8) -> &A { &self[u as usize] }
197 fn set(&mut self, u:u8,v:A) { self[u as usize] = v }
199 fn replace(&mut self, u: u8, v: A) -> A {
201 std::mem::replace(&mut self[u as usize], v)
202 }
203}
204
205#[derive(Clone,PartialEq,Hash,Eq)]
209pub struct TeXStr<C:CharType>(Ptr<Vec<C>>);
210impl<C:CharType> TeXStr<C> {
211 pub fn len(&self) -> usize { self.0.len() }
212 pub fn as_vec(&self) -> &Vec<C> { &self.0 }
213}
214
215fn is_ascii(u:u8) -> bool { 32 <= u && u <= 126 }
217
218impl<C:CharType> Display for TeXStr<C> {
219 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
220 C::display_str(self, f)
221 }
222}
223impl From<&str> for TeXStr<u8> {
224 fn from(s: &str) -> Self {
225 TeXStr(Ptr::new(s.as_bytes().to_vec()))
226 }
227}
228impl From<String> for TeXStr<u8> {
229 fn from(s: String) -> Self {
230 TeXStr(Ptr::new(s.into_bytes()))
231 }
232}
233impl<C:CharType> From<Vec<C>> for TeXStr<C> {
234 fn from(v: Vec<C>) -> Self {
235 TeXStr(Ptr::new(v))
236 }
237}
238
239
240
241impl CharType for char {
242 const MAX: Self = 255 as char;
243 type Allchars<A: Default> = AllUnicodeChars<A>; fn from_i64(i: i64) -> Option<Self> { if i > 0 && i < 0x110000 { Some(char::from_u32(i as u32).unwrap()) } else { None } }
245 fn to_usize(self) -> usize { self as usize }
246 fn from_str(s: &str) -> TeXStr<Self> {
247 TeXStr(Ptr::new(s.chars().collect()))
248 }
249 fn display_str(str: &TeXStr<Self>, f: &mut Formatter<'_>) -> std::fmt::Result {
250 let str : String = str.0.iter().collect();
251 write!(f,"{}",str)
252 }
253
254 fn backslash() -> Self { '\\' }
255 fn carriage_return() -> Self { '\r' }
256 fn newline() -> Self { '\n' }
257 fn char_str(&self) -> String { self.to_string() }
258 fn is_eol(self) -> Option<bool> {
259 match self {
260 '\n' => Some(true),
261 '\r' => None,
262 _ => Some(false)
263 }
264 }
265 fn is_eol_pair(self, next: Self) -> bool {
266 next == '\n' }
268 fn as_bytes(&self) -> Vec<u8> {
269 self.to_string().as_bytes().into_iter().map(|u| *u).collect()
270 }
271
272 fn ident() -> Self::Allchars<Self> {
273 todo!()
274 }
275 fn empty_str() -> TeXStr<Self> {
276 todo!()
277 }
278 fn par_token() -> TeXStr<Self> {
279 todo!()
280 }
281 fn relax_token() -> TeXStr<Self> {
282 todo!()
283 }
284 fn starting_catcode_scheme() -> CategoryCodeScheme<Self> {
285 todo!()
286 }
287 fn from_u8_iter(iter: &mut IntoIter<u8>) -> Option<Self> {
288 todo!()
289 }
290 fn rep_field<A: Clone + Default>(a: A) -> Self::Allchars<A> {
291 todo!()
292 }
293 fn zeros() -> Self::Allchars<Self> {
294 todo!()
295 }
296}
297
298pub struct AllUnicodeChars<A:Default>(PhantomData<A>);
299impl<A:Default> AllCharsTrait<char,A> for AllUnicodeChars<A> {
300 fn get(&self, u: char) -> &A {
301 todo!()
302 }
303
304 fn set(&mut self, u: char, v: A) {
305 todo!()
306 }
307
308 fn replace(&mut self, u: char, v: A) -> A {
309 todo!()
310 }
311}
312
313