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::serializator::error::SerializationPartialRes;
25use crate::serializator::serializator::*;
26use crate::static_scheme::generator::RustCodeEnumType;
27use crate::{map_new_static_throw_text, ser_partial_throw, static_throw_text, LexerInfo, StaticSchemeError};
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 UInt,
69 Int,
70 LongUint,
71 LongInt,
72 Boolean,
73 Vector,
74 Range,
75 RangeInc,
76 Variable,
77 Entity,
78 Enumerator,
79 AutoType
80}
81
82impl ArgDataType
83{
84 pub fn has_subtype(&self) -> bool
86 {
87 return
88 *self == Self::Vector || *self == Self::Range ||
89 *self == Self::RangeInc || *self == Self::Symbol;
90 }
91}
92
93impl fmt::Display for ArgDataType
94{
95 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
96 {
97 match *self
98 {
99 Self::None => write!(f, "Not Defined"),
100 Self::Symbol => write!(f, "Symbol"),
101 Self::String => write!(f, "String"),
102 Self::UInt => write!(f, "UInt"),
103 Self::Int => write!(f, "Int"),
104 Self::LongInt => write!(f, "LongInt"),
105 Self::LongUint => write!(f, "LongUint"),
106 Self::Boolean => write!(f, "Boolean"),
107 Self::Vector => write!(f, "Vector"),
108 Self::Range => write!(f, "Range"),
109 Self::RangeInc => write!(f, "RangeInc"),
110 Self::Variable => write!(f, "Variable"),
111 Self::Entity => write!(f, "Entity"),
112 Self::Enumerator => write!(f, "Enumerator"),
113 Self::AutoType => write!(f, "Auto-type"),
114 }
115 }
116}
117
118#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
120pub enum GenericDataTypes
121{
122 None,
123 Symbol(Box<GenericDataTypes>, LexerInfo),
124 String(String, LexerInfo),
125 UInt(u64, LexerInfo),
126 Int(i64, LexerInfo),
127 LongUInt(u128, LexerInfo),
128 LongInt(i128, LexerInfo),
129 Boolean(bool, LexerInfo),
130 Variable(String, LexerInfo), Entity(String, LexerInfo), Enumerator(String, String, LexerInfo),
133 Vector(Vec<GenericDataTypes>, LexerInfo),
134 Range(Box<GenericDataTypes>, Box<GenericDataTypes>, LexerInfo),
135 RangeIncl(Box<GenericDataTypes>, Box<GenericDataTypes>, LexerInfo),
136 AnyValWrap(Box<GenericDataTypes>, LexerInfo)
137}
138
139impl Default for GenericDataTypes
140{
141 fn default() -> Self
142 {
143 return Self::None;
144 }
145}
146
147impl GenericDataTypes
148{
149 pub
150 fn get_arg_type(&self) -> ArgDataType
151 {
152 match *self
153 {
154 Self::None => ArgDataType::None,
155 Self::Symbol(_, _) => ArgDataType::Symbol,
156 Self::String(_, _) => ArgDataType::String,
157 Self::UInt(_, _) => ArgDataType::UInt,
158 Self::Int(_, _) => ArgDataType::Int,
159 Self::LongInt(_, _) => ArgDataType::LongInt,
160 Self::LongUInt(_, _) => ArgDataType::LongUint,
161 Self::Boolean(_, _) => ArgDataType::Boolean,
162 Self::Variable(_, _) => ArgDataType::Variable,
163 Self::Entity(_, _) => ArgDataType::Entity,
164 Self::Vector(_, _) => ArgDataType::Vector,
165 Self::Range(_, _, _) => ArgDataType::Range,
166 Self::RangeIncl(_, _, _) => ArgDataType::RangeInc,
167 Self::Enumerator(_, _, _) => ArgDataType::Enumerator,
168 Self::AnyValWrap(_, _) => ArgDataType::AutoType,
169 }
170 }
171}
172
173
174impl fmt::Display for GenericDataTypes
175{
176 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
177 {
178 match *self
179 {
180 Self::None =>
181 write!(f, "None"),
182 Self::Symbol(ref r, ref li) =>
183 write!(f, "Symbol({}: {})", r, li),
184 Self::String(ref r, ref li) =>
185 write!(f, "String({}: {})", r, li),
186 Self::UInt(ref r, ref li) =>
187 write!(f, "UInt({}: {})", r, li),
188 Self::Int(ref r, ref li) =>
189 write!(f, "Int({}: {})", r, li),
190 Self::LongInt(ref r, ref li) =>
191 write!(f, "LongInt({}: {})", r, li),
192 Self::LongUInt(ref r, ref li) =>
193 write!(f, "LongUint({}: {})", r, li),
194 Self::Boolean(ref r, ref li) =>
195 write!(f, "Boolean({}: {})", r, li),
196 Self::Vector(ref r, ref _li) =>
197 {
198 write!(f, "Vector(")?;
199 for i in r.iter()
200 {
201 write!(f, "{}", i)?;
202 }
203 write!(f, ")")
204 },
205 Self::Range(ref l, ref r, ref li) =>
206 write!(f, "Range({}..{}): {}", l, r, li),
207 Self::RangeIncl(ref l, ref r, ref li) =>
208 write!(f, "RangeIncl({}..={}): {}", l, r, li),
209 Self::Variable(ref var, ref li) =>
210 write!(f, "Variable(${}): '{}'", var, li),
211 Self::Entity(ref ent, ref li) =>
212 write!(f, "Entity(@{}): '{}'", ent, li),
213 Self::Enumerator(ref enum_name, ref enum_item, ref li) =>
214 write!(f, "Enumerator({}::{}): '{}'", enum_name, enum_item, li),
215 Self::AnyValWrap(ref anyval, ref li) =>
216 write!(f, "AnyValue({}): '{}'", anyval, li),
217 }
218 }
219}
220
221#[derive(Debug, Serialize, Deserialize)]
224pub struct Serializator
225{
226 name: Arc<String>,
228
229 root_proc: Option<Arc<Procedure>>,
231
232 procedures: HashMap<Arc<String>, Arc<Procedure>>,
234
235 defines: HashMap<Arc<String>, Arc<Define>>,
237
238 enum_defines: HashMap<Arc<String>, Arc<DefineEnum>>,
240
241 root_ser_structure: Option<Arc<Structure>>,
243
244 enumeratos: Vec<Arc<Enumerator>>,
246
247 structs: Vec<Arc<Structure>>,
249
250 file_path: Option<PathBuf>,
252}
253
254impl fmt::Display for Serializator
255{
256 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
257 {
258 write!(f, "{}", self.name)
259 }
260}
261
262impl Clone for Serializator
264{
265 fn clone(&self) -> Self
266 {
267 panic!("Asserion trap: Serializator must never be cloned! \
268 Implementation Clone for Serializator is used to comply \
269 with compilter requirments.");
270 }
281}
282
283impl Serializator
284{
285 pub const SERIALIZATOR_FROM_MEMORY_PATH: &'static str = "from memory";
287
288 pub
291 fn new(name: String) -> Self
292 {
293 return
294 Self
295 {
296 name: Arc::new(name),
297 root_proc: None,
298 procedures: HashMap::new(),
299 defines: HashMap::new(),
300 enum_defines: HashMap::new(),
301 root_ser_structure: None,
302 enumeratos: Vec::new(),
303 structs: Vec::new(),
304 file_path: None,
305 };
306 }
307
308 pub
311 fn set_file_path(&mut self, file_path: Option<PathBuf>)
312 {
313 self.file_path = file_path;
314 }
315
316 pub
319 fn get_file_path(&self) -> Option<&PathBuf>
320 {
321 return self.file_path.as_ref();
322 }
323
324 pub
327 fn get_file_path_string_safe(&self) -> String
328 {
329 return
330 self.file_path
331 .as_ref()
332 .map_or(
333 Self::SERIALIZATOR_FROM_MEMORY_PATH.to_string(),
334 |s| s.display().to_string()
335 );
336 }
337
338 pub
353 fn get_defines_by_proc_dt(&self, proc_name: &String, arg_dt: ArgDataType) -> Vec<Arc<Define>>
354 {
355 let mut defs: Vec<Arc<Define>> = Vec::new();
356
357 for (_defn, defk) in self.defines.iter()
358 {
359 if defk.is_in_proc_scope(proc_name) == true && defk.get_data().get_arg_type() == arg_dt
360 {
361 defs.push(defk.clone());
362 }
363 }
364
365 return defs;
366 }
367
368 pub
388 fn resolve_path_to_struct(
389 &self,
390 source:Arc<Procedure>,
391 path_to_label: &[String],
392 full_path_to_lbl: &[String],
393 ) -> StaticSchemeRes<(Arc<Structure>,Arc<Procedure>)>
394 {
395 let p = &path_to_label[0];
397
398 match source.procs.get(p)
400 {
401 Some(r) =>
402 {
403 if r.foregn_names.len() > 1
406 {
407 return Err(
408 StaticSchemeError
409 ::new_text(
410 format!("found item at: '{}', full path: '{}' is not a structure because allowes \
411 more than one variant: '{}'", p, error::convert_list(full_path_to_lbl),
412 error::convert_hashset(&r.foregn_names, " "))
413 )
414 );
415 }
416
417 let foregn_names: Vec<String> =
419 r.foregn_names.iter().map(|f| f.clone()).collect();
420
421 let proc =
424 self
425 .procedures
426 .get(&foregn_names[0])
427 .ok_or_else(||
428 StaticSchemeError
429 ::new_text(
430 format!("fprocedure named: '{}', label path: '{}' does not exist in list of \
431 procedures", &foregn_names[0], error::convert_list(full_path_to_lbl))
432 )
433 )?
434 .clone();
435
436 if path_to_label.len() > 1
438 {
439 return self.resolve_path_to_struct(proc, &path_to_label[1..], full_path_to_lbl);
440 }
441 else
442 {
443 return
445 Ok((self.get_serialization_struct_by_procname(proc.get_name())?, proc));
446 }
447 }
448 None =>
449 {
450 return Err(
452 StaticSchemeError
453 ::new_text(format!("path label not found: '{}', on chain: '{}', procedure \
454 endpoint: '{}' for structure", p, error::convert_list(full_path_to_lbl), source.get_name()))
455 );
456 },
457 }
458 }
459
460 pub
470 fn resolve_path_to_proc(
471 &self,
472 source:Arc<Procedure>,
473 path_to_label: &[String],
474 full_path_to_lbl: &[String],
475 ) -> StaticSchemeRes<(Option<Arc<Structure>>,Arc<Procedure>)>
476 {
477 let p = &path_to_label[0];
479
480 match source.procs.get(p)
482 {
483 Some(r) =>
484 {
485 if r.foregn_names.len() > 1
488 {
489 static_throw_text!("found item at: '{}', full path: '{}' is not a structure because allowes \
490 more than one variant: '{}'", p, error::convert_list(full_path_to_lbl),
491 error::convert_hashset(&r.foregn_names, " "));
492 }
493
494 let foregn_names: Vec<String> =
496 r.foregn_names.iter().map(|f| f.clone()).collect();
497
498 let proc =
501 self.procedures
502 .get(&foregn_names[0])
503 .ok_or_else(||
504 map_new_static_throw_text!("procedure named: '{}', label path: '{}' does not exist in list of \
505 procedures, in source procedure '{}'",
506 &foregn_names[0], error::convert_list(full_path_to_lbl), source.get_name())
507 )?
508 .clone();
509
510 if path_to_label.len() > 1
512 {
513 return self.resolve_path_to_proc(proc, &path_to_label[1..], full_path_to_lbl);
514 }
515 else
516 {
517 return
519 Ok((self.get_serialization_struct_by_procname_opt(proc.get_name()), proc));
520 }
521 }
522 None =>
523 {
524 static_throw_text!("path label not found: '{}', on chain: '{}', procedure \
526 endpoint: '{}' for structure", p, error::convert_list(full_path_to_lbl), source.get_name());
527 },
528 }
529 }
530
531 fn find_enum_by_procs(&self, foreign_proc: &ForegnProc) -> StaticSchemeRes<Arc<Enumerator>>
551 {
552 let mut cnt: usize = 0;
553 let mut last_found: Option<Arc<Enumerator>> = None;
554
555 'ext: for enm in self.enumeratos.iter()
556 {
557 let map: HashSet<String> =
558 enm.get_enum_procs_list()
559 .iter()
560 .map(|p| p.clone())
561 .collect();
562
563 for for_proc_name in foreign_proc.foregn_names.iter()
564 {
565 if map.contains(for_proc_name) == false
566 {
567 cnt = 0;
568 continue 'ext;
569 }
570
571 cnt += 1;
572 }
573
574 if cnt == map.len()
575 {
576 return Ok(enm.clone());
577 }
578 else
579 {
580 cnt = 0;
581
582 match last_found
583 {
584 Some(ref r) =>
585 {
586 if r.get_enum_procs_list().len() > map.len()
587 {
588 last_found = Some(enm.clone());
589 }
590 },
591 None =>
592 {
593 last_found = Some(enm.clone());
594 }
595 }
596 }
597 }
598
599 if let Some(r) = last_found
600 {
601 return Ok(r);
602 }
603 else
604 {
605 static_throw_text!("can not find enum which serializes: '{}'",
606 error::convert_hashset(&foreign_proc.foregn_names, " "));
607 }
608
609 }
665
666 pub
686 fn resolve_path_to_enum(
687 &self,
688 source:Arc<Procedure>,
689 path_to_label: &[String],
690 full_path_to_lbl: &[String],
691 ) -> StaticSchemeRes<(Arc<Enumerator>,Arc<Procedure>)>
692 {
693 let p = &path_to_label[0];
695
696 match source.procs.get(p)
698 {
699 Some(r) =>
700 {
701 if path_to_label.len() == 1
703 {
704 let enumer = self.find_enum_by_procs(r)?;
705
706 return Ok((enumer, source));
707 }
708
709 if r.foregn_names.len() > 1
712 {
713 static_throw_text!("found item at: '{}', full path: '{}' is not a structure because allowes \
714 more than one variant: '{}'", p, error::convert_list(full_path_to_lbl),
715 error::convert_hashset(&r.foregn_names, " "));
716 }
717
718 let foregn_names: Vec<String> =
720 r.foregn_names.iter().map(|f| f.clone()).collect();
721
722 let proc =
725 self.procedures
726 .get(&foregn_names[0])
727 .ok_or_else(||
728 map_new_static_throw_text!("procedure named: '{}', label path: '{}' does not exist in list of \
729 procedures", &foregn_names[0], error::convert_list(full_path_to_lbl))
730 )?
731 .clone();
732
733 return self.resolve_path_to_enum(proc, &path_to_label[1..], full_path_to_lbl);
735 },
736 None =>
737 {
738 static_throw_text!("path label not found: '{}', on chain: '{}', procedure \
739 endpoint: '{}' for enumerator", p, error::convert_list(full_path_to_lbl), source.get_name());
740 }
741 }
742 }
743
744 pub
763 fn resolve_path_to_arg(
764 &self,
765 source:Arc<Procedure>,
766 path_to_label: &[String],
767 full_path_to_lbl: &[String]
768 ) -> StaticSchemeRes<Arc<Argument>>
769 {
770 let p = &path_to_label[0];
772
773 if path_to_label.len() == 1
775 {
776 let arg =
777 source.args.get(p)
778 .ok_or_else(||
779 map_new_static_throw_text!("argument labeled as: '{}' was not found on path: '{}'",
780 p, error::convert_list(full_path_to_lbl))
781 )?
782 .clone();
783
784 return Ok(arg)
785 }
786 else
787 {
788 match source.procs.get(p)
790 {
791 Some(r) =>
792 {
793 if r.foregn_names.len() > 1
796 {
797 static_throw_text!("found item at: '{}', full path: '{}' is not a structure because allowes \
798 more than one variant: '{}'", p, error::convert_list(full_path_to_lbl),
799 error::convert_hashset(&r.foregn_names, " "));
800 }
801
802 let foregn_names: Vec<String> =
804 r.foregn_names.iter().map(|f| f.clone()).collect();
805
806 let proc =
809 self.procedures
810 .get(&foregn_names[0])
811 .ok_or_else(||
812 map_new_static_throw_text!("procedure named: '{}', label path: '{}' does not exist in list of \
813 procedures", &foregn_names[0], error::convert_list(full_path_to_lbl))
814 )?
815 .clone();
816
817 if path_to_label.len() > 1
818 {
819 return self.resolve_path_to_arg(proc, &path_to_label[1..], full_path_to_lbl);
820 }
821 else
822 {
823 static_throw_text!("endpoint is not an argument, last path: '{}', full path: '{}' \
824 procedure name: '{}'", p, error::convert_list(full_path_to_lbl), proc.get_name());
825 }
826 }
827 None =>
828 {
829 static_throw_text!("path label not found: '{}', on chain: '{}', procedure \
830 endpoint: '{}' for argument", p, error::convert_list(full_path_to_lbl), source.get_name());
831 },
832 }
833 }
834 }
835
836 pub
851 fn generate_rust_code(&self, rust_code: &mut RustCode) -> StaticSchemeRes<()>
852 {
853 for (_, de) in self.enum_defines.iter()
855 {
856 let items: Vec<RustCodeEnumType> =
857 de
858 .enum_defs
859 .iter()
860 .map(|itm| {
861 RustCodeEnumType::Empty(prepare_enum_variant(itm.as_str()), None)
862 }
863 )
864 .collect();
865
866 rust_code
867 .add_item(
868 RustCodeItem
869 ::new_enum_arg(de.get_enum_name().as_str(), de.get_rust_code_gen(), items)
870 );
871 }
872
873 for (_, de) in self.defines.iter()
875 {
876 let def = RustCodeDefineType::try_from(de.get_data())?;
877
878 rust_code.add_item(RustCodeItem::new_define(de.get_name().as_str(), def, de.comment.clone()));
879 }
880
881 let cur_set_int =
883 self
884 .get_root_ser()
885 .ok_or_else(||
886 map_new_static_throw_text!(
887 "in file: '{}', root serialization is empty, nothing to do in '{}'",
888 self.get_file_path_string_safe(),self.get_name()
889 )
890 )?;
891
892 let cur_proc_int =
894 self.get_root_proc()
895 .ok_or_else(||
896 map_new_static_throw_text!(
897 "in file: '{}', root procedure is empty, nothing to do in '{}'",
898 self.get_file_path_string_safe(),self.get_name()
899 )
900 )?;
901
902 self.generate_rust_struct(rust_code, cur_set_int.clone(), cur_proc_int, true)
904 .map_err(|e|
905 map_new_static_throw_text!("generating Rust formatted structs failed: {}", e)
906 )?;
907
908 return Ok(());
909 }
910
911 fn generate_rust_struct(
935 &self,
936 rust_code: &mut RustCode,
937 cur_set_int: Arc<Structure>,
938 cur_proc_int: Arc<Procedure>,
939 is_root: bool,
940 ) -> StaticSchemeRes<()>
941 {
942 let mut fields: Vec<RustCodeItemStruct> = Vec::with_capacity(cur_set_int.get_fields_len());
943
944 let field_first =
945 match cur_set_int.get_first_field()
946 {
947 Some(fdecl) =>
948 {
949 fdecl.get_data_type() == &FieldTypes::Enum && fdecl.get_field_name().is_none() == true
950 },
951 None => false
952 };
953
954 if is_root == true &&
955 cur_set_int.get_fields_len() == 1 &&
956 field_first == true
957 {
958 let field = cur_set_int.get_first_field().unwrap();
959
960 if field.is_optional() == true
962 {
963 static_throw_text!("(root) procedure: '{}', field path: '{}' is 'optional', but anonymous \
964 field can not be optional in this case", cur_proc_int.get_name(),
965 error::convert_list(field.get_path_to_label()));
966 }
967
968 let _ =
971 self
972 .generate_field(rust_code, field, cur_proc_int.clone(), None)
973 .map_err(|e|
974 map_new_static_throw_text!("{} procedure: '{}', path to label: '{}'", e, cur_proc_int.get_name(),
975 error::convert_list(field.get_path_to_label()))
976 )?;
977
978 }
979 else
980 {
981 for root_field in cur_set_int.get_fields_iter()
983 {
984 let field =
985 self
986 .generate_field(rust_code, root_field, cur_proc_int.clone(), None)
987 .map_err(|e|
988 map_new_static_throw_text!("{} procedure: '{}', path to label: '{}'", e, cur_proc_int.get_name(),
989 error::convert_list(root_field.get_path_to_label()))
990 )?;
991
992 fields.push(field);
993 }
994
995 let rci =
996 RustCodeItem::new_struct(
997 cur_set_int.as_ref(),
998 fields,
999 is_root,
1000 );
1001
1002 rust_code.add_item(rci);
1003 }
1004
1005 return Ok(());
1006 }
1007
1008 pub
1029 fn generate_field_data_type(
1030 &self,
1031 rust_code: &mut RustCode,
1032 field: &FieldDecl,
1033 cur_proc_int:Arc<Procedure>,
1034 cur_enumer: Option<Arc<Enumerator>>
1035 ) -> StaticSchemeRes<RustCodeItemDataType>
1036 {
1037 let field_datatype =
1038 match field.get_data_type()
1039 {
1040 FieldTypes::String =>
1041 RustCodeItemDataType::String,
1042 FieldTypes::Boolean =>
1043 RustCodeItemDataType::Bool,
1044 FieldTypes::Int =>
1045 RustCodeItemDataType::Int(field.get_int_width()),
1046 FieldTypes::UInt =>
1047 RustCodeItemDataType::Uint(field.get_int_width()),
1048 FieldTypes::LongInt =>
1049 RustCodeItemDataType::Int(field.get_int_width()),
1050 FieldTypes::LongUInt =>
1051 RustCodeItemDataType::Uint(field.get_int_width()),
1052 FieldTypes::AnyType =>
1053 {
1054 rust_code.set_field_any(8);
1069
1070 RustCodeItemDataType::AnyType
1071 },
1072 FieldTypes::Range =>
1073 {
1074 let foreign_arg =
1075 self.resolve_path_to_arg(cur_proc_int.clone(), field.get_path_to_label(),
1076 field.get_path_to_label())?;
1077
1078
1079 let sd_type =
1080 match foreign_arg.get_collection_type()
1081 {
1082 ArgDataType::UInt =>
1083 RustCodeItemDataType::Uint(field.get_int_width()),
1084 ArgDataType::Int =>
1085 RustCodeItemDataType::Int(field.get_int_width()),
1086 _ =>
1087 static_throw_text!("unexpected inner type for <range>, type: '{}'",
1088 foreign_arg.get_collection_type())
1089 };
1090
1091 RustCodeItemDataType::Range(Box::new(sd_type))
1092 },
1093 FieldTypes::RangeInc =>
1094 {
1095 let foreign_arg =
1096 self.resolve_path_to_arg(cur_proc_int.clone(), field.get_path_to_label(),
1097 field.get_path_to_label())?;
1098
1099 let sd_type =
1100 match foreign_arg.get_collection_type()
1101 {
1102 ArgDataType::UInt =>
1103 RustCodeItemDataType::Uint(field.get_int_width()),
1104 ArgDataType::Int =>
1105 RustCodeItemDataType::Int(field.get_int_width()),
1106 _ =>
1107 static_throw_text!("unexpected inner type for <rangeinc>, type: '{}'",
1108 foreign_arg.get_collection_type())
1109 };
1110
1111 RustCodeItemDataType::RangeInclusive(Box::new(sd_type))
1112 },
1113 FieldTypes::Struct =>
1114 {
1115 let (foregn_struct, foregn_proc) =
1116 self.resolve_path_to_struct(cur_proc_int.clone(), field.get_path_to_label(),
1117 field.get_path_to_label())?;
1118
1119 self.generate_rust_struct(
1120 rust_code,
1121 foregn_struct.clone(),
1122 foregn_proc,
1123 false
1124 )?;
1125
1126 RustCodeItemDataType::Struct(foregn_struct.get_struct_name().get_name_1().to_string())
1127 },
1128 FieldTypes::Vector =>
1129 {
1130 let inner_type =
1131 match field.get_data_inner_type()
1132 {
1133 FieldTypes::AnyType =>
1134 {
1135 rust_code.set_field_any(8);
1136
1137 RustCodeItemDataType::AnyType
1138 },
1139 FieldTypes::Struct =>
1140 {
1141 let (foregn_struct, foregn_proc) =
1142 self.resolve_path_to_struct(cur_proc_int.clone(), field.get_path_to_label(),
1143 field.get_path_to_label())?;
1144
1145 self.generate_rust_struct(rust_code, foregn_struct.clone(),
1146 foregn_proc, false)?;
1147
1148 RustCodeItemDataType::Struct(foregn_struct.get_struct_name().get_name_1().to_string())
1149 },
1150 FieldTypes::ArgEnum =>
1151 {
1152 let foreign_arg =
1153 self.resolve_path_to_arg(cur_proc_int.clone(), field.get_path_to_label(),
1154 field.get_path_to_label())?;
1155
1156
1157 if *foreign_arg.get_data_type() == ArgDataType::Enumerator
1158 {
1159 static_throw_text!("argument on the path: '{}' is not defined as `enumerator`",
1160 field.get_path_to_label().join("/"));
1161 }
1162
1163 match field.get_arg_enum_title()
1164 {
1165 Some(r) =>
1166 {
1167 let _ =
1168 self.enum_defines
1169 .get(r)
1170 .ok_or_else(||
1171 map_new_static_throw_text!("can not find argument enum name: '{}'", r)
1172 );
1173
1174 RustCodeItemDataType::Enum(r.clone())
1175 },
1176 None =>
1177 {
1178 static_throw_text!("enum name was not set, field: '{}'",
1179 field.get_field_name_safe())
1180 }
1181 }
1182 },
1183 FieldTypes::Enum =>
1184 {
1185 let (enumer, proced) =
1186 self.resolve_path_to_enum(cur_proc_int.clone(), field.get_path_to_label(),
1187 field.get_path_to_label())?;
1188
1189 if cur_enumer.is_some() == true && enumer.as_ref() == cur_enumer.as_ref().unwrap().as_ref()
1190 {
1191 RustCodeItemDataType::Enum(enumer.get_enum_label().clone())
1192 }
1193 else
1194 {
1195 self.generate_rust_enum(rust_code, enumer.clone(), proced)?;
1197
1198 RustCodeItemDataType::Enum(enumer.get_enum_label().clone())
1199 }
1200 },
1201 FieldTypes::Range =>
1202 {
1203 let foreign_arg =
1204 self.resolve_path_to_arg(cur_proc_int.clone(), field.get_path_to_label(),
1205 field.get_path_to_label())?;
1206
1207 let sd_type =
1208 match foreign_arg.get_collection_type()
1209 {
1210 ArgDataType::UInt =>
1211 RustCodeItemDataType::Uint(field.get_int_width()),
1212 ArgDataType::Int =>
1213 RustCodeItemDataType::Int(field.get_int_width()),
1214 _ =>
1215 static_throw_text!("unexpected inner type for <range>, type: '{}'",
1216 foreign_arg.get_collection_type())
1217 };
1218
1219 RustCodeItemDataType::Range(Box::new(sd_type))
1220 },
1221 FieldTypes::RangeInc =>
1222 {
1223 let foreign_arg =
1224 self.resolve_path_to_arg(cur_proc_int.clone(), field.get_path_to_label(),
1225 field.get_path_to_label())?;
1226
1227 let sd_type =
1228 match foreign_arg.get_collection_type()
1229 {
1230 ArgDataType::UInt =>
1231 RustCodeItemDataType::Uint(field.get_int_width()),
1232 ArgDataType::Int =>
1233 RustCodeItemDataType::Int(field.get_int_width()),
1234 _ =>
1235 static_throw_text!("unexpected inner type for <rangeinc>, type: '{}'",
1236 foreign_arg.get_collection_type())
1237 };
1238
1239 RustCodeItemDataType::RangeInclusive(Box::new(sd_type))
1240 },
1241 FieldTypes::String =>
1242 RustCodeItemDataType::String,
1243 FieldTypes::Boolean =>
1244 RustCodeItemDataType::Bool,
1245 FieldTypes::Int =>
1246 RustCodeItemDataType::Int(field.get_int_width()),
1247 FieldTypes::UInt =>
1248 RustCodeItemDataType::Uint(field.get_int_width()),
1249 FieldTypes::LongInt =>
1250 RustCodeItemDataType::Int(field.get_int_width()),
1251 FieldTypes::LongUInt =>
1252 RustCodeItemDataType::Uint(field.get_int_width()),
1253 FieldTypes::None =>
1254 static_throw_text!("can not serialize field with type None"),
1255 FieldTypes::Optional =>
1256 static_throw_text!("can not serialize field with type Optional"),
1257 FieldTypes::Vector =>
1258 static_throw_text!("field with vector in vector is not allowed"),
1259 };
1260
1261 RustCodeItemDataType::Vector(Box::new(inner_type), field.get_vector_serial_type())
1262 },
1263 FieldTypes::Enum =>
1264 {
1265 let (enumer, proced) =
1267 self.resolve_path_to_enum(cur_proc_int.clone(), field.get_path_to_label(),
1268 field.get_path_to_label())?;
1269
1270 self.generate_rust_enum(rust_code, enumer.clone(), proced)?;
1271
1272 RustCodeItemDataType::Enum(enumer.get_enum_label().clone())
1273 },
1274 FieldTypes::ArgEnum =>
1275 {
1276 let foreign_arg =
1277 self.resolve_path_to_arg(cur_proc_int.clone(), field.get_path_to_label(),
1278 field.get_path_to_label())?;
1279
1280 if *foreign_arg.get_data_type() != ArgDataType::Enumerator
1281 {
1282 static_throw_text!("argument on the path: '{}' is not defined as `enumerator`",
1283 field.get_path_to_label().join("/"));
1284 }
1285
1286 match field.get_arg_enum_title()
1287 {
1288 Some(r) =>
1289 {
1290 let _ =
1291 self.enum_defines
1292 .get(r)
1293 .ok_or_else(||
1294 map_new_static_throw_text!("can not find argument enum name: '{}'", r)
1295 );
1296
1297 RustCodeItemDataType::Enum(r.clone())
1298 },
1299 None =>
1300 {
1301 static_throw_text!("enum name was not set, field: '{}'",
1302 field.get_field_name_safe())
1303 }
1304 }
1305 },
1306 FieldTypes::None =>
1307 static_throw_text!("can not serialize field with type None"),
1308 FieldTypes::Optional =>
1309 static_throw_text!("can not serialize field with type Optional"),
1310 };
1311
1312
1313 return Ok(field_datatype);
1314 }
1315
1316 fn generate_field(
1339 &self,
1340 rust_code: &mut RustCode,
1341 field: &FieldDecl,
1342 cur_proc_int: Arc<Procedure>,
1343 cur_enumer: Option<Arc<Enumerator>>
1344 ) -> StaticSchemeRes<RustCodeItemStruct>
1345 {
1346 return
1347 Ok(
1348 RustCodeItemStruct::new(field.get_field_name(), field.is_optional(),
1349 field.get_field_comment(),
1350 self.generate_field_data_type(rust_code, field, cur_proc_int, cur_enumer)?)
1351 );
1352 }
1353
1354 fn generate_rust_enum(
1379 &self,
1380 rust_code: &mut RustCode,
1381 enumer:Arc<Enumerator>,
1382 _proced:Arc<Procedure>
1383 ) -> StaticSchemeRes<()>
1384 {
1385 let mut enums: Vec<RustCodeEnumType> = Vec::with_capacity(enumer.get_enum_opts_len());
1387
1388 for enm in enumer.get_enum_opts_iter()
1390 {
1391 match enm
1392 {
1393 EnumOpt::Anonymous{ proc_rename, comment, .. } =>
1395 {
1396 let rcet = RustCodeEnumType::new_anon(proc_rename, comment.clone());
1397
1398 enums.push(rcet);
1399 },
1400 EnumOpt::Vector{ proc_name, proc_rename, fields, comment } =>
1402 {
1403 let mut items: Vec<RustCodeItemDataType> = Vec::with_capacity(fields.len());
1405
1406 let proc_loc =
1408 self.procedures
1409 .get(proc_name)
1410 .ok_or_else(||
1411 map_new_static_throw_text!("procedure named: '{}', does not exist in list of \
1412 procedures while serializing enum {} -> {}", proc_name, proc_name, proc_rename)
1413 )?
1414 .clone();
1415
1416 for field in fields.iter()
1417 {
1418 let field =
1419 self.generate_field_data_type(rust_code, field, proc_loc.clone(), Some(enumer.clone()))?;
1420
1421 items.push(field);
1422 }
1423
1424 let rcet = RustCodeEnumType::new_vec(proc_rename, items, comment.clone());
1425
1426 enums.push(rcet);
1427 },
1428 EnumOpt::Structure { proc_name, proc_rename, structure, comment } =>
1430 {
1431 let mut items: Vec<RustCodeItemStruct> = Vec::with_capacity(structure.get_fields_len());
1433
1434 let proc_loc =
1436 self.procedures
1437 .get(proc_name)
1438 .ok_or_else(||
1439 map_new_static_throw_text!("procedure named: '{}', does not exist in list of \
1440 procedures while serializing enum {} -> {}", proc_name, proc_name, proc_rename)
1441 )?
1442 .clone();
1443
1444 for root_field in structure.get_fields_iter()
1445 {
1446 let field =
1447 self.generate_field(rust_code, root_field, proc_loc.clone(), Some(enumer.clone()))
1448 .map_err(|e|
1449 map_new_static_throw_text!("{} procedure: '{}', path to label: '{}'", e, proc_name,
1450 error::convert_list(root_field.get_path_to_label()))
1451 )?;
1452
1453 items.push(field);
1454 }
1455
1456 let rcet = RustCodeEnumType::new_fields(proc_rename, items, comment.clone());
1457 enums.push(rcet);
1460 }
1461 }
1462 }
1463
1464 rust_code.add_item(
1465 RustCodeItem::new_enum(enumer.as_ref(),enums)
1466 );
1467
1468 return Ok(());
1469 }
1470
1471 pub
1473 fn get_name(&self) -> &String
1474 {
1475 return &self.name;
1476 }
1477
1478 pub
1480 fn clone_name(&self) ->Arc<String>
1481 {
1482 return self.name.clone();
1483 }
1484
1485 pub
1487 fn new_root_proc(&mut self, proc: Procedure) -> StaticSchemeRes<()>
1488 {
1489 if self.root_proc.is_none() == false
1490 {
1491 static_throw_text!("procedure: '{}' already exists in root of serializer: '{}'",
1492 proc.get_name(), self.name);
1493 }
1494
1495 self.root_proc = Some(Arc::new(proc));
1496
1497 return Ok(());
1498 }
1499
1500 pub
1502 fn new_proc(&mut self, proc: Procedure) -> StaticSchemeRes<()>
1503 {
1504 if self.procedures.contains_key(proc.get_name()) == true
1505 {
1506 static_throw_text!("procedure: '{}' already exists in serializer: '{}'",
1507 proc.get_name(), self.name);
1508 }
1509
1510 self.procedures.insert(proc.clone_name(), Arc::new(proc));
1511
1512 return Ok(());
1513 }
1514
1515 pub
1517 fn symbol_define(&mut self, def: Define) -> StaticSchemeRes<()>
1518 {
1519 if self.defines.contains_key(def.get_name()) == true
1520 {
1521 static_throw_text!("redefinition of the define label: '{}' in serializer: '{}'",
1522 def.get_name(), self.name);
1523 }
1524
1525 self.defines.insert(def.clone_name(), Arc::new(def));
1526
1527 return Ok(());
1528 }
1529
1530 pub
1531 fn symbol_enum_define(&mut self, def: DefineEnum) -> StaticSchemeRes<()>
1532 {
1533 if self.enum_defines.contains_key(def.get_enum_name()) == true
1534 {
1535 static_throw_text!("redefinition of the enum-define label: '{}' in serializer: '{}'",
1536 def.get_enum_name(), self.name);
1537 }
1538
1539 self.enum_defines.insert(def.clone_enum_name(), Arc::new(def));
1540
1541 return Ok(());
1542 }
1543
1544 pub
1546 fn set_root_serialization_struct(&mut self, ser: Structure) -> StaticSchemeRes<()>
1547 {
1548 if self.root_ser_structure.is_some() == true
1549 {
1550 static_throw_text!("redefinition of the root struct: '{}' in serializer: '{}'",
1551 ser.get_struct_name(), self.name);
1552 }
1553 let rc_ser = Arc::new(ser);
1554
1555 self.root_ser_structure = Some(rc_ser.clone());
1556 self.structs.push(rc_ser);
1557
1558 return Ok(());
1559 }
1560
1561 pub
1563 fn add_serialization_struct(&mut self, ser: Structure)
1564 {
1565 self.structs.push(Arc::new(ser));
1566 }
1567
1568 pub
1570 fn add_serialization_enum(&mut self, enm: Enumerator)
1571 {
1572 self.enumeratos.push(Arc::new(enm));
1573 }
1574
1575 pub
1591 fn get_serialization_struct_by_procname(&self, proc_name: &String) -> StaticSchemeRes<Arc<Structure>>
1592 {
1593 for i in self.structs.iter()
1594 {
1595 if i.contain_proc_name(proc_name) == true
1596 {
1597 return Ok(i.clone());
1598 }
1599 }
1600
1601 static_throw_text!("no struct serializes procedure: '{}' was found in serializer: '{}'",
1602 proc_name, self.get_name());
1603 }
1604
1605 pub
1606 fn get_serialization_struct_by_procname_opt(&self, proc_name: &String) -> Option<Arc<Structure>>
1607 {
1608 for i in self.structs.iter()
1609 {
1610 if i.contain_proc_name(proc_name) == true
1611 {
1612 return Some(i.clone());
1613 }
1614 }
1615
1616 return None;
1617 }
1618
1619 pub
1620 fn get_serialization_struct_by_name(&self, struct_name: &str) -> StaticSchemeRes<Arc<Structure>>
1621 {
1622 for i in self.structs.iter()
1623 {
1624 if i.get_struct_name() == struct_name
1625 {
1626 return Ok(i.clone());
1627 }
1628 }
1629
1630 static_throw_text!("no struct with name: '{}' was found in serializer: '{}'",
1631 struct_name, self.get_name());
1632 }
1633
1634 pub
1649 fn get_serialization_enum_by_procname(&self, proc_name: &String) -> SerializationPartialRes<&Enumerator>
1650 {
1651 for i in self.enumeratos.iter()
1652 {
1653 if i.is_proc_name_presents(proc_name) == true
1654 {
1655 return Ok(i);
1656 }
1657 }
1658
1659 ser_partial_throw!("no enum serializes procedure: '{}' was found in serializer: '{}'", proc_name, self.get_name());
1660 }
1661
1662 pub
1663 fn get_procedure_by_name(&self, proc_name: &String) -> Option<&Arc<Procedure>>
1664 {
1665 return self.procedures.get(proc_name);
1666 }
1667
1668 pub
1685 fn get_root_ser(&self) -> Option<Arc<Structure>>
1686 {
1687 return self.root_ser_structure.clone();
1688 }
1689
1690 pub
1694 fn get_root_proc(&self) -> Option<Arc<Procedure>>
1695 {
1696 return self.root_proc.clone();
1697 }
1698
1699 pub
1701 fn get_define_list_iter(&self) -> hash_map::Iter<'_, Arc<String>, Arc<Define>>
1702 {
1703 return self.defines.iter();
1704 }
1705
1706 pub
1708 fn get_enum_define_list_iter(&self) -> hash_map::Iter<'_, Arc<String>, Arc<DefineEnum>>
1709 {
1710 return self.enum_defines.iter();
1711 }
1712
1713 pub
1714 fn get_enum_define_value_by_key(&self, key: &String) -> Option<&Arc<DefineEnum>>
1715 {
1716 return self.enum_defines.get(key);
1717 }
1718
1719 pub
1721 fn get_procedure_list_iter(&self) -> hash_map::Iter<'_,Arc<String>, Arc<Procedure>>
1722 {
1723 return self.procedures.iter();
1724 }
1725}
1726
1727#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
1729pub struct DefineEnum
1730{
1731 enum_name:Arc<String>,
1733
1734 enum_defs: IndexSet<String>,
1736
1737 rust_code_gen: RustCodeFields,
1739}
1740
1741impl Hash for DefineEnum
1742{
1743 fn hash<H: Hasher>(&self, state: &mut H)
1744 {
1745 self.enum_name.hash(state);
1746 }
1747}
1748
1749impl PartialEq<str> for DefineEnum
1750{
1751 fn eq(&self, other: &str) -> bool
1752 {
1753 return self.enum_name.as_str() == other;
1754 }
1755}
1756
1757impl PartialEq<String> for DefineEnum
1758{
1759 fn eq(&self, other: &String) -> bool
1760 {
1761 return self.enum_name.as_str() == other.as_str();
1762 }
1763}
1764
1765impl Borrow<str> for DefineEnum
1766{
1767 fn borrow(&self) -> &str
1768 {
1769 return &self.enum_name;
1770 }
1771}
1772
1773impl Borrow<String> for DefineEnum
1774{
1775 fn borrow(&self) -> &String
1776 {
1777 return &self.enum_name;
1778 }
1779}
1780
1781impl fmt::Display for DefineEnum
1782{
1783 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
1784 {
1785 write!(f, "enum_name: '{}', enum_defs: '{}'",
1786 self.enum_name,
1787 self.enum_defs
1788 .iter()
1789 .map(|f| f.as_str())
1790 .collect::<Vec<&str>>()
1791 .join(","),
1792 )
1793 }
1794}
1795
1796impl Clone for DefineEnum
1797{
1798 fn clone(&self) -> Self
1799 {
1800 panic!("Asserion trap: Define must never be cloned! \
1801 Implementation Clone for Define is used to comply \
1802 with compilter requirments.");
1803 }
1804}
1805
1806impl DefineEnum
1807{
1808 pub
1809 fn new(enum_name: String, enum_defs: IndexSet<String>) -> StaticSchemeRes<Self>
1810 {
1811 if enum_defs.len() == 0
1812 {
1813 static_throw_text!("(define-enum \"{}\") is empty!", enum_name);
1814 }
1815
1816 return Ok(
1823 Self
1824 {
1825 enum_name:
1826 Arc::new(enum_name),
1827 enum_defs:
1828 enum_defs,
1829 rust_code_gen:
1830 RustCodeFields::default(),
1831 }
1832 );
1833 }
1834
1835
1836 pub
1837 fn get_enum_name(&self) -> &String
1838 {
1839 return self.enum_name.as_ref();
1840 }
1841
1842 pub
1843 fn get_rust_code_gen(&self) -> &RustCodeFields
1844 {
1845 return &self.rust_code_gen;
1846 }
1847
1848 pub
1849 fn get_rust_code_gen_mut(&mut self) -> &mut RustCodeFields
1850 {
1851 return &mut self.rust_code_gen;
1852 }
1853
1854
1855 pub
1856 fn clone_enum_name(&self) ->Arc<String>
1857 {
1858 return self.enum_name.clone();
1859 }
1860
1861 pub
1862 fn generate_enum_pairs(&self) -> (Vec<Arc<String>>, Vec<Arc<String>>)
1863 {
1864 let mut enum_symbol_pair: Vec<Arc<String>> = Vec::with_capacity(self.enum_defs.len());
1865 let mut enum_symbol: Vec<Arc<String>> = Vec::with_capacity(self.enum_defs.len());
1866
1867 for ed in self.enum_defs.iter()
1868 {
1869 let upper_c = prepare_enum_variant(ed);
1870 let lower_c = some_kind_of_lowercase_first_letter(ed);
1871
1872 enum_symbol_pair.push(Arc::new([self.enum_name.as_ref(), "::", upper_c.as_str()].concat()));
1873 enum_symbol_pair.push(Arc::new([self.enum_name.as_ref(), "::", lower_c.as_str()].concat()));
1874 enum_symbol.push(Arc::new(upper_c.to_string()));
1875 enum_symbol.push(Arc::new(lower_c.to_string()));
1876 }
1877
1878 return (enum_symbol_pair, enum_symbol);
1879 }
1880
1881 pub
1882 fn present(&self, itm: &str) -> bool
1883 {
1884 return self.enum_defs.contains(itm);
1885 }
1886}
1887
1888#[derive(Debug, Default, Serialize, Deserialize)]
1890pub struct Define
1891{
1892 name: Arc<String>,
1894
1895 data: GenericDataTypes,
1897
1898 proc_binds: Option<HashSet<String>>,
1900
1901 comment: Option<String>,
1903}
1904
1905impl fmt::Display for Define
1906{
1907 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
1908 {
1909 write!(f, "symbol: '{}', data: '{}', binds: '{}'",
1910 self.name, self.data,
1911 self.proc_binds
1912 .as_ref()
1913 .map_or(
1914 "UNBIND".to_string(),
1915 |f| f.iter().map(|v| v.as_str()).collect::<Vec<&str>>().join(", ")
1916 )
1917 )
1918 }
1919}
1920
1921impl Hash for Define
1922{
1923 fn hash<H: Hasher>(&self, state: &mut H)
1924 {
1925 self.name.as_ref().hash(state);
1926 }
1927}
1928
1929impl Eq for Define {}
1930
1931impl PartialEq for Define
1932{
1933 fn eq(&self, other: &Self) -> bool
1934 {
1935 return
1936 self.name.as_ref() == other.name.as_ref();
1937 }
1938}
1939
1940impl Borrow<String> for Define
1941{
1942 fn borrow(&self) -> &String
1943 {
1944 return &self.name;
1945 }
1946}
1947
1948impl Borrow<str> for Define
1949{
1950 fn borrow(&self) -> &str
1951 {
1952 return &self.name;
1953 }
1954}
1955
1956impl Clone for Define
1957{
1958 fn clone(&self) -> Self
1959 {
1960 panic!("Asserion trap: Define must never be cloned! \
1961 Implementation Clone for Define is used to comply \
1962 with compilter requirments.");
1963 }
1964}
1965
1966impl Define
1967{
1968 pub
1969 fn new(name: String, data: GenericDataTypes, proc_binds_set: HashSet<String>) -> Self
1970 {
1971 let proc_binds =
1972 if proc_binds_set.len() > 0
1973 {
1974 Some(proc_binds_set)
1975 }
1976 else
1977 {
1978 None
1979 };
1980
1981 return Self{ name: Arc::new(name), data, proc_binds, comment: None };
1982 }
1983
1984 pub
1985 fn clone_name(&self) -> Arc<String>
1986 {
1987 return self.name.clone();
1988 }
1989
1990 pub
1991 fn clone_data(&self) -> GenericDataTypes
1992 {
1993 return self.data.clone();
1994 }
1995 pub
1996 fn set_comment(&mut self, comment: String)
1997 {
1998 self.comment.replace(comment);
1999 }
2000
2001 pub
2002 fn get_name(&self) -> &String
2003 {
2004 return &self.name;
2005 }
2006
2007 pub
2008 fn get_data(&self) -> &GenericDataTypes
2009 {
2010 return &self.data;
2011 }
2012
2013 pub
2014 fn get_binds(&self) -> Option<&HashSet<String>>
2015 {
2016 return self.proc_binds.as_ref();
2017 }
2018
2019 pub
2023 fn is_in_proc_scope(&self, proc_name: &String) -> bool
2024 {
2025 if let Some(ref p) = self.proc_binds
2026 {
2027 return p.contains(proc_name);
2028 }
2029 else
2030 {
2031 return true;
2032 }
2033 }
2034}
2035
2036#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
2039pub struct Procedure
2040{
2041 name: Arc<String>,
2043
2044 args: LinkedHashMap<Arc<String>, Arc<Argument>>,
2046
2047 procs: LinkedHashMap<Arc<String>, Arc<ForegnProc>>,
2049
2050 is_empty: bool,
2052}
2053
2054impl PartialEq<str> for Procedure
2055{
2056 fn eq(&self, other: &str) -> bool
2057 {
2058 return self.name.as_str() == other;
2059 }
2060}
2061
2062impl Hash for Procedure
2063{
2064 fn hash<H: Hasher>(&self, state: &mut H)
2065 {
2066 self.name.hash(state);
2067 }
2068}
2069
2070impl Borrow<str> for Procedure
2071{
2072 fn borrow(&self) -> &str
2073 {
2074 return &self.name;
2075 }
2076}
2077
2078impl Borrow<String> for Procedure
2079{
2080 fn borrow(&self) -> &String
2081 {
2082 return &self.name;
2083 }
2084}
2085
2086impl fmt::Display for Procedure
2087{
2088 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
2089 {
2090 write!(f, "name: {}, is_empty: {}, porcs: {}", self.name, self.is_empty,
2091 self.procs.keys().map(|k| k.as_ref().clone()).collect::<Vec<String>>().join(", "))
2092 }
2093}
2094
2095impl Clone for Procedure
2096{
2097 fn clone(&self) -> Self
2098 {
2099 panic!("Asserion trap: Procedure must never be cloned! \
2100 Implementation Clone for Procedure is used to comply \
2101 with compilter requirments.");
2102 }
2103}
2104
2105impl Procedure
2106{
2107 pub const ROOT_PROC_NAME: &'static str = "root_procedure_0000";
2108
2109 pub
2110 fn new(name: String, li: LexerInfo) -> StaticSchemeRes<Self>
2111 {
2112 if common::contains_printable_all(&name) == false
2113 {
2114 return Err(
2115 StaticSchemeError
2116 ::new_text(format!("in procedure: 'N?A', near: '{}' the procedure name \
2117 contains non-printable character!",
2118 li)
2119 )
2120 );
2121 }
2122
2123 return Ok(
2124 Self
2125 {
2126 name: Arc::new(name),
2127 args: LinkedHashMap::new(),
2128 procs: LinkedHashMap::new(),
2129 is_empty: false,
2130 }
2131 );
2132 }
2133
2134 pub
2135 fn new_root() -> Self
2136 {
2137 return
2138 Self
2139 {
2140 name: Arc::new(Self::ROOT_PROC_NAME.to_string()),
2141 args: LinkedHashMap::new(),
2142 procs: LinkedHashMap::new(),
2143 is_empty: false,
2144 };
2145 }
2146
2147 pub
2148 fn is_root(&self) -> bool
2149 {
2150 return self.name.as_str() == Self::ROOT_PROC_NAME;
2151 }
2152
2153 pub
2154 fn clone_name(&self) ->Arc<String>
2155 {
2156 return self.name.clone();
2157 }
2158
2159 pub
2160 fn get_arg_by_label(&self, arg_level: &String) -> Option<&Arc<Argument>>
2161 {
2162 return self.args.get(arg_level);
2163 }
2164
2165 pub
2166 fn get_proc_by_label(&self, proc_name: &String) -> Option<&Arc<ForegnProc>>
2167 {
2168 return self.procs.get(proc_name);
2169 }
2170
2171 pub
2172 fn get_name(&self) -> &String
2173 {
2174 return &self.name;
2175 }
2176
2177 pub
2178 fn get_args_iter(&self) -> linked_hash_map::Iter<'_,Arc<String>,Arc<Argument>>
2179 {
2180 return self.args.iter();
2181 }
2182
2183 pub
2184 fn get_args_len(&self) -> usize
2185 {
2186 return self.args.len();
2187 }
2188
2189 pub
2190 fn get_procs_iter(&self) -> linked_hash_map::Iter<'_,Arc<String>,Arc<ForegnProc>>
2191 {
2192 return self.procs.iter();
2193 }
2194
2195 pub
2196 fn get_procs_len(&self) -> usize
2197 {
2198 return self.procs.len();
2199 }
2200
2201 pub
2202 fn get_proc(&self) -> &LinkedHashMap<Arc<String>,Arc<ForegnProc>>
2203 {
2204 return &self.procs;
2205 }
2206
2207 pub
2210 fn add_arg(&mut self, arg: Argument) -> StaticSchemeRes<()>
2211 {
2212 if self.is_empty == true
2213 {
2214 static_throw_text!("(procedure \"{}\") was explicitly set to empty but expects \
2215 (arg \"{}\") to appear", self.get_name(), arg.get_label());
2216 }
2217
2218 let res =
2219 self.args.insert(arg.clone_label(), Arc::new(arg));
2220
2221 if let Some(r) = res
2222 {
2223 static_throw_text!("redefinition of the (arg \"{}\" {:?}) in \
2224 (procedure \"{}\")", r.get_label(), r.arg_data_types, self.get_name());
2225 }
2226
2227 return Ok(());
2228 }
2229
2230 pub
2241 fn add_proc(
2242 &mut self,
2243 proc_label: String,
2244 proc_names: HashSet<String>,
2245 proc_allowed_flags: ProcFlags
2246 ) -> StaticSchemeRes<()>
2247 {
2248 if self.is_empty == true
2249 {
2250 return Err(
2251 StaticSchemeError::new_text(format!("procedure: '{}' was explicitly set to be empty, but a \
2252 foreign procedure is added: '{}", self.get_name(), proc_label))
2253 );
2254 }
2255
2256 let label = Arc::new(proc_label);
2257 let fp = ForegnProc::new(label.clone(), proc_names, proc_allowed_flags);
2258
2259 let res = self.procs.insert(label, Arc::new(fp));
2260
2261 if let Some(r) = res
2262 {
2263 return Err(
2264 StaticSchemeError
2265 ::new_text(format!("redefinition of the foreign proc: '{}' in procedure: '{}'",
2266 r.get_label(), self.get_name())
2267 )
2268 );
2269 }
2270
2271 return Ok(());
2272 }
2273
2274 pub
2277 fn set_empty(&mut self)
2278 {
2279 self.is_empty = true;
2280 }
2281
2282 pub
2284 fn is_empty(&self) -> bool
2285 {
2286 return self.is_empty;
2287 }
2288
2289 pub
2304 fn lookup_procedure(&self, proc_name: &String) -> Option<Arc<ForegnProc>>
2305 {
2306 for (_, p) in self.procs.iter()
2307 {
2308 if p.contains_proc(proc_name) == true
2309 {
2310 return Some(p.clone());
2311 }
2312 }
2313
2314 return None;
2315 }
2316
2317 pub
2318 fn validate(&self, li: LexerInfo) -> StaticSchemeRes<()>
2319 {
2320 if self.args.is_empty() == true && self.procs.is_empty() == true &&
2321 self.is_empty() == false
2322 {
2323 return Err(
2324 StaticSchemeError
2325 ::new_text(format!("in procedure: '{}', near: '{}' the procedure should either contain \
2326 foreign procs or arg or to be set to empty (procedure_empty)",
2327 self.get_name(), li)
2328 )
2329 );
2330 }
2331 else if (self.args.is_empty() == false || self.procs.is_empty() == false) &&
2332 self.is_empty() == true
2333 {
2334 return Err(
2335 StaticSchemeError
2336 ::new_text(format!("in procedure: '{}', near: '{}' the procedure both contains \
2337 foreign procs or arg and set to be empty (procedure_empty)",
2338 self.get_name(), li)
2339 )
2340 );
2341 }
2342
2343 return Ok(());
2344 }
2345}
2346
2347
2348#[derive(Debug, Serialize, Deserialize)]
2356pub struct ForegnProc
2357{
2358 label: Arc<String>,
2360
2361 foregn_names: HashSet<String>,
2364
2365 flags: ProcFlags,
2367}
2368
2369impl fmt::Display for ForegnProc
2370{
2371 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
2372 {
2373 write!(f, "[foregn proc] label: '{}'", self.label)
2374 }
2375}
2376
2377impl Eq for ForegnProc {}
2378
2379impl PartialEq for ForegnProc
2380{
2381 fn eq(&self, other: &Self) -> bool
2382 {
2383 self.label == other.label
2384 }
2385}
2386
2387impl Hash for ForegnProc
2388{
2389 fn hash<H: Hasher>(&self, state: &mut H)
2390 {
2391 self.label.hash(state);
2392 }
2393}
2394
2395impl ForegnProc
2396{
2397 pub
2398 fn new(label: Arc<String>, foregn_names: HashSet<String>, flags: ProcFlags,) -> Self
2399 {
2400 return Self {label: label, foregn_names: foregn_names, flags: flags};
2401 }
2402
2403 pub
2404 fn clone_label(&self) -> Arc<String>
2405 {
2406 return self.label.clone();
2407 }
2408
2409 pub
2410 fn get_label(&self) -> &String
2411 {
2412 return &self.label;
2413 }
2414
2415 pub
2418 fn contains_proc(&self, proc_name: &String) -> bool
2419 {
2420 return self.foregn_names.contains(proc_name);
2421 }
2422
2423 pub
2425 fn is_flag_set(&self, flag: ProcFlags) -> bool
2426 {
2427 return self.flags.intersects(flag);
2428 }
2429
2430 pub
2431 fn get_proc_iter(&self) -> std::collections::hash_set::Iter<'_, String>
2432 {
2433 return self.foregn_names.iter();
2434 }
2435}
2436
2437#[derive(Clone, Debug)]
2440pub struct Arg<'t>
2441{
2442 arg_data_types: &'t [ArgDataType],
2444
2445 index: Cell<usize>,
2447
2448 set_enum_bind: Option<&'t String>
2450}
2451
2452impl<'t> Arg<'t>
2453{
2454 fn new(args: &'t [ArgDataType], set_enum_b: Option<&'t String>) -> Arg<'t>
2455 {
2456 return
2457 Self
2458 {
2459 arg_data_types: args,
2460 index: Cell::new(0),
2461 set_enum_bind: set_enum_b
2462 };
2463 }
2464
2465 pub
2468 fn pop_arg(&self) -> Option<&'t ArgDataType>
2469 {
2470 let arg = self.arg_data_types.get(self.index.get());
2471 self.index.set( self.index.get() + 1 );
2472
2473 return arg;
2474 }
2475
2476 pub
2477 fn is_arg_enum_bind(&self) -> bool
2478 {
2479 return self.set_enum_bind.is_some();
2480 }
2481
2482 pub
2483 fn get_arg_enum_bind(&self) -> &String
2484 {
2485 return self.set_enum_bind.as_ref().unwrap();
2486 }
2487}
2488
2489#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
2491pub struct Argument
2492{
2493 label: Arc<String>,
2495 arg_data_types: Vec<ArgDataType>,
2500
2501 set_enum_bind: Option<String>,
2506}
2507
2508impl fmt::Display for Argument
2509{
2510 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
2511 {
2512 write!(f, "label: '{}', datatypes: '{}'",
2513 self.label, self.arg_data_types.iter().map(|d| d.to_string()).collect::<Vec<String>>().join("::"))
2514 }
2515}
2516
2517impl Argument
2518{
2519 fn validate_arg_datatypes(arg_data_types: &[ArgDataType]) -> StaticSchemeRes<()>
2522 {
2523 let arg0_opt = arg_data_types.get(0);
2524 if arg0_opt.is_none() == true || arg0_opt.unwrap() == &ArgDataType::None
2525 {
2526 static_throw_text!("argument validation problem: data type is mising");
2527 }
2528
2529 if arg0_opt.unwrap().has_subtype() == true
2530 {
2531 return Self::validate_arg_datatypes(&arg_data_types[1..]);
2532 }
2533
2534 return Ok(());
2535 }
2536
2537 pub
2538 fn new(label: Arc<String>, arg_data_types: Vec<ArgDataType>) -> StaticSchemeRes<Self>
2539 {
2540 Self::validate_arg_datatypes(arg_data_types.as_slice())?;
2542
2543 return Ok(
2544 Self
2545 {
2546 label,
2547 arg_data_types,
2548 set_enum_bind: None,
2549 }
2550 );
2551 }
2552
2553 pub
2554 fn clone_label(&self) ->Arc<String>
2555 {
2556 return self.label.clone();
2557 }
2558
2559 pub
2560 fn get_args(&self) -> Arg<'_>
2561 {
2562 return
2563 Arg::new(
2564 self.arg_data_types.as_slice(),
2565 self.set_enum_bind.as_ref()
2566 );
2567 }
2568
2569 pub
2570 fn set_enum_bind(&mut self, enum_bind: Option<String>) -> StaticSchemeRes<()>
2571 {
2572 if self.arg_data_types.iter().any(|f| f == &ArgDataType::Enumerator) == true
2573 {
2574 if enum_bind.is_some() == true
2575 {
2576 self.set_enum_bind = enum_bind;
2577 }
2578 else
2579 {
2580 static_throw_text!("enum_bind is none, but should be set for emumerator in argument");
2581 }
2582
2583 return Ok(());
2584 }
2585 else
2586 {
2587 if enum_bind.is_some() == true
2588 {
2589 static_throw_text!("enum_bind can only be set to procedure's field of type enum");
2590 }
2591
2592 return Ok(());
2593 }
2594 }
2595
2596 pub
2597 fn get_label(&self) -> &String
2598 {
2599 return &self.label;
2600 }
2601
2602 pub
2603 fn get_data_base_type(&self) -> &ArgDataType
2604 {
2605 return &self.arg_data_types[0];
2606 }
2607
2608 pub
2609 fn get_data_type(&self) -> &ArgDataType
2610 {
2611 return &self.arg_data_types[0];
2612 }
2613
2614 pub
2615 fn get_collection_type(&self) -> &ArgDataType
2616 {
2617 return &self.arg_data_types[1];
2618 }
2619
2620 pub
2621 fn get_collection_type_sub(&self) -> &ArgDataType
2622 {
2623 return &self.arg_data_types[2];
2624 }
2625
2626 pub
2627 fn get_arg_index(&self, idx: usize) -> Option<&ArgDataType>
2628 {
2629 return self.arg_data_types.get(idx);
2630 }
2631
2632 pub
2633 fn get_enum_bind(&self) -> Option<&String>
2634 {
2635 return self.set_enum_bind.as_ref();
2636 }
2637}
2638
2639