1use std::borrow::Borrow;
11use std::sync::Arc;
12use std::fmt;
13use std::path::PathBuf;
14use indexmap::IndexSet;
15use linked_hash_map::LinkedHashMap;
16use std::collections::{HashSet, HashMap};
17use std::collections::hash_map;
18use std::cell::Cell;
19use std::hash::{Hash, Hasher};
20
21use serde::{Serialize, Deserialize};
22
23use crate::common::{self, some_kind_of_lowercase_first_letter, prepare_enum_variant};
24use crate::lexer::lexer_node::{NodeInteger, NodeLongInteger};
25use crate::serializator::serializator::*;
26use crate::static_scheme::generator::RustCodeEnumType;
27use crate::LexerInfo;
28
29use super::error::{self, StaticSchemeRes};
30use super::generator::{RustCode, RustCodeDefineType, RustCodeFields, RustCodeItem, RustCodeItemDataType, RustCodeItemStruct};
31
32bitflags! {
33 #[derive(Copy, Clone, Debug, Serialize, Deserialize)]
36 pub struct ProcFlags: u64
37 {
38 const FLAG_OPTIONAL = 1;
40
41 const FLAG_COLLECTION = 2;
43 }
44}
45
46
47
48#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
51pub enum VectorSerializType
52{
53 Array,
55 Hashset,
57 Indexset
59}
60
61#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
63pub enum ArgDataType
64{
65 None,
66 Symbol,
67 String,
68 Int,
69 UInt,
70 LongInt,
71 LongUint,
72 Boolean,
73 Vector,
74 Range,
75 RangeInc,
76 Variable,
77 Entity,
78 Enumerator,
79 AutoType
80}
81
82impl Default for ArgDataType
83{
84 fn default() -> Self
85 {
86 return Self::None;
87 }
88}
89
90impl ArgDataType
91{
92 pub fn has_subtype(&self) -> bool
94 {
95 return
96 *self == Self::Vector || *self == Self::Range ||
97 *self == Self::RangeInc || *self == Self::Symbol;
98 }
99}
100
101impl fmt::Display for ArgDataType
102{
103 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
104 {
105 match *self
106 {
107 Self::None => write!(f, "Not Defined"),
108 Self::Symbol => write!(f, "Symbol"),
109 Self::String => write!(f, "String"),
110 Self::Int => write!(f, "Int"),
111 Self::UInt => write!(f, "Uint"),
112 Self::LongInt => write!(f, "LongInt"),
113 Self::LongUint => write!(f, "LongUint"),
114 Self::Boolean => write!(f, "Boolean"),
115 Self::Vector => write!(f, "Vector"),
116 Self::Range => write!(f, "Range"),
117 Self::RangeInc => write!(f, "RangeInc"),
118 Self::Variable => write!(f, "Variable"),
119 Self::Entity => write!(f, "Entity"),
120 Self::Enumerator => write!(f, "Enumerator"),
121 Self::AutoType => write!(f, "Auto-type"),
122 }
123 }
124}
125
126#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
128pub enum GenericDataTypes
129{
130 None,
131 Symbol(Box<GenericDataTypes>, LexerInfo),
132 String(String, LexerInfo),
133 Int(NodeInteger, LexerInfo),
134 LongInt(NodeLongInteger, LexerInfo),
135 Boolean(bool, LexerInfo),
136 Variable(String, LexerInfo), Entity(String, LexerInfo), Enumerator(String, String, LexerInfo),
139 Vector(Vec<GenericDataTypes>, LexerInfo),
140 Range(Box<GenericDataTypes>, Box<GenericDataTypes>, LexerInfo),
141 RangeIncl(Box<GenericDataTypes>, Box<GenericDataTypes>, LexerInfo),
142 AnyValWrap(Box<GenericDataTypes>, LexerInfo)
143}
144
145impl Default for GenericDataTypes
146{
147 fn default() -> Self
148 {
149 return Self::None;
150 }
151}
152
153impl fmt::Display for GenericDataTypes
154{
155 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
156 {
157 match *self
158 {
159 Self::None =>
160 write!(f, "None"),
161 Self::Symbol(ref r, ref li) =>
162 write!(f, "Symbol({}: {})", r, li),
163 Self::String(ref r, ref li) =>
164 write!(f, "String({}: {})", r, li),
165 Self::Int(ref r, ref li) =>
166 write!(f, "Int({}: {})", r, li),
167 Self::LongInt(ref r, ref li) =>
168 write!(f, "LongInt({}: {})", r, li),
169 Self::Boolean(ref r, ref li) =>
170 write!(f, "Boolean({}: {})", r, li),
171 Self::Vector(ref r, ref _li) =>
172 {
173 write!(f, "Vector(")?;
174 for i in r.iter()
175 {
176 write!(f, "{}", i)?;
177 }
178 write!(f, ")")
179 },
180 Self::Range(ref l, ref r, ref li) =>
181 write!(f, "Range({}..{}): {}", l, r, li),
182 Self::RangeIncl(ref l, ref r, ref li) =>
183 write!(f, "RangeIncl({}..={}): {}", l, r, li),
184 Self::Variable(ref var, ref li) =>
185 write!(f, "Variable(${}): '{}'", var, li),
186 Self::Entity(ref ent, ref li) =>
187 write!(f, "Entity(@{}): '{}'", ent, li),
188 Self::Enumerator(ref enum_name, ref enum_item, ref li) =>
189 write!(f, "Enumerator({}::{}): '{}'", enum_name, enum_item, li),
190 Self::AnyValWrap(ref anyval, ref li) =>
191 write!(f, "AnyValue({}): '{}'", anyval, li),
192 }
193 }
194}
195
196#[derive(Clone, Copy, Debug, PartialEq, Eq)]
197pub enum PathResolve
198{
199 Proc,
200 Struct,
201}
202
203#[derive(Debug, Serialize, Deserialize)]
206pub struct Serializator
207{
208 name: Arc<String>,
210
211 root_proc: Option<Arc<Procedure>>,
213
214 procedures: HashMap<Arc<String>, Arc<Procedure>>,
216
217 defines: HashMap<Arc<String>, Arc<Define>>,
219
220 enum_defines: HashMap<Arc<String>, Arc<DefineEnum>>,
222
223 root_ser_structure: Option<Arc<Structure>>,
225
226 enumeratos: Vec<Arc<Enumerator>>,
228
229 structs: Vec<Arc<Structure>>,
231
232 file_path: Option<PathBuf>,
234}
235
236impl fmt::Display for Serializator
237{
238 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
239 {
240 write!(f, "{}", self.name)
241 }
242}
243
244impl Clone for Serializator
246{
247 fn clone(&self) -> Self
248 {
249 panic!("Asserion trap: Serializator must never be cloned! \
250 Implementation Clone for Serializator is used to comply \
251 with compilter requirments.");
252 }
263}
264
265impl Serializator
266{
267 pub const SERIALIZATOR_FROM_MEMORY_PATH: &'static str = "from memory";
269
270 pub
273 fn new(name: String) -> Self
274 {
275 return
276 Self
277 {
278 name: Arc::new(name),
279 root_proc: None,
280 procedures: HashMap::new(),
281 defines: HashMap::new(),
282 enum_defines: HashMap::new(),
283 root_ser_structure: None,
284 enumeratos: Vec::new(),
285 structs: Vec::new(),
286 file_path: None,
287 };
288 }
289
290 pub
293 fn set_file_path(&mut self, file_path: Option<PathBuf>)
294 {
295 self.file_path = file_path;
296 }
297
298 pub
301 fn get_file_path(&self) -> Option<&PathBuf>
302 {
303 return self.file_path.as_ref();
304 }
305
306 pub
309 fn get_file_path_string_safe(&self) -> String
310 {
311 return
312 self
313 .file_path
314 .as_ref()
315 .map_or(
316 Self::SERIALIZATOR_FROM_MEMORY_PATH.to_string(),
317 |s| s.display().to_string()
318 );
319 }
320
321 pub
336 fn get_defines_by_proc_dt(&self, proc_name: &String, arg_dt: ArgDataType) -> Vec<Arc<Define>>
337 {
338 let mut defs: Vec<Arc<Define>> = Vec::new();
339
340 for (_defn, defk) in self.defines.iter()
341 {
342 if defk.is_in_proc_scope(proc_name) == true && defk.get_datatype() == arg_dt
343 {
344 defs.push(defk.clone());
345 }
346 }
347
348 return defs;
349 }
350
351 pub
352 fn resolve_path_to(&self, source: Arc<Procedure>, path_to_label: &[String],
353 full_path_to_lbl: &[String], is_enum: bool, path_last_len: usize) -> Result<(Arc<Procedure>, Arc<ForegnProc>), String>
354 {
355 let p = &path_to_label[0];
357
358 match source.procs.get(p)
360 {
361 Some(r) =>
362 {
363 if is_enum == true && path_to_label.len() == 1
365 {
366 return Ok((source.clone(), r.clone()));
367 }
368
369 if r.foregn_names.len() > 1
372 {
373 return Err(
374 format!("found item at: '{}', full path: '{}' is not a structure because allows \
375 more than one variant: '{}'", p, error::convert_list(full_path_to_lbl),
376 error::convert_hashset(&r.foregn_names, " "))
377 );
378 }
379
380 let foregn_names: Vec<String> =
382 r.foregn_names.iter().map(|f| f.clone()).collect();
383
384 let proc =
387 self
388 .procedures
389 .get(&foregn_names[0])
390 .ok_or_else(||
391 format!("procedure named: '{}', label path: '{}' does not exist in list of \
392 procedures", &foregn_names[0], error::convert_list(full_path_to_lbl))
393 )?
394 .clone();
395
396 if path_to_label.len() > path_last_len || is_enum == true
398 {
399 return self.resolve_path_to(proc, &path_to_label[1..], full_path_to_lbl, is_enum, path_last_len);
400 }
401 else
402 {
403 return Ok((proc, r.clone()));
404 }
405 }
406 None =>
407 {
408 return Err(
410 format!("path label not found: '{}', on chain: '{}', procedure \
411 endpoint: '{}' for structure", p, error::convert_list(full_path_to_lbl), source.get_name())
412 );
413 },
414 }
415 }
416
417
418 pub
438 fn resolve_path_to_struct(
439 &self,
440 source: Arc<Procedure>,
441 path_to_label: &[String],
442 full_path_to_lbl: &[String],
443 ) -> Result<(Arc<Structure>,Arc<Procedure>), String>
444 {
445 let (proc, _) = self.resolve_path_to(source, path_to_label, full_path_to_lbl, false, 1)?;
446
447 return Ok(
449 (self.get_serialization_struct_by_procname(proc.get_name())?, proc)
450 );
451 }
452
453 pub
463 fn resolve_path_to_proc(
464 &self,
465 source:Arc<Procedure>,
466 path_to_label: &[String],
467 full_path_to_lbl: &[String],
468 ) -> Result<(Option<Arc<Structure>>,Arc<Procedure>), String>
469 {
470 let (proc, _) = self.resolve_path_to(source, path_to_label, full_path_to_lbl, false, 1)?;
471
472 return Ok(
474 (self.get_serialization_struct_by_procname_opt(proc.get_name()), proc)
475 );
476 }
477
478 pub
498 fn resolve_path_to_enum(
499 &self,
500 source:Arc<Procedure>,
501 path_to_label: &[String],
502 full_path_to_lbl: &[String],
503 ) -> Result<(Arc<Enumerator>,Arc<Procedure>), String>
504 {
505 let (proc, forn_proc) = self.resolve_path_to(source, path_to_label, full_path_to_lbl, true, 1)?;
506
507 let enumer = self.find_enum_by_procs(&forn_proc)?;
508
509 return Ok((enumer, proc));
510 }
511
512 fn find_enum_by_procs(&self, foreign_proc: &ForegnProc) -> Result<Arc<Enumerator>, String>
532 {
533 let mut cnt: usize = 0;
534 let mut last_found: Option<Arc<Enumerator>> = None;
535
536 'ext: for enm_itm in self.enumeratos.iter()
537 {
538 let map: HashSet<String> =
539 enm_itm
540 .get_enum_procs_list()
541 .iter()
542 .map(|p| p.clone())
543 .collect();
544
545 for for_proc_name in foreign_proc.foregn_names.iter()
546 {
547 if map.contains(for_proc_name) == false
548 {
549 cnt = 0;
550 continue 'ext;
551 }
552
553 cnt += 1;
554 }
555
556 if cnt == map.len()
557 {
558 return Ok(enm_itm.clone());
559 }
560 else
561 {
562 cnt = 0;
563
564 match last_found
565 {
566 Some(ref r) =>
567 {
568 if r.get_enum_procs_list().len() > map.len()
569 {
570 last_found = Some(enm_itm.clone());
571 }
572 },
573 None =>
574 {
575 last_found = Some(enm_itm.clone());
576 }
577 }
578 }
579 }
580
581 if let Some(r) = last_found
582 {
583 return Ok(r);
584 }
585 else
586 {
587 return Err(
588 format!("can not find enum which serializes: '{}'",
589 error::convert_hashset(&foreign_proc.foregn_names, " "))
590 );
591 }
592 }
593
594
595
596 pub
615 fn resolve_path_to_arg(
616 &self,
617 source:Arc<Procedure>,
618 path_to_label: &[String],
619 full_path_to_lbl: &[String]
620 ) -> Result<Arc<Argument>, String>
621 {
622 let p = &path_to_label[0];
624
625 let (proc, _) =
626 self.resolve_path_to(source, path_to_label, full_path_to_lbl, false, 2)?;
627
628 let p = path_to_label.last().unwrap();
629
630 let arg =
631 proc
632 .args
633 .get(p)
634 .ok_or_else(||
635 format!("argument labeled as: '{}' was not found on path: '{}'",
636 p, error::convert_list(full_path_to_lbl))
637 )?
638 .clone();
639
640
641 return Ok(arg);
642 }
643
644 pub
659 fn generate_rust_code(&self, rust_code: &mut RustCode) -> Result<(), String>
660 {
661 for (_, de) in self.enum_defines.iter()
663 {
664 let items: Vec<RustCodeEnumType> =
665 de
666 .enum_defs
667 .iter()
668 .map(|itm| {
669 RustCodeEnumType::Empty(prepare_enum_variant(itm.as_str()), None)
670 }
671 )
672 .collect();
673
674 rust_code
675 .add_item(
676 RustCodeItem
677 ::new_enum_arg(de.get_enum_name().as_str(), de.get_rust_code_gen(), items)
678 );
679 }
680
681 for (_, de) in self.defines.iter()
683 {
684 let def =
685 RustCodeDefineType::make_from(de.get_datatype(), de.get_data())?;
686
687 rust_code.add_item(RustCodeItem::new_define(de.get_name().as_str(), def, de.comment.clone()));
688 }
689
690 let cur_set_int =
692 self
693 .get_root_ser()
694 .ok_or_else(||
695 format!(
696 "in file: '{}', root serialization is empty, nothing to do in '{}'",
697 self.get_file_path_string_safe(),self.get_name()
698 )
699 )?;
700
701 let cur_proc_int =
703 self
704 .get_root_proc()
705 .ok_or_else(||
706 format!(
707 "in file: '{}', root procedure is empty, nothing to do in '{}'",
708 self.get_file_path_string_safe(),self.get_name()
709 )
710 )?;
711
712 self
714 .generate_rust_struct(rust_code, cur_set_int.clone(), cur_proc_int, true)
715 .map_err(|e|
716 format!("generating Rust formatted structs failed: {}", e)
717 )?;
718
719 return Ok(());
720 }
721
722 fn generate_rust_struct(
746 &self,
747 rust_code: &mut RustCode,
748 cur_set_int: Arc<Structure>,
749 cur_proc_int: Arc<Procedure>,
750 is_root: bool,
751 ) -> Result<(), String>
752 {
753 let mut fields: Vec<RustCodeItemStruct> = Vec::with_capacity(cur_set_int.get_fields_len());
754
755 let field_first =
756 match cur_set_int.get_first_field()
757 {
758 Some(fdecl) =>
759 {
760 fdecl.get_data_type() == &FieldTypes::Enum && fdecl.get_field_name().is_none() == true
761 },
762 None => false
763 };
764
765 if is_root == true &&
766 cur_set_int.get_fields_len() == 1 &&
767 field_first == true
768 {
769 let field = cur_set_int.get_first_field().unwrap();
770
771 if field.is_optional() == true
773 {
774 return Err(
775 format!("(root) procedure: '{}', field path: '{}' is 'optional', but anonymous \
776 field can not be optional in this case", cur_proc_int.get_name(),
777 error::convert_list(field.get_path_to_label()))
778 );
779 }
780
781 let _ =
784 self
785 .generate_field(rust_code, field, cur_proc_int.clone(), None)
786 .map_err(|e|
787 format!("{} procedure: '{}', path to label: '{}'", e, cur_proc_int.get_name(),
788 error::convert_list(field.get_path_to_label()))
789 )?;
790
791 }
792 else
793 {
794 for root_field in cur_set_int.get_fields_iter()
796 {
797 let field =
798 self
799 .generate_field(rust_code, root_field, cur_proc_int.clone(), None)
800 .map_err(|e|
801 format!("{} procedure: '{}', path to label: '{}'", e, cur_proc_int.get_name(),
802 error::convert_list(root_field.get_path_to_label()))
803 )?;
804
805 fields.push(field);
806 }
807
808 let rci =
809 RustCodeItem::new_struct(
810 cur_set_int.as_ref(),
811 fields,
812 is_root,
813 );
814
815 rust_code.add_item(rci);
816 }
817
818 return Ok(());
819 }
820
821 pub
842 fn generate_field_data_type(
843 &self,
844 rust_code: &mut RustCode,
845 field: &FieldDecl,
846 cur_proc_int:Arc<Procedure>,
847 cur_enumer: Option<Arc<Enumerator>>
848 ) -> Result<RustCodeItemDataType, String>
849 {
850 let field_datatype =
851 match field.get_data_type()
852 {
853 FieldTypes::String =>
854 RustCodeItemDataType::String,
855 FieldTypes::Boolean =>
856 RustCodeItemDataType::Bool,
857 FieldTypes::Int =>
858 RustCodeItemDataType::Int(field.get_int_width()),
859 FieldTypes::UInt =>
860 RustCodeItemDataType::Uint(field.get_int_width()),
861 FieldTypes::LongInt =>
862 RustCodeItemDataType::Int(field.get_int_width()),
863 FieldTypes::LongUInt =>
864 RustCodeItemDataType::Uint(field.get_int_width()),
865 FieldTypes::AnyType =>
866 {
867 rust_code.set_field_any(8);
882
883 RustCodeItemDataType::AnyType
884 },
885 FieldTypes::Range =>
886 {
887 let foreign_arg =
888 self.resolve_path_to_arg(cur_proc_int.clone(), field.get_path_to_label(),
889 field.get_path_to_label())?;
890
891
892 let sd_type =
893 match foreign_arg.get_collection_type()
894 {
895 ArgDataType::UInt =>
896 RustCodeItemDataType::Uint(field.get_int_width()),
897 ArgDataType::Int =>
898 RustCodeItemDataType::Int(field.get_int_width()),
899 _ =>
900 return Err(
901 format!("unexpected inner type for <range>, type: '{}'",
902 foreign_arg.get_collection_type())
903 )
904 };
905
906 RustCodeItemDataType::Range(Box::new(sd_type))
907 },
908 FieldTypes::RangeInc =>
909 {
910 let foreign_arg =
911 self.resolve_path_to_arg(cur_proc_int.clone(), field.get_path_to_label(),
912 field.get_path_to_label())?;
913
914 let sd_type =
915 match foreign_arg.get_collection_type()
916 {
917 ArgDataType::UInt =>
918 RustCodeItemDataType::Uint(field.get_int_width()),
919 ArgDataType::Int =>
920 RustCodeItemDataType::Int(field.get_int_width()),
921 _ =>
922 return Err(
923 format!("unexpected inner type for <rangeinc>, type: '{}'",
924 foreign_arg.get_collection_type())
925 )
926 };
927
928 RustCodeItemDataType::RangeInclusive(Box::new(sd_type))
929 },
930 FieldTypes::Struct =>
931 {
932 let (foregn_struct, foregn_proc) =
933 self.resolve_path_to_struct(cur_proc_int.clone(), field.get_path_to_label(),
934 field.get_path_to_label())?;
935
936 self.generate_rust_struct(
937 rust_code,
938 foregn_struct.clone(),
939 foregn_proc,
940 false
941 )?;
942
943 RustCodeItemDataType::Struct(foregn_struct.get_struct_name().get_name_1().to_string())
944 },
945 FieldTypes::Vector =>
946 {
947 let inner_type =
948 match field.get_data_inner_type(1)
949 {
950 FieldTypes::AnyType =>
951 {
952 rust_code.set_field_any(8);
953
954 RustCodeItemDataType::AnyType
955 },
956 FieldTypes::Struct =>
957 {
958 let (foregn_struct, foregn_proc) =
959 self.resolve_path_to_struct(cur_proc_int.clone(), field.get_path_to_label(),
960 field.get_path_to_label())?;
961
962 self.generate_rust_struct(rust_code, foregn_struct.clone(),
963 foregn_proc, false)?;
964
965 RustCodeItemDataType::Struct(foregn_struct.get_struct_name().get_name_1().to_string())
966 },
967 FieldTypes::ArgEnum =>
968 {
969 let foreign_arg =
970 self.resolve_path_to_arg(cur_proc_int.clone(), field.get_path_to_label(),
971 field.get_path_to_label())?;
972
973
974 if *foreign_arg.get_data_type() == ArgDataType::Enumerator
975 {
976 return Err(
977 format!("argument on the path: '{}' is not defined as `enumerator`",
978 field.get_path_to_label().join("/"))
979 );
980 }
981
982 match field.get_arg_enum_title()
983 {
984 Some(r) =>
985 {
986 let _ =
987 self.enum_defines
988 .get(r)
989 .ok_or_else(||
990 format!("can not find argument enum name: '{}'", r)
991 );
992
993 RustCodeItemDataType::Enum(r.clone())
994 },
995 None =>
996 {
997 return Err(
998 format!("enum name was not set, field: '{}'", field.get_field_name_safe())
999 );
1000 }
1001 }
1002 },
1003 FieldTypes::Enum =>
1004 {
1005 let (enumer, proced) =
1006 self.resolve_path_to_enum(cur_proc_int.clone(), field.get_path_to_label(),
1007 field.get_path_to_label())?;
1008
1009 if cur_enumer.is_some() == true && enumer.as_ref() == cur_enumer.as_ref().unwrap().as_ref()
1010 {
1011 RustCodeItemDataType::Enum(enumer.get_enum_label().clone())
1012 }
1013 else
1014 {
1015 self.generate_rust_enum(rust_code, enumer.clone(), proced)?;
1017
1018 RustCodeItemDataType::Enum(enumer.get_enum_label().clone())
1019 }
1020 },
1021 FieldTypes::Range =>
1022 {
1023 let foreign_arg =
1024 self.resolve_path_to_arg(cur_proc_int.clone(), field.get_path_to_label(),
1025 field.get_path_to_label())?;
1026
1027 let sd_type =
1028 match foreign_arg.get_collection_type()
1029 {
1030 ArgDataType::UInt =>
1031 RustCodeItemDataType::Uint(field.get_int_width()),
1032 ArgDataType::Int =>
1033 RustCodeItemDataType::Int(field.get_int_width()),
1034 _ =>
1035 return Err(
1036 format!("unexpected inner type for <range>, type: '{}'",
1037 foreign_arg.get_collection_type())
1038 )
1039 };
1040
1041 RustCodeItemDataType::Range(Box::new(sd_type))
1042 },
1043 FieldTypes::RangeInc =>
1044 {
1045 let foreign_arg =
1046 self.resolve_path_to_arg(cur_proc_int.clone(), field.get_path_to_label(),
1047 field.get_path_to_label())?;
1048
1049 let sd_type =
1050 match foreign_arg.get_collection_type()
1051 {
1052 ArgDataType::UInt =>
1053 RustCodeItemDataType::Uint(field.get_int_width()),
1054 ArgDataType::Int =>
1055 RustCodeItemDataType::Int(field.get_int_width()),
1056 _ =>
1057 return Err(
1058 format!("unexpected inner type for <rangeinc>, type: '{}'",
1059 foreign_arg.get_collection_type())
1060 )
1061 };
1062
1063 RustCodeItemDataType::RangeInclusive(Box::new(sd_type))
1064 },
1065 FieldTypes::String =>
1066 RustCodeItemDataType::String,
1067 FieldTypes::Boolean =>
1068 RustCodeItemDataType::Bool,
1069 FieldTypes::Int =>
1070 RustCodeItemDataType::Int(field.get_int_width()),
1071 FieldTypes::UInt =>
1072 RustCodeItemDataType::Uint(field.get_int_width()),
1073 FieldTypes::LongInt =>
1074 RustCodeItemDataType::Int(field.get_int_width()),
1075 FieldTypes::LongUInt =>
1076 RustCodeItemDataType::Uint(field.get_int_width()),
1077 FieldTypes::None =>
1078 return Err(format!("can not serialize field with type None")),
1079 FieldTypes::Optional =>
1080 return Err(format!("can not serialize field with type Optional")),
1081 FieldTypes::Vector =>
1082 return Err(format!("field with vector in vector is not allowed")),
1083 };
1084
1085 RustCodeItemDataType::Vector(Box::new(inner_type), field.get_vector_serial_type())
1086 },
1087 FieldTypes::Enum =>
1088 {
1089 let (enumer, proced) =
1091 self.resolve_path_to_enum(cur_proc_int.clone(), field.get_path_to_label(),
1092 field.get_path_to_label())?;
1093
1094 self.generate_rust_enum(rust_code, enumer.clone(), proced)?;
1095
1096 RustCodeItemDataType::Enum(enumer.get_enum_label().clone())
1097 },
1098 FieldTypes::ArgEnum =>
1099 {
1100 let foreign_arg =
1101 self.resolve_path_to_arg(cur_proc_int.clone(), field.get_path_to_label(),
1102 field.get_path_to_label())?;
1103
1104 if *foreign_arg.get_data_type() != ArgDataType::Enumerator
1105 {
1106 return Err(
1107 format!("argument on the path: '{}' is not defined as `enumerator`",
1108 field.get_path_to_label().join("/"))
1109 );
1110 }
1111
1112 match field.get_arg_enum_title()
1113 {
1114 Some(r) =>
1115 {
1116 let _ =
1117 self.enum_defines
1118 .get(r)
1119 .ok_or_else(||
1120 format!("can not find argument enum name: '{}'", r)
1121 );
1122
1123 RustCodeItemDataType::Enum(r.clone())
1124 },
1125 None =>
1126 {
1127 return Err(
1128 format!("enum name was not set, field: '{}'", field.get_field_name_safe())
1129 );
1130 }
1131 }
1132 },
1133 FieldTypes::None =>
1134 return Err(format!("can not serialize field with type None")),
1135 FieldTypes::Optional =>
1136 return Err(format!("can not serialize field with type Optional")),
1137 };
1138
1139
1140 return Ok(field_datatype);
1141 }
1142
1143 fn generate_field(
1168 &self,
1169 rust_code: &mut RustCode,
1170 field: &FieldDecl,
1171 cur_proc_int: Arc<Procedure>,
1172 cur_enumer: Option<Arc<Enumerator>>
1173 ) -> Result<RustCodeItemStruct, String>
1174 {
1175 let is_enum = cur_enumer.is_some();
1176 let field_datatype = self.generate_field_data_type(rust_code, field, cur_proc_int, cur_enumer)?;
1177
1178 return Ok(
1179 RustCodeItemStruct
1180 ::new(field.get_field_name(), field.is_optional(), field.get_field_comment(),
1181 field_datatype, is_enum
1182 )
1183 );
1184 }
1185
1186 fn generate_rust_enum(
1211 &self,
1212 rust_code: &mut RustCode,
1213 enumer:Arc<Enumerator>,
1214 _proced:Arc<Procedure>
1215 ) -> Result<(), String>
1216 {
1217 let mut enums: Vec<RustCodeEnumType> = Vec::with_capacity(enumer.get_enum_opts_len());
1219
1220 for enm in enumer.get_enum_opts_iter()
1222 {
1223 match enm
1224 {
1225 EnumOpt::Anonymous{ proc_rename, comment, .. } =>
1227 {
1228 let rcet = RustCodeEnumType::new_anon(proc_rename, comment.clone());
1229
1230 enums.push(rcet);
1231 },
1232 EnumOpt::Vector{ proc_name, proc_rename, fields, comment } =>
1234 {
1235 let mut items: Vec<RustCodeItemDataType> = Vec::with_capacity(fields.len());
1237
1238 let proc_loc =
1240 self
1241 .procedures
1242 .get(proc_name)
1243 .ok_or_else(||
1244 format!("procedure named: '{}', does not exist in list of \
1245 procedures while serializing enum {} -> {}", proc_name, proc_name, proc_rename)
1246 )?
1247 .clone();
1248
1249 for field in fields.iter()
1250 {
1251 let field =
1252 self.generate_field_data_type(rust_code, field, proc_loc.clone(), Some(enumer.clone()))?;
1253
1254 items.push(field);
1255 }
1256
1257 let rcet = RustCodeEnumType::new_vec(proc_rename, items, comment.clone());
1258
1259 enums.push(rcet);
1260 },
1261 EnumOpt::Structure { proc_name, proc_rename, structure, comment } =>
1263 {
1264 let mut items: Vec<RustCodeItemStruct> = Vec::with_capacity(structure.get_fields_len());
1266
1267 let proc_loc =
1269 self
1270 .procedures
1271 .get(proc_name)
1272 .ok_or_else(||
1273 format!("procedure named: '{}', does not exist in list of \
1274 procedures while serializing enum {} -> {}", proc_name, proc_name, proc_rename)
1275 )?
1276 .clone();
1277
1278 for root_field in structure.get_fields_iter()
1279 {
1280 let field =
1281 self
1282 .generate_field(rust_code, root_field, proc_loc.clone(), Some(enumer.clone()))
1283 .map_err(|e|
1284 format!("{} procedure: '{}', path to label: '{}'", e, proc_name,
1285 error::convert_list(root_field.get_path_to_label()))
1286 )?;
1287
1288 items.push(field);
1289 }
1290
1291 let rcet = RustCodeEnumType::new_fields(proc_rename, items, comment.clone());
1292 enums.push(rcet);
1295 }
1296 }
1297 }
1298
1299 rust_code.add_item(
1300 RustCodeItem::new_enum(enumer.as_ref(),enums)
1301 );
1302
1303 return Ok(());
1304 }
1305
1306 pub
1308 fn get_name(&self) -> &String
1309 {
1310 return &self.name;
1311 }
1312
1313 pub
1315 fn clone_name(&self) ->Arc<String>
1316 {
1317 return self.name.clone();
1318 }
1319
1320 pub
1322 fn new_root_proc(&mut self, proc: Procedure) -> Result<(), String>
1323 {
1324 if self.root_proc.is_none() == false
1325 {
1326 return Err(
1327 format!("procedure: '{}' already exists in root of serializer: '{}'",
1328 proc.get_name(), self.name)
1329 );
1330 }
1331
1332 self.root_proc = Some(Arc::new(proc));
1333
1334 return Ok(());
1335 }
1336
1337 pub
1339 fn new_proc(&mut self, proc: Procedure) -> Result<(), String>
1340 {
1341 if self.procedures.contains_key(proc.get_name()) == true
1342 {
1343 return Err(
1344 format!("procedure: '{}' already exists in serializer: '{}'",
1345 proc.get_name(), self.name)
1346 );
1347 }
1348
1349 self.procedures.insert(proc.clone_name(), Arc::new(proc));
1350
1351 return Ok(());
1352 }
1353
1354 pub
1356 fn symbol_define(&mut self, def: Define) -> Result<(), String>
1357 {
1358 if self.defines.contains_key(def.get_name()) == true
1359 {
1360 return Err(
1361 format!("redefinition of the define label: '{}' in serializer: '{}'",
1362 def.get_name(), self.name)
1363 );
1364 }
1365
1366 self.defines.insert(def.clone_name(), Arc::new(def));
1367
1368 return Ok(());
1369 }
1370
1371 pub
1372 fn symbol_enum_define(&mut self, def: DefineEnum) -> Result<(), String>
1373 {
1374 if self.enum_defines.contains_key(def.get_enum_name()) == true
1375 {
1376 return Err(
1377 format!("redefinition of the enum-define label: '{}' in serializer: '{}'",
1378 def.get_enum_name(), self.name)
1379 );
1380 }
1381
1382 self.enum_defines.insert(def.clone_enum_name(), Arc::new(def));
1383
1384 return Ok(());
1385 }
1386
1387 pub
1389 fn set_root_serialization_struct(&mut self, ser: Structure) -> Result<(), String>
1390 {
1391 if self.root_ser_structure.is_some() == true
1392 {
1393 return Err(
1394 format!("redefinition of the root struct: '{}' in serializer: '{}'",
1395 ser.get_struct_name(), self.name)
1396 );
1397 }
1398 let rc_ser = Arc::new(ser);
1399
1400 self.root_ser_structure = Some(rc_ser.clone());
1401 self.structs.push(rc_ser);
1402
1403 return Ok(());
1404 }
1405
1406 pub
1408 fn add_serialization_struct(&mut self, ser: Structure)
1409 {
1410 self.structs.push(Arc::new(ser));
1411 }
1412
1413 pub
1415 fn add_serialization_enum(&mut self, enm: Enumerator)
1416 {
1417 self.enumeratos.push(Arc::new(enm));
1418 }
1419
1420 pub
1436 fn get_serialization_struct_by_procname(&self, proc_name: &String) -> Result<Arc<Structure>, String>
1437 {
1438 for i in self.structs.iter()
1439 {
1440 if i.contain_proc_name(proc_name) == true
1441 {
1442 return Ok(i.clone());
1443 }
1444 }
1445
1446 return Err(
1447 format!("no struct serializes procedure: '{}' was found in serializer: '{}'",
1448 proc_name, self.get_name())
1449 );
1450 }
1451
1452 pub
1453 fn get_serialization_struct_by_procname_opt(&self, proc_name: &String) -> Option<Arc<Structure>>
1454 {
1455 for i in self.structs.iter()
1456 {
1457 if i.contain_proc_name(proc_name) == true
1458 {
1459 return Some(i.clone());
1460 }
1461 }
1462
1463 return None;
1464 }
1465
1466 pub
1467 fn get_serialization_struct_by_name(&self, struct_name: &str) -> Result<Arc<Structure>, String>
1468 {
1469 for i in self.structs.iter()
1470 {
1471 if i.get_struct_name() == struct_name
1472 {
1473 return Ok(i.clone());
1474 }
1475 }
1476
1477 return Err(
1478 format!("no struct with name: '{}' was found in serializer: '{}'",
1479 struct_name, self.get_name())
1480 );
1481 }
1482
1483 pub
1498 fn get_serialization_enum_by_procname(&self, proc_name: &String) -> Result<&Enumerator, String>
1499 {
1500 for i in self.enumeratos.iter()
1501 {
1502 if i.is_proc_name_presents(proc_name) == true
1503 {
1504 return Ok(i);
1505 }
1506 }
1507
1508 return Err(format!("no enum serializes procedure: '{}' was found in serializer: '{}'", proc_name, self.get_name()));
1509 }
1510
1511 pub
1512 fn get_procedure_by_name(&self, proc_name: &String) -> Option<&Arc<Procedure>>
1513 {
1514 return self.procedures.get(proc_name);
1515 }
1516
1517 pub
1534 fn get_root_ser(&self) -> Option<Arc<Structure>>
1535 {
1536 return self.root_ser_structure.clone();
1537 }
1538
1539 pub
1543 fn get_root_proc(&self) -> Option<Arc<Procedure>>
1544 {
1545 return self.root_proc.clone();
1546 }
1547
1548 pub
1550 fn get_define_list_iter(&self) -> hash_map::Iter<'_, Arc<String>, Arc<Define>>
1551 {
1552 return self.defines.iter();
1553 }
1554
1555 pub
1557 fn get_enum_define_list_iter(&self) -> hash_map::Iter<'_, Arc<String>, Arc<DefineEnum>>
1558 {
1559 return self.enum_defines.iter();
1560 }
1561
1562 pub
1563 fn get_enum_define_value_by_key(&self, key: &String) -> Option<&Arc<DefineEnum>>
1564 {
1565 return self.enum_defines.get(key);
1566 }
1567
1568 pub
1570 fn get_procedure_list_iter(&self) -> hash_map::Iter<'_,Arc<String>, Arc<Procedure>>
1571 {
1572 return self.procedures.iter();
1573 }
1574}
1575
1576#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
1578pub struct DefineEnum
1579{
1580 enum_name:Arc<String>,
1582
1583 enum_defs: IndexSet<String>,
1585
1586 rust_code_gen: RustCodeFields,
1588}
1589
1590impl Hash for DefineEnum
1591{
1592 fn hash<H: Hasher>(&self, state: &mut H)
1593 {
1594 self.enum_name.hash(state);
1595 }
1596}
1597
1598impl PartialEq<str> for DefineEnum
1599{
1600 fn eq(&self, other: &str) -> bool
1601 {
1602 return self.enum_name.as_str() == other;
1603 }
1604}
1605
1606impl PartialEq<String> for DefineEnum
1607{
1608 fn eq(&self, other: &String) -> bool
1609 {
1610 return self.enum_name.as_str() == other.as_str();
1611 }
1612}
1613
1614impl Borrow<str> for DefineEnum
1615{
1616 fn borrow(&self) -> &str
1617 {
1618 return &self.enum_name;
1619 }
1620}
1621
1622impl Borrow<String> for DefineEnum
1623{
1624 fn borrow(&self) -> &String
1625 {
1626 return &self.enum_name;
1627 }
1628}
1629
1630impl fmt::Display for DefineEnum
1631{
1632 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
1633 {
1634 write!(f, "enum_name: '{}', enum_defs: '{}'",
1635 self.enum_name,
1636 self.enum_defs.iter().map(|f| f.as_str()).collect::<Vec<&str>>().join(","),
1637 )
1638 }
1639}
1640
1641impl Clone for DefineEnum
1642{
1643 fn clone(&self) -> Self
1644 {
1645 panic!("Asserion trap: Define must never be cloned! \
1646 Implementation Clone for Define is used to comply \
1647 with compilter requirments.");
1648 }
1649}
1650
1651impl DefineEnum
1652{
1653 pub
1654 fn new(enum_name: String, enum_defs: IndexSet<String>) -> Result<Self, String>
1655 {
1656 if enum_defs.len() == 0
1657 {
1658 return Err(format!("(define-enum \"{}\") is empty!", enum_name));
1659 }
1660
1661 return Ok(
1662 Self
1663 {
1664 enum_name:
1665 Arc::new(enum_name),
1666 enum_defs:
1667 enum_defs,
1668 rust_code_gen:
1669 RustCodeFields::default(),
1670 }
1671 );
1672 }
1673
1674
1675 pub
1676 fn get_enum_name(&self) -> &String
1677 {
1678 return self.enum_name.as_ref();
1679 }
1680
1681 pub
1682 fn get_rust_code_gen(&self) -> &RustCodeFields
1683 {
1684 return &self.rust_code_gen;
1685 }
1686
1687 pub
1688 fn get_rust_code_gen_mut(&mut self) -> &mut RustCodeFields
1689 {
1690 return &mut self.rust_code_gen;
1691 }
1692
1693
1694 pub
1695 fn clone_enum_name(&self) ->Arc<String>
1696 {
1697 return self.enum_name.clone();
1698 }
1699
1700 pub
1701 fn generate_enum_pairs(&self) -> (Vec<Arc<String>>, Vec<Arc<String>>)
1702 {
1703 let mut enum_symbol_pair: Vec<Arc<String>> = Vec::with_capacity(self.enum_defs.len());
1704 let mut enum_symbol: Vec<Arc<String>> = Vec::with_capacity(self.enum_defs.len());
1705
1706 for ed in self.enum_defs.iter()
1707 {
1708 let upper_c = prepare_enum_variant(ed);
1709 let lower_c = some_kind_of_lowercase_first_letter(ed);
1710
1711 enum_symbol_pair.push(Arc::new([self.enum_name.as_ref(), "::", upper_c.as_str()].concat()));
1712 enum_symbol_pair.push(Arc::new([self.enum_name.as_ref(), "::", lower_c.as_str()].concat()));
1713 enum_symbol.push(Arc::new(upper_c.to_string()));
1714 enum_symbol.push(Arc::new(lower_c.to_string()));
1715 }
1716
1717 return (enum_symbol_pair, enum_symbol);
1718 }
1719
1720 pub
1721 fn present(&self, itm: &str) -> bool
1722 {
1723 return self.enum_defs.contains(itm);
1724 }
1725
1726 pub
1727 fn convert_to_dyn_scheme_def(&self, itm: &str) -> Option<&str>
1728 {
1729 for d in self.enum_defs.iter()
1730 {
1731 if prepare_enum_variant(d.as_str()) == itm
1732 {
1733 return Some(d.as_str());
1734 }
1735 }
1736
1737 return None;
1738 }
1739}
1740
1741#[derive(Debug, Default, Serialize, Deserialize)]
1743pub struct Define
1744{
1745 name: Arc<String>,
1747
1748 data: GenericDataTypes,
1750
1751 data_type: ArgDataType,
1753
1754 proc_binds: Option<HashSet<String>>,
1756
1757 comment: Option<String>,
1759}
1760
1761impl fmt::Display for Define
1762{
1763 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
1764 {
1765 write!(f, "symbol: '{}', data: '{}', binds: '{}'",
1766 self.name, self.data,
1767 self.proc_binds
1768 .as_ref()
1769 .map_or(
1770 "UNBIND".to_string(),
1771 |f| f.iter().map(|v| v.as_str()).collect::<Vec<&str>>().join(", ")
1772 )
1773 )
1774 }
1775}
1776
1777impl Hash for Define
1778{
1779 fn hash<H: Hasher>(&self, state: &mut H)
1780 {
1781 self.name.as_ref().hash(state);
1782 }
1783}
1784
1785impl Eq for Define {}
1786
1787impl PartialEq for Define
1788{
1789 fn eq(&self, other: &Self) -> bool
1790 {
1791 return
1792 self.name.as_ref() == other.name.as_ref();
1793 }
1794}
1795
1796impl Borrow<String> for Define
1797{
1798 fn borrow(&self) -> &String
1799 {
1800 return &self.name;
1801 }
1802}
1803
1804impl Borrow<str> for Define
1805{
1806 fn borrow(&self) -> &str
1807 {
1808 return &self.name;
1809 }
1810}
1811
1812impl Clone for Define
1813{
1814 fn clone(&self) -> Self
1815 {
1816 panic!("Asserion trap: Define must never be cloned! \
1817 Implementation Clone for Define is used to comply \
1818 with compilter requirments.");
1819 }
1820}
1821
1822impl Define
1823{
1824 pub
1825 fn new(name: String, dt_type: ArgDataType, data: GenericDataTypes, proc_binds_set: HashSet<String>) -> Self
1826 {
1827 let proc_binds =
1828 if proc_binds_set.len() > 0
1829 {
1830 Some(proc_binds_set)
1831 }
1832 else
1833 {
1834 None
1835 };
1836
1837 return Self{ name: Arc::new(name), data_type: dt_type, data, proc_binds, comment: None };
1838 }
1839
1840 pub
1841 fn clone_name(&self) -> Arc<String>
1842 {
1843 return self.name.clone();
1844 }
1845
1846 pub
1847 fn clone_data(&self) -> GenericDataTypes
1848 {
1849 return self.data.clone();
1850 }
1851 pub
1852 fn set_comment(&mut self, comment: String)
1853 {
1854 self.comment.replace(comment);
1855 }
1856
1857 pub
1858 fn get_name(&self) -> &String
1859 {
1860 return &self.name;
1861 }
1862
1863 pub
1864 fn get_data(&self) -> &GenericDataTypes
1865 {
1866 return &self.data;
1867 }
1868
1869 pub
1870 fn get_binds(&self) -> Option<&HashSet<String>>
1871 {
1872 return self.proc_binds.as_ref();
1873 }
1874
1875 pub
1876 fn get_datatype(&self) -> ArgDataType
1877 {
1878 return self.data_type;
1879 }
1880
1881 pub
1885 fn is_in_proc_scope(&self, proc_name: &String) -> bool
1886 {
1887 if let Some(ref p) = self.proc_binds
1888 {
1889 return p.contains(proc_name);
1890 }
1891 else
1892 {
1893 return true;
1894 }
1895 }
1896}
1897
1898#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
1901pub struct Procedure
1902{
1903 name: Arc<String>,
1905
1906 args: LinkedHashMap<Arc<String>, Arc<Argument>>,
1908
1909 procs: LinkedHashMap<Arc<String>, Arc<ForegnProc>>,
1911
1912 is_empty: bool,
1914}
1915
1916impl PartialEq<str> for Procedure
1917{
1918 fn eq(&self, other: &str) -> bool
1919 {
1920 return self.name.as_str() == other;
1921 }
1922}
1923
1924impl Hash for Procedure
1925{
1926 fn hash<H: Hasher>(&self, state: &mut H)
1927 {
1928 self.name.hash(state);
1929 }
1930}
1931
1932impl Borrow<str> for Procedure
1933{
1934 fn borrow(&self) -> &str
1935 {
1936 return &self.name;
1937 }
1938}
1939
1940impl Borrow<String> for Procedure
1941{
1942 fn borrow(&self) -> &String
1943 {
1944 return &self.name;
1945 }
1946}
1947
1948impl fmt::Display for Procedure
1949{
1950 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
1951 {
1952 write!(f, "name: {}, is_empty: {}, porcs: {}", self.name, self.is_empty,
1953 self.procs.keys().map(|k| k.as_ref().clone()).collect::<Vec<String>>().join(", "))
1954 }
1955}
1956
1957impl Clone for Procedure
1958{
1959 fn clone(&self) -> Self
1960 {
1961 panic!("Asserion trap: Procedure must never be cloned! \
1962 Implementation Clone for Procedure is used to comply \
1963 with compilter requirments.");
1964 }
1965}
1966
1967impl Procedure
1968{
1969 pub const ROOT_PROC_NAME: &'static str = "root_procedure_0000";
1970
1971 pub
1972 fn new(name: String, li: LexerInfo) -> Result<Self, String>
1973 {
1974 if common::contains_printable_all(&name) == false
1975 {
1976 return Err(
1977 format!("in procedure: 'N?A', near: '{}' the procedure name contains non-printable character!", li)
1978 );
1979 }
1980
1981 return Ok(
1982 Self
1983 {
1984 name: Arc::new(name),
1985 args: LinkedHashMap::new(),
1986 procs: LinkedHashMap::new(),
1987 is_empty: false,
1988 }
1989 );
1990 }
1991
1992 pub
1993 fn new_root() -> Self
1994 {
1995 return
1996 Self
1997 {
1998 name: Arc::new(Self::ROOT_PROC_NAME.to_string()),
1999 args: LinkedHashMap::new(),
2000 procs: LinkedHashMap::new(),
2001 is_empty: false,
2002 };
2003 }
2004
2005 pub
2006 fn is_root(&self) -> bool
2007 {
2008 return self.name.as_str() == Self::ROOT_PROC_NAME;
2009 }
2010
2011 pub
2012 fn clone_name(&self) ->Arc<String>
2013 {
2014 return self.name.clone();
2015 }
2016
2017 pub
2018 fn get_arg_by_label(&self, arg_level: &String) -> Option<&Arc<Argument>>
2019 {
2020 return self.args.get(arg_level);
2021 }
2022
2023 pub
2024 fn get_proc_by_label(&self, proc_name: &String) -> Option<&Arc<ForegnProc>>
2025 {
2026 return self.procs.get(proc_name);
2027 }
2028
2029 pub
2030 fn get_name(&self) -> &String
2031 {
2032 return &self.name;
2033 }
2034
2035 pub
2036 fn get_args_iter(&self) -> linked_hash_map::Iter<'_,Arc<String>,Arc<Argument>>
2037 {
2038 return self.args.iter();
2039 }
2040
2041 pub
2042 fn get_args_len(&self) -> usize
2043 {
2044 return self.args.len();
2045 }
2046
2047 pub
2048 fn get_procs_iter(&self) -> linked_hash_map::Iter<'_,Arc<String>,Arc<ForegnProc>>
2049 {
2050 return self.procs.iter();
2051 }
2052
2053 pub
2054 fn get_procs_len(&self) -> usize
2055 {
2056 return self.procs.len();
2057 }
2058
2059 pub
2060 fn get_proc(&self) -> &LinkedHashMap<Arc<String>,Arc<ForegnProc>>
2061 {
2062 return &self.procs;
2063 }
2064
2065 pub
2068 fn add_arg(&mut self, arg: Argument) -> Result<(), String>
2069 {
2070 if self.is_empty == true
2071 {
2072 return Err(
2073 format!("(procedure \"{}\") was explicitly set to empty but expects \
2074 (arg \"{}\") to appear", self.get_name(), arg.get_label())
2075 );
2076 }
2077
2078 let res =
2079 self.args.insert(arg.clone_label(), Arc::new(arg));
2080
2081 if let Some(r) = res
2082 {
2083 return Err(
2084 format!("redefinition of the (arg \"{}\" {:?}) in \
2085 (procedure \"{}\")", r.get_label(), r.arg_data_types, self.get_name())
2086 );
2087 }
2088
2089 return Ok(());
2090 }
2091
2092 pub
2103 fn add_proc(
2104 &mut self,
2105 proc_label: String,
2106 proc_names: HashSet<String>,
2107 proc_allowed_flags: ProcFlags
2108 ) -> Result<(), String>
2109 {
2110 if self.is_empty == true
2111 {
2112 return Err(
2113 format!("procedure: '{}' was explicitly set to be empty, but a \
2114 foreign procedure is added: '{}", self.get_name(), proc_label)
2115 );
2116 }
2117
2118 let label = Arc::new(proc_label);
2119 let fp = ForegnProc::new(label.clone(), proc_names, proc_allowed_flags);
2120
2121 let res = self.procs.insert(label, Arc::new(fp));
2122
2123 if let Some(r) = res
2124 {
2125 return Err(
2126 format!("redefinition of the foreign proc: '{}' in procedure: '{}'",
2127 r.get_label(), self.get_name())
2128 );
2129 }
2130
2131 return Ok(());
2132 }
2133
2134 pub
2137 fn set_empty(&mut self)
2138 {
2139 self.is_empty = true;
2140 }
2141
2142 pub
2144 fn is_empty(&self) -> bool
2145 {
2146 return self.is_empty;
2147 }
2148
2149 pub
2164 fn lookup_procedure(&self, proc_name: &String) -> Option<Arc<ForegnProc>>
2165 {
2166 for (_, p) in self.procs.iter()
2167 {
2168 if p.contains_proc(proc_name) == true
2169 {
2170 return Some(p.clone());
2171 }
2172 }
2173
2174 return None;
2175 }
2176
2177 pub
2178 fn validate(&self, li: LexerInfo) -> Result<(), String>
2179 {
2180 if self.args.is_empty() == true && self.procs.is_empty() == true &&
2181 self.is_empty() == false
2182 {
2183 return Err(
2184 format!("in procedure: '{}', near: '{}' the procedure should either contain \
2185 foreign procs or arg or to be set to empty (procedure_empty)", self.get_name(), li)
2186 );
2187 }
2188 else if (self.args.is_empty() == false || self.procs.is_empty() == false) &&
2189 self.is_empty() == true
2190 {
2191 return Err(
2192 format!("in procedure: '{}', near: '{}' the procedure both contains \
2193 foreign procs or arg and set to be empty (procedure_empty)",
2194 self.get_name(), li)
2195 );
2196 }
2197
2198 return Ok(());
2199 }
2200}
2201
2202
2203#[derive(Debug, Serialize, Deserialize)]
2211pub struct ForegnProc
2212{
2213 label: Arc<String>,
2215
2216 foregn_names: HashSet<String>,
2219
2220 flags: ProcFlags,
2222}
2223
2224impl fmt::Display for ForegnProc
2225{
2226 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
2227 {
2228 write!(f, "[foregn proc] label: '{}'", self.label)
2229 }
2230}
2231
2232impl Eq for ForegnProc {}
2233
2234impl PartialEq for ForegnProc
2235{
2236 fn eq(&self, other: &Self) -> bool
2237 {
2238 self.label == other.label
2239 }
2240}
2241
2242impl Hash for ForegnProc
2243{
2244 fn hash<H: Hasher>(&self, state: &mut H)
2245 {
2246 self.label.hash(state);
2247 }
2248}
2249
2250impl ForegnProc
2251{
2252 pub
2253 fn new(label: Arc<String>, foregn_names: HashSet<String>, flags: ProcFlags,) -> Self
2254 {
2255 return Self {label: label, foregn_names: foregn_names, flags: flags};
2256 }
2257
2258 pub
2259 fn clone_label(&self) -> Arc<String>
2260 {
2261 return self.label.clone();
2262 }
2263
2264 pub
2265 fn get_label(&self) -> &String
2266 {
2267 return &self.label;
2268 }
2269
2270 pub
2273 fn contains_proc(&self, proc_name: &String) -> bool
2274 {
2275 return self.foregn_names.contains(proc_name);
2276 }
2277
2278 pub
2280 fn is_flag_set(&self, flag: ProcFlags) -> bool
2281 {
2282 return self.flags.intersects(flag);
2283 }
2284
2285 pub
2286 fn get_proc_iter(&self) -> std::collections::hash_set::Iter<'_, String>
2287 {
2288 return self.foregn_names.iter();
2289 }
2290}
2291
2292#[derive(Clone, Debug)]
2295pub struct Arg<'t>
2296{
2297 arg_data_types: &'t [ArgDataType],
2299
2300 index: Cell<usize>,
2302
2303 set_enum_bind: Option<&'t String>
2305}
2306
2307impl<'t> Arg<'t>
2308{
2309 fn new(args: &'t [ArgDataType], set_enum_b: Option<&'t String>) -> Arg<'t>
2310 {
2311 return
2312 Self
2313 {
2314 arg_data_types: args,
2315 index: Cell::new(0),
2316 set_enum_bind: set_enum_b
2317 };
2318 }
2319
2320 pub
2323 fn pop_arg(&self) -> Option<&'t ArgDataType>
2324 {
2325 let arg = self.arg_data_types.get(self.index.get());
2326 self.index.set( self.index.get() + 1 );
2327
2328 return arg;
2329 }
2330
2331 pub
2332 fn is_arg_enum_bind(&self) -> bool
2333 {
2334 return self.set_enum_bind.is_some();
2335 }
2336
2337 pub
2338 fn get_arg_enum_bind(&self) -> &String
2339 {
2340 return self.set_enum_bind.as_ref().unwrap();
2341 }
2342}
2343
2344#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
2346pub struct Argument
2347{
2348 label: Arc<String>,
2350 arg_data_types: Vec<ArgDataType>,
2355
2356 set_enum_bind: Option<String>,
2361}
2362
2363impl fmt::Display for Argument
2364{
2365 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
2366 {
2367 write!(f, "label: '{}', datatypes: '{}'",
2368 self.label, self.arg_data_types.iter().map(|d| d.to_string()).collect::<Vec<String>>().join("::"))
2369 }
2370}
2371
2372impl Argument
2373{
2374 fn validate_arg_datatypes(arg_data_types: &[ArgDataType]) -> Result<(), String>
2377 {
2378 let arg0_opt = arg_data_types.get(0);
2379 if arg0_opt.is_none() == true || arg0_opt.unwrap() == &ArgDataType::None
2380 {
2381 return Err(format!("argument validation problem: data type is mising"));
2382 }
2383
2384 if arg0_opt.unwrap().has_subtype() == true
2385 {
2386 return Self::validate_arg_datatypes(&arg_data_types[1..]);
2387 }
2388
2389 return Ok(());
2390 }
2391
2392 pub
2393 fn new(label: Arc<String>, arg_data_types: Vec<ArgDataType>) -> Result<Self, String>
2394 {
2395 Self::validate_arg_datatypes(arg_data_types.as_slice())?;
2397
2398 return Ok(
2399 Self
2400 {
2401 label,
2402 arg_data_types,
2403 set_enum_bind: None,
2404 }
2405 );
2406 }
2407
2408 pub
2409 fn clone_label(&self) ->Arc<String>
2410 {
2411 return self.label.clone();
2412 }
2413
2414 pub
2415 fn get_args(&self) -> Arg<'_>
2416 {
2417 return
2418 Arg::new(
2419 self.arg_data_types.as_slice(),
2420 self.set_enum_bind.as_ref()
2421 );
2422 }
2423
2424 pub
2425 fn set_enum_bind(&mut self, enum_bind: Option<String>) -> Result<(), String>
2426 {
2427 if self.arg_data_types.iter().any(|f| f == &ArgDataType::Enumerator) == true
2428 {
2429 if enum_bind.is_some() == true
2430 {
2431 self.set_enum_bind = enum_bind;
2432 }
2433 else
2434 {
2435 return Err(format!("enum_bind is none, but should be set for emumerator in argument"));
2436 }
2437
2438 return Ok(());
2439 }
2440 else
2441 {
2442 if enum_bind.is_some() == true
2443 {
2444 return Err(format!("enum_bind can only be set to procedure's field of type enum"));
2445 }
2446
2447 return Ok(());
2448 }
2449 }
2450
2451 pub
2452 fn get_label(&self) -> &String
2453 {
2454 return &self.label;
2455 }
2456
2457 pub
2458 fn get_data_base_type(&self) -> &ArgDataType
2459 {
2460 return &self.arg_data_types[0];
2461 }
2462
2463 pub
2464 fn get_data_type(&self) -> &ArgDataType
2465 {
2466 return &self.arg_data_types[0];
2467 }
2468
2469 pub
2470 fn get_collection_type(&self) -> &ArgDataType
2471 {
2472 return &self.arg_data_types[1];
2473 }
2474
2475 pub
2476 fn get_collection_type_sub(&self) -> &ArgDataType
2477 {
2478 return &self.arg_data_types[2];
2479 }
2480
2481 pub
2482 fn get_arg_index(&self, idx: usize) -> Option<&ArgDataType>
2483 {
2484 return self.arg_data_types.get(idx);
2485 }
2486
2487 pub
2488 fn get_enum_bind(&self) -> Option<&String>
2489 {
2490 return self.set_enum_bind.as_ref();
2491 }
2492}
2493
2494