1use crate::css::fileinfo::FileWeakRef;
2use crate::css::node::NodeWeakRef;
3use crate::css::select_node::SelectorNode;
4use crate::extend::string::StringExtend;
5use crate::extend::vec_str::VecCharExtend;
6use crate::sourcemap::loc::{Loc, LocMap};
7use crate::style_core::scan::traversal;
8use crate::token::lib::Token;
9use crate::token::select::{TokenAllowChar, TokenCombinaChar, TokenKeyWordChar, TokenSelectChar};
10use crate::util::str_enum::{CharToEnum, EnumToChar};
11use serde::ser::SerializeStruct;
12use serde::{Deserialize, Serialize, Serializer};
13use serde_json::{Map, Value};
14use std::cmp::Ordering;
15use std::ops::Deref;
16
17#[derive(Debug, Clone, Serialize, Eq, PartialEq)]
18#[serde(tag = "type", content = "value")]
19enum SelectVarText {
20 Txt(String),
21 Var(String),
22}
23
24#[derive(Debug, Clone, Serialize, Eq, PartialEq, Deserialize)]
25#[serde(tag = "type", content = "value")]
26pub enum SelectParadigm {
27 SelectWrap(String),
28 CominaWrap(TokenCombinaChar),
29 VarWrap(char),
30 KeyWrap(String),
31}
32
33impl SelectParadigm {
34 pub fn deserializer(val: &Value) -> Self {
38 serde_json::from_str(&serde_json::to_string(val).unwrap()).unwrap()
39 }
40}
41
42pub trait Paradigm {
43 fn tostr(&self) -> String;
48}
49
50impl Paradigm for Vec<SelectParadigm> {
51 fn tostr(&self) -> String {
52 let mut txt = "".to_string();
53 self.iter().for_each(|par| match par {
54 SelectParadigm::SelectWrap(cc) => txt += cc,
55 SelectParadigm::CominaWrap(cc) => {
56 txt.push(cc.to_str());
57 }
58 SelectParadigm::VarWrap(cc) => txt.push(*cc),
59 SelectParadigm::KeyWrap(cc) => {
60 txt = cc.clone();
61 }
62 });
63 txt
64 }
65}
66
67#[derive(Debug, Clone)]
68pub struct NewSelector {
69 pub paradigm_vec: Vec<Vec<SelectParadigm>>,
71
72 pub loc: Option<Loc>,
74
75 map: LocMap,
77
78 pub charlist: Vec<char>,
80
81 pub parent: NodeWeakRef,
84
85 pub fileinfo: FileWeakRef,
87}
88
89impl Serialize for NewSelector {
90 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
91 where
92 S: Serializer,
93 {
94 let mut state = serializer.serialize_struct("FileInfo", 3)?;
95 state.serialize_field("loc", &self.loc)?;
96 state.serialize_field("content", &self.charlist.poly())?;
97 state.serialize_field("paradigm_vec", &self.paradigm_vec)?;
98 state.end()
99 }
100}
101
102impl NewSelector {
103 pub fn new(
107 charlist: Vec<char>,
108 loc: Option<Loc>,
109 map: Option<LocMap>,
110 parent: NodeWeakRef,
111 fileinfo: FileWeakRef,
112 ) -> Self {
113 NewSelector {
114 paradigm_vec: vec![],
115 loc,
116 map: map.unwrap_or_else(|| LocMap::new(&charlist)),
117 charlist,
118 parent,
119 fileinfo,
120 }
121 }
122
123 pub fn find_up_select_node(node: NodeWeakRef) -> NodeWeakRef {
127 if let Some(ref heap_node) = node {
128 let rule = heap_node.upgrade().unwrap();
129 if matches!(
130 *rule.deref().borrow().selector.as_ref().unwrap(),
131 SelectorNode::Select(..)
132 ) {
133 node.clone()
134 } else {
135 let parent = rule.deref().borrow().parent.clone();
136 Self::find_up_select_node(parent)
137 }
138 } else {
139 None
140 }
141 }
142
143 pub fn deserializer(
147 map: &Map<String, Value>,
148 parent: NodeWeakRef,
149 fileinfo: FileWeakRef,
150 ) -> Result<Self, String> {
151 let mut select = Self {
152 paradigm_vec: vec![],
153 loc: None,
154 map: LocMap::new(&[]),
155 charlist: vec![],
156 parent,
157 fileinfo,
158 };
159 if let Some(Value::String(content)) = map.get("content") {
160 select.charlist = content.to_char_vec();
161 } else {
162 return Err("deserializer NewSelector has error -> charlist is empty!".to_string());
163 }
164 if let Some(Value::Object(loc)) = map.get("loc") {
165 select.loc = Some(Loc::deserializer(loc));
166 select.map = LocMap::merge(select.loc.as_ref().unwrap(), &select.charlist).0;
167 } else {
168 select.map = LocMap::new(&select.charlist);
169 }
170 if let Some(Value::Array(charlist)) = map.get("paradigm_vec") {
171 for paradigm_vec in charlist {
172 let mut list = vec![];
173 if let Value::Array(paradigm) = paradigm_vec {
174 list = paradigm.iter().map(SelectParadigm::deserializer).collect();
175 }
176 if !list.is_empty() {
177 select.paradigm_vec.push(list);
178 }
179 }
180 } else {
181 return Err("deserializer NewSelector has error -> paradigm_vec is empty!".to_string());
182 }
183 Ok(select)
184 }
185
186 pub fn value(&self) -> String {
190 self.charlist.poly()
191 }
192
193 pub fn code_gen(&self) -> Result<Vec<Vec<SelectParadigm>>, String> {
197 let mut split_select_txt: Vec<Vec<SelectParadigm>> = vec![];
198
199 for list in self.paradigm_vec.iter() {
200 let self_rule = self.parent.as_ref().unwrap().upgrade().unwrap();
202 let node = self_rule.deref().borrow().parent.clone();
203 let select_rule_node = Self::find_up_select_node(node);
204 let mut parent_select_txt = vec![];
205 if let Some(any_parent_rule) = select_rule_node {
206 let heap_any_parent_rule = any_parent_rule.upgrade().unwrap();
207 if let Some(SelectorNode::Select(ps)) =
208 heap_any_parent_rule.deref().borrow().selector.as_ref()
209 {
210 parent_select_txt = ps.code_gen()?;
211 };
212 }
213
214 let mut self_list = vec![];
216 let mut has_var = false;
217
218 let mut var_index = -1;
220 for (np, p) in list.iter().enumerate() {
221 if matches!(p, SelectParadigm::VarWrap(..)) {
222 var_index = np as i32;
223 } else if matches!(p, SelectParadigm::KeyWrap(..)) {
224 has_var = true;
225 }
226 }
227
228 if var_index > -1 {
229 has_var = true;
230
231 for expr in parent_select_txt.iter() {
232 let mut cplist = list.clone();
233 cplist.remove(var_index as usize);
234 for item in expr.iter().rev() {
235 cplist.insert(var_index as usize, item.clone())
236 }
237 self_list.push(cplist);
238 }
239 } else {
240 self_list.push(list.clone());
241 }
242
243 if has_var || parent_select_txt.is_empty() {
244 if !self_list.is_empty() {
245 split_select_txt.append(&mut self_list);
246 }
247 } else {
248 for expr in parent_select_txt.iter() {
249 for m in self_list.iter() {
250 let mut cp_expr = expr.clone();
251 if cp_expr.last() != Some(&SelectParadigm::CominaWrap(TokenCombinaChar::Space)) {
252 cp_expr.push(SelectParadigm::CominaWrap(TokenCombinaChar::Space));
253 }
254 cp_expr.append(&mut m.clone());
255 split_select_txt.push(cp_expr);
256 }
257 }
258 }
259 }
260
261 Ok(split_select_txt)
263 }
264
265 pub fn errormsg(&self, index: &usize) -> Result<(), String> {
269 let mut safe_index = *index;
270 if *index > self.charlist.len() - 1 {
271 safe_index = self.charlist.len() - 1;
272 }
273 let char = *self.charlist.get(safe_index).unwrap();
274 let error_loc = self.map.get(safe_index).unwrap();
275 Err(format!(
276 "select text {}, char {} is not allow, line is {} col is {}",
277 self.charlist.poly(),
278 char,
279 error_loc.line,
280 error_loc.col
281 ))
282 }
283
284 pub fn add_paradigm(&mut self, obj: SelectParadigm) {
291 if self.paradigm_vec.is_empty() {
292 if !matches!(obj, SelectParadigm::CominaWrap(..)) {
293 self.paradigm_vec.push(vec![obj]);
294 } else {
295 self.paradigm_vec.push(vec![
296 obj,
297 SelectParadigm::CominaWrap(TokenCombinaChar::Space),
298 ]);
299 }
300 } else {
301 let list = self.paradigm_vec.last_mut().unwrap();
302 if !matches!(obj, SelectParadigm::CominaWrap(..))
303 || matches!(obj, SelectParadigm::CominaWrap(TokenCombinaChar::Space))
304 {
305 if matches!(obj, SelectParadigm::VarWrap(..))
306 && matches!(list.get(0), Some(&SelectParadigm::CominaWrap(..)))
307 {
308 list.remove(0);
309 }
310 if list.is_empty() && !matches!(obj, SelectParadigm::CominaWrap(TokenCombinaChar::Space))
311 || !list.is_empty()
312 {
313 list.push(obj);
314 }
315 } else {
316 let last_paradigm = list.last();
317 if last_paradigm.is_some()
318 && !matches!(
319 last_paradigm,
320 Some(SelectParadigm::CominaWrap(TokenCombinaChar::Space))
321 )
322 {
323 list.push(SelectParadigm::CominaWrap(TokenCombinaChar::Space));
324 }
325 list.push(obj);
326 list.push(SelectParadigm::CominaWrap(TokenCombinaChar::Space));
327 }
328 }
329 }
330
331 pub fn clear_paraigm(&mut self, index: &usize) -> Result<(), String> {
337 if let Some(list) = self.paradigm_vec.last_mut() {
338 let mut rm_index_list: Vec<usize> = vec![];
339 let mut num = 0;
340 for (index, word) in list.iter().rev().enumerate() {
341 match word {
342 SelectParadigm::CominaWrap(_) => {
343 rm_index_list.push(list.len() - 1 - index);
344 }
345 _ => {
346 break;
347 }
348 }
349 }
350 for (_, val) in rm_index_list.into_iter().enumerate() {
351 list.remove(val - num);
352 num += 1;
353 }
354 if list.is_empty() {
355 return Err(self.errormsg(index).err().unwrap());
356 }
357 Ok(())
358 } else {
359 Err(self.errormsg(index).err().unwrap())
360 }
361 }
362
363 pub fn add_paradigm_vec(&mut self) {
367 self.paradigm_vec.push(vec![]);
368 }
369
370 pub fn last_paradigm(&self) -> Option<&SelectParadigm> {
374 if self.paradigm_vec.last().is_some() {
375 return self.paradigm_vec.last().unwrap().last();
376 }
377 None
378 }
379
380 pub fn last_paradigm_without_space(&self) -> Option<&SelectParadigm> {
384 if let Some(list) = self.paradigm_vec.last() {
385 for p in list.iter().rev() {
386 if *p != SelectParadigm::CominaWrap(TokenCombinaChar::Space) {
387 return Some(p);
388 } else {
389 continue;
390 }
391 }
392 None
393 } else {
394 None
395 }
396 }
397
398 pub fn is_end(char: Option<&char>, extend_char: Option<Vec<char>>) -> bool {
402 if let Some(cc) = char {
403 let mut charlist: Vec<char> = vec![];
404 if let Some(mut extend_list) = extend_char {
405 charlist.append(&mut extend_list);
406 }
407 charlist.append(
408 &mut TokenSelectChar::iterator()
409 .map(|x| x.to_str())
410 .collect::<Vec<char>>(),
411 );
412 charlist.append(
413 &mut TokenCombinaChar::iterator()
414 .map(|x| x.to_str())
415 .collect::<Vec<char>>(),
416 );
417 charlist.append(
418 &mut TokenKeyWordChar::iterator()
419 .map(|x| x.to_str())
420 .collect::<Vec<char>>(),
421 );
422 charlist.contains(cc)
423 } else {
424 false
425 }
426 }
427
428 pub fn parse(&mut self) -> Result<(), String> {
433 let index: usize = 0;
434 if self.charlist.contains(&'@') {
436 self.pure_select_txt()?;
437 }
438 let charlist = &self.charlist.clone();
439
440 let (_, end) = traversal(
441 Some(index),
442 charlist,
443 &mut (|arg, charword| {
444 let (index, _, _) = arg;
445 let (_, char, _) = charword;
446
447 if Token::is_token(Some(char)) {
448 if TokenSelectChar::is(char) {
449 let (select_word, end) = self.parse_selector_word(index)?;
451 self.add_paradigm(SelectParadigm::SelectWrap(select_word));
452 *index = end;
453 } else if TokenCombinaChar::is(char) {
454 let (_, end) = self.parse_combina_word(index)?;
455 *index = end;
456 } else if TokenKeyWordChar::is(char) {
457 if *char == '&' {
458 self.add_paradigm(SelectParadigm::VarWrap(*char));
459 } else {
460 let (key_word, end) = self.parse_at_keyword(index)?;
462 self.add_paradigm(SelectParadigm::KeyWrap(key_word));
463 *index = end;
464 }
465 } else if TokenAllowChar::is(char) {
466 let (select_word, end) = self.parse_selector_word(index)?;
468 self.add_paradigm(SelectParadigm::SelectWrap(select_word));
469 *index = end;
470 } else {
471 return Err(self.errormsg(index).err().unwrap());
472 }
473 } else {
474 let (select_word, end) = self.parse_selector_word(index)?;
476 self.add_paradigm(SelectParadigm::SelectWrap(select_word));
477 *index = end;
478 }
479 Ok(())
480 }),
481 )?;
482 self.clear_paraigm(&end)?;
483 Ok(())
484 }
485
486 fn parse_at_keyword(&mut self, index: &usize) -> Result<(String, usize), String> {
491 traversal(
492 Some(*index),
493 &self.charlist,
494 &mut (|arg, charword| {
495 let (index, temp, end) = arg;
496 let (_, char, next) = charword;
497 if Token::is_token(Some(char)) {
498 if *char == '@' {
499 if temp.is_empty() {
500 temp.push(*char);
501 } else {
502 return Err(self.errormsg(index).err().unwrap());
503 }
504 } else if TokenAllowChar::is(char) || Token::is_space_token(Some(char)) {
505 temp.push(*char);
506 } else {
507 return Err(self.errormsg(index).err().unwrap());
508 }
509 } else {
510 temp.push(*char);
511 }
512 if next.is_none() {
513 *end = true;
514 }
515 Ok(())
516 }),
517 )
518 }
519
520 fn parse_combina_word(&mut self, index: &usize) -> Result<(String, usize), String> {
524 let char = *self.charlist.get(*index).unwrap();
525 if Token::is_space_token(Some(&char)) {
526 let last_pardigm = self.last_paradigm();
527 if let Some(SelectParadigm::CominaWrap(token)) = last_pardigm {
528 if *token != TokenCombinaChar::Space {
529 self.add_paradigm(SelectParadigm::CominaWrap(TokenCombinaChar::Space));
530 }
531 } else {
532 self.add_paradigm(SelectParadigm::CominaWrap(TokenCombinaChar::Space));
533 }
534 } else if char == TokenCombinaChar::AddChar.to_str()
535 || char == TokenCombinaChar::ExtendChar.to_str()
536 || char == TokenCombinaChar::BrotherMatchChar.to_str()
537 || char == TokenCombinaChar::ColumnChar.to_str()
538 {
539 let last_pardigm = self.last_paradigm_without_space();
540 if !matches!(last_pardigm, Some(SelectParadigm::CominaWrap(..))) {
542 let combin_token = char.to_enum::<TokenCombinaChar>().unwrap();
543 self.add_paradigm(SelectParadigm::CominaWrap(combin_token));
544 } else {
545 return Err(self.errormsg(index).err().unwrap());
546 }
547 } else if char == TokenCombinaChar::Comma.to_str() {
548 self.clear_paraigm(index)?;
549 self.add_paradigm_vec();
550 }
551 Ok((char.to_string(), *index))
552 }
553
554 fn parse_selector_word(&mut self, start: &usize) -> Result<(String, usize), String> {
558 let res: (String, usize);
559 let charlist = &self.charlist;
560 let char = charlist.get(*start).unwrap();
561 if *char == '.' || *char == '#' {
562 res = self.parse_selector_class_or_id_word(start)?;
563 } else if *char == ':' {
564 res = self.parse_selector_pseudo_class_word(start)?;
565 } else if *char == '*' {
566 res = ('*'.to_string(), *start);
567 } else if *char == '[' {
568 res = self.parse_selector_attr(start)?;
569 } else if *char == '(' {
570 res = self.parse_selector_brackets(start)?;
571 } else if !Token::is_token(Some(char)) || TokenAllowChar::is(char) {
572 res = self.parse_selector_ele(start)?;
573 } else {
574 return Err(self.errormsg(start).err().unwrap());
575 }
576 Ok(res)
577 }
578
579 fn parse_selector_ele(&mut self, start: &usize) -> Result<(String, usize), String> {
583 traversal(
584 Some(*start),
585 &self.charlist,
586 &mut (|arg, charword| {
587 let (index, temp, end) = arg;
588 let (_, char, next) = charword;
589 if Token::is_token(Some(char)) {
590 if TokenAllowChar::is(char) {
591 temp.push(*char);
592 } else {
593 return Err(self.errormsg(index).err().unwrap());
594 }
595 } else {
596 temp.push(*char);
597 }
598 if next.is_none() || Self::is_end(next, None) {
599 *end = true;
600 }
601 Ok(())
602 }),
603 )
604 }
605
606 fn parse_selector_class_or_id_word(&mut self, start: &usize) -> Result<(String, usize), String> {
610 let charlist = &self.charlist;
611 let mut record = false;
612 traversal(
613 Some(*start),
614 charlist,
615 &mut (|arg, charword| {
616 let (index, temp, end) = arg;
617 let (_, char, next) = charword;
618 if Token::is_token(Some(char)) {
619 if TokenAllowChar::is(char) {
620 temp.push(*char);
621 } else if TokenSelectChar::is(char) && !record {
622 record = true;
623 temp.push(*char);
624 } else {
625 return Err(self.errormsg(index).err().unwrap());
626 }
627 } else {
628 temp.push(*char);
629 }
630 if (next.is_none() || Self::is_end(next, None)) && record {
632 if temp.len() < 2 {
633 return Err(self.errormsg(index).err().unwrap());
635 }
636 *end = true;
637 }
638 Ok(())
639 }),
640 )
641 }
642
643 fn parse_selector_pseudo_class_word(&mut self, start: &usize) -> Result<(String, usize), String> {
647 let charlist = &self.charlist;
648 let mut record = false;
649 traversal(
650 Some(*start),
651 charlist,
652 &mut (|arg, charword| {
653 let (index, temp, end) = arg;
654 let (_, char, next) = charword;
655 let mut next_fix = next;
656 if Token::is_token(Some(char)) {
657 if !record && *char == ':' {
658 if next == Some(&':') {
659 temp.push(*char);
660 *index += 1;
661 next_fix = {
662 if *index + 1 < charlist.len() {
663 charlist.get(*index + 1)
664 } else {
665 None
666 }
667 };
668 }
669 temp.push(*char);
670 record = true;
671 } else if TokenAllowChar::is(char) {
672 temp.push(*char);
673 } else {
674 return Err(self.errormsg(index).err().unwrap());
675 }
676 } else {
677 temp.push(*char);
678 }
679 if (next.is_none() || Self::is_end(next_fix, None)) && record {
681 if (temp.len() < 2 && *temp == vec![':']) || (temp.len() < 3 && *temp == vec![':', ':']) {
682 return Err(self.errormsg(index).err().unwrap());
684 }
685 *end = true;
686 }
687 Ok(())
688 }),
689 )
690 }
691
692 fn parse_selector_brackets(&mut self, start: &usize) -> Result<(String, usize), String> {
696 let mut level = 0;
697 let res = traversal(
698 Some(*start),
699 &self.charlist,
700 &mut (|arg, charword| {
701 let (index, temp, end) = arg;
702 let (_, char, next) = charword;
703 if Token::is_token(Some(char)) {
704 if TokenAllowChar::is(char) {
705 temp.push(*char);
706 return Ok(());
707 }
708 if *char == ')' {
709 level -= 1;
710 match level.cmp(&0) {
711 Ordering::Less => {
712 return Err(self.errormsg(index).err().unwrap());
713 }
714 Ordering::Equal => {
715 *end = true;
716 temp.push(*char);
717 return Ok(());
718 }
719 Ordering::Greater => {
720 temp.push(*char);
721 }
722 }
723 } else if *char == '@' && next != Some(&'{') {
724 return Err(self.errormsg(index).err().unwrap());
725 } else if *char == '(' {
726 level += 1;
727 temp.push(*char);
728 } else {
729 temp.push(*char);
730 }
731 } else {
732 temp.push(*char);
733 }
734 Ok(())
735 }),
736 )?;
737 if level > 0 {
738 return Err(self.errormsg(&res.1).err().unwrap());
739 }
740 Ok(res)
741 }
742
743 fn parse_selector_attr(&mut self, start: &usize) -> Result<(String, usize), String> {
747 let equal_chars = vec!['~', '|', '^', '$', '*'];
749 let mut hasequal = false;
750 let mut has_brackest = false;
751 let mut queto: Option<char> = None;
752
753 let res = traversal(
754 Some(*start),
755 &self.charlist,
756 &mut (|arg, charword| {
757 let (index, temp, end) = arg;
758 let (prev, char, next) = charword;
759 let get_prev_char_without_space = || -> Option<char> {
760 let mut res: Option<char> = None;
761 for tc in temp.iter().rev() {
762 if *tc == ' ' {
763 continue;
764 } else {
765 res = Some(*tc);
766 break;
767 }
768 }
769 res
770 };
771
772 if let Some(token_queto) = queto {
773 if has_brackest {
774 if *char == token_queto && prev != Some(&'\\') {
775 queto = None;
776 }
777 temp.push(*char);
778 } else {
779 return Err(self.errormsg(index).err().unwrap());
780 }
781 } else if Token::is_token(Some(char)) {
782 if has_brackest {
783 if *char == '[' {
784 return Err(self.errormsg(index).err().unwrap());
785 } else if *char == ']' {
786 let prev_char_without_space = get_prev_char_without_space();
787 if prev_char_without_space == Some('=') {
788 return Err(self.errormsg(index).err().unwrap());
789 }
790 temp.push(*char);
792 has_brackest = false;
793 *end = true;
794 } else if TokenAllowChar::is(char) {
795 temp.push(*char);
796 } else if equal_chars.contains(char) {
797 if next == Some(&'=') && !hasequal {
798 temp.push(*char);
799 temp.push('=');
800 hasequal = true;
801 *index += 1;
802 } else {
803 return Err(self.errormsg(index).err().unwrap());
804 }
805 } else if *char == '=' {
806 let prev_char_without_space = get_prev_char_without_space();
807 if prev_char_without_space == Some('[') {
808 return Err(self.errormsg(index).err().unwrap());
809 }
810 if !hasequal {
811 temp.push('=');
812 hasequal = true;
813 } else {
814 return Err(self.errormsg(index).err().unwrap());
815 }
816 } else if *char == '"' || *char == '\'' {
817 queto = Some(*char);
818 temp.push(*char);
819 } else {
820 return Err(self.errormsg(index).err().unwrap());
821 }
822 } else {
823 if *char == '[' {
825 temp.push(*char);
826 has_brackest = true;
827 } else {
828 return Err(self.errormsg(index).err().unwrap());
829 }
830 }
831 } else if has_brackest {
832 temp.push(*char);
833 } else {
834 return Err(self.errormsg(index).err().unwrap());
835 }
836 Ok(())
837 }),
838 )?;
839 if has_brackest {
840 return Err(self.errormsg(&res.1).err().unwrap());
841 }
842 Ok(res)
843 }
844
845 fn pure_select_txt(&mut self) -> Result<(), String> {
850 let mut record = false;
851 let mut list: Vec<SelectVarText> = vec![];
852 traversal(
853 None,
854 &self.charlist,
855 &mut (|arg, charword| {
856 let (index, temp, _end) = arg;
857 let (_prev, char, next) = charword;
858 if *char == '@' && next == Some(&'{') {
859 if !temp.is_empty() {
860 list.push(SelectVarText::Txt(temp.poly()));
861 }
862 temp.clear();
863 temp.push('@');
864 temp.push('{');
865 *index += 1;
866 record = true
867 } else if *char == '}' && record {
868 temp.push(*char);
869 if !temp.is_empty() {
870 list.push(SelectVarText::Var(temp.poly()));
871 } else {
872 return Err(format!(
873 "select txt {} index is {} -> @ var is not closure",
874 self.charlist.poly(),
875 *index
876 ));
877 }
878 temp.clear();
879 record = false;
880 } else {
881 temp.push(*char);
882 }
883 Ok(())
884 }),
885 )?;
886
887 let mut new_content = "".to_string();
888 if !list.is_empty() {
889 for tt in list {
890 if let SelectVarText::Txt(t) = tt {
891 new_content += &t;
892 }
893 }
894 self.charlist = new_content.to_char_vec();
895 }
896
897 Ok(())
898 }
899}