1use std::{collections::HashSet, str::FromStr};
2
3use log::error;
4use toml::Value;
5
6use super::{
7 error::TomlHelper,
8 gobjects::GStatus,
9 ident::Ident,
10 parameter_matchable::Functionlike,
11 parsable::{Parsable, Parse},
12 string_type::StringType,
13};
14use crate::{
15 analysis::safety_assertion_mode::SafetyAssertionMode,
16 codegen::Visibility,
17 library::{Infallible, Mandatory, Nullable},
18 version::Version,
19};
20
21#[derive(Clone, Debug)]
22pub struct CallbackParameter {
23 pub ident: Ident,
24 pub nullable: Option<Nullable>,
25}
26
27pub type CallbackParameters = Vec<CallbackParameter>;
28
29impl Parse for CallbackParameter {
30 fn parse(toml: &Value, object_name: &str) -> Option<Self> {
31 let Some(ident) = Ident::parse(toml, object_name, "callback parameter") else {
32 error!(
33 "No 'name' or 'pattern' given for parameter for object {}",
34 object_name
35 );
36 return None;
37 };
38 toml.check_unwanted(&["nullable"], &format!("callback parameter {object_name}"));
39
40 let nullable = toml
41 .lookup("nullable")
42 .and_then(Value::as_bool)
43 .map(Nullable);
44
45 Some(Self { ident, nullable })
46 }
47}
48
49impl AsRef<Ident> for CallbackParameter {
50 fn as_ref(&self) -> &Ident {
51 &self.ident
52 }
53}
54
55#[derive(Clone, Debug)]
56pub struct Parameter {
57 pub ident: Ident,
58 pub constant: bool,
61 pub move_: Option<bool>,
62 pub nullable: Option<Nullable>,
63 pub mandatory: Option<Mandatory>,
64 pub infallible: Option<Infallible>,
65 pub length_of: Option<String>,
66 pub string_type: Option<StringType>,
67 pub callback_parameters: CallbackParameters,
68}
69
70impl Parse for Parameter {
71 fn parse(toml: &Value, object_name: &str) -> Option<Self> {
72 let Some(ident) = Ident::parse(toml, object_name, "function parameter") else {
73 error!(
74 "No 'name' or 'pattern' given for parameter for object {}",
75 object_name
76 );
77 return None;
78 };
79 toml.check_unwanted(
80 &[
81 "const",
82 "nullable",
83 "mandatory",
84 "infallible",
85 "length_of",
86 "name",
87 "move",
88 "pattern",
89 "string_type",
90 "callback_parameter",
91 ],
92 &format!("function parameter {object_name}"),
93 );
94
95 let constant = toml
96 .lookup("const")
97 .and_then(Value::as_bool)
98 .unwrap_or(false);
99 let move_ = toml.lookup("move").and_then(Value::as_bool);
100 let nullable = toml
101 .lookup("nullable")
102 .and_then(Value::as_bool)
103 .map(Nullable);
104 let mandatory = toml
105 .lookup("mandatory")
106 .and_then(Value::as_bool)
107 .map(Mandatory);
108 let infallible = toml
109 .lookup("infallible")
110 .and_then(Value::as_bool)
111 .map(Infallible);
112 let length_of = toml
113 .lookup("length_of")
114 .and_then(Value::as_str)
115 .map(|s| if s == "return" { "" } else { s })
116 .map(ToOwned::to_owned);
117 let string_type = toml.lookup("string_type").and_then(Value::as_str);
118 let string_type = match string_type {
119 None => None,
120 Some(val) => match StringType::from_str(val) {
121 Ok(val) => Some(val),
122 Err(error_str) => {
123 error!(
124 "Error: {} for parameter for object {}",
125 error_str, object_name
126 );
127 None
128 }
129 },
130 };
131 let callback_parameters =
132 CallbackParameters::parse(toml.lookup("callback_parameter"), object_name);
133
134 Some(Self {
135 ident,
136 constant,
137 move_,
138 nullable,
139 mandatory,
140 infallible,
141 length_of,
142 string_type,
143 callback_parameters,
144 })
145 }
146}
147
148impl AsRef<Ident> for Parameter {
149 fn as_ref(&self) -> &Ident {
150 &self.ident
151 }
152}
153
154pub type Parameters = Vec<Parameter>;
155
156#[derive(Clone, Debug)]
157pub struct Return {
158 pub nullable: Option<Nullable>,
159 pub mandatory: Option<Mandatory>,
160 pub infallible: Option<Infallible>,
161 pub bool_return_is_error: Option<String>,
162 pub nullable_return_is_error: Option<String>,
163 pub use_return_for_result: Option<bool>,
164 pub string_type: Option<StringType>,
165 pub type_name: Option<String>,
166}
167
168impl Return {
169 pub fn parse(toml: Option<&Value>, object_name: &str) -> Self {
170 if toml.is_none() {
171 return Self {
172 nullable: None,
173 mandatory: None,
174 infallible: None,
175 bool_return_is_error: None,
176 nullable_return_is_error: None,
177 use_return_for_result: None,
178 string_type: None,
179 type_name: None,
180 };
181 }
182
183 let v = toml.unwrap();
184 v.check_unwanted(
185 &[
186 "nullable",
187 "mandatory",
188 "infallible",
189 "bool_return_is_error",
190 "nullable_return_is_error",
191 "use_return_for_result",
192 "string_type",
193 "type",
194 ],
195 "return",
196 );
197
198 let nullable = v.lookup("nullable").and_then(Value::as_bool).map(Nullable);
199 let mandatory = v
200 .lookup("mandatory")
201 .and_then(Value::as_bool)
202 .map(Mandatory);
203 let infallible = v
204 .lookup("infallible")
205 .and_then(Value::as_bool)
206 .map(Infallible);
207 let bool_return_is_error = v
208 .lookup("bool_return_is_error")
209 .and_then(Value::as_str)
210 .map(ToOwned::to_owned);
211 let nullable_return_is_error = v
212 .lookup("nullable_return_is_error")
213 .and_then(Value::as_str)
214 .map(ToOwned::to_owned);
215 let use_return_for_result = v.lookup("use_return_for_result").and_then(Value::as_bool);
216 let string_type = v.lookup("string_type").and_then(Value::as_str);
217 let string_type = match string_type {
218 None => None,
219 Some(v) => match StringType::from_str(v) {
220 Ok(v) => Some(v),
221 Err(error_str) => {
222 error!("Error: {} for return", error_str);
223 None
224 }
225 },
226 };
227 let type_name = v
228 .lookup("type")
229 .and_then(Value::as_str)
230 .map(ToOwned::to_owned);
231 if string_type.is_some() && type_name.is_some() {
232 error!(
233 "\"string_type\" and \"type\" parameters can't be passed at the same time for \
234 object {}, only \"type\" will be applied in this case",
235 object_name
236 );
237 }
238
239 Self {
240 nullable,
241 mandatory,
242 infallible,
243 bool_return_is_error,
244 nullable_return_is_error,
245 use_return_for_result,
246 string_type,
247 type_name,
248 }
249 }
250}
251
252pub fn check_rename(rename: &Option<String>, object_name: &str, function_name: &Ident) -> bool {
253 if let Some(rename) = rename {
254 for c in &["\t", "\n", " "] {
255 if rename.contains(c) {
256 error!(
257 "Invalid 'rename' value given to {}::{}: forbidden character '{:?}'",
258 object_name, function_name, c
259 );
260 return false;
261 }
262 }
263 }
264 true
265}
266
267#[derive(Clone, Debug)]
268pub struct Function {
269 pub ident: Ident,
270 pub status: GStatus,
271 pub version: Option<Version>,
272 pub cfg_condition: Option<String>,
273 pub parameters: Parameters,
274 pub ret: Return,
275 pub doc_hidden: bool,
276 pub doc_ignore_parameters: HashSet<String>,
277 pub disable_length_detect: bool,
278 pub doc_trait_name: Option<String>,
279 pub doc_struct_name: Option<String>,
280 pub no_future: bool,
281 pub unsafe_: bool,
282 pub rename: Option<String>,
283 pub visibility: Option<Visibility>,
284 pub bypass_auto_rename: bool,
285 pub is_constructor: Option<bool>,
286 pub assertion: Option<SafetyAssertionMode>,
287 pub generate_doc: bool,
288}
289
290impl Parse for Function {
291 fn parse(toml: &Value, object_name: &str) -> Option<Self> {
292 let Some(ident) = Ident::parse(toml, object_name, "function") else {
293 error!(
294 "No 'name' or 'pattern' given for function for object {}",
295 object_name
296 );
297 return None;
298 };
299 toml.check_unwanted(
300 &[
301 "ignore",
302 "manual",
303 "version",
304 "cfg_condition",
305 "parameter",
306 "return",
307 "name",
308 "doc_hidden",
309 "doc_ignore_parameters",
310 "disable_length_detect",
311 "pattern",
312 "doc_trait_name",
313 "doc_struct_name",
314 "no_future",
315 "unsafe",
316 "rename",
317 "bypass_auto_rename",
318 "constructor",
319 "assertion",
320 "visibility",
321 "generate_doc",
322 ],
323 &format!("function {object_name}"),
324 );
325
326 let status = {
327 if toml
328 .lookup("ignore")
329 .and_then(Value::as_bool)
330 .unwrap_or(false)
331 {
332 GStatus::Ignore
333 } else if toml
334 .lookup("manual")
335 .and_then(Value::as_bool)
336 .unwrap_or(false)
337 {
338 GStatus::Manual
339 } else {
340 GStatus::Generate
341 }
342 };
343 let version = toml
344 .lookup("version")
345 .and_then(Value::as_str)
346 .and_then(|s| s.parse().ok());
347 let cfg_condition = toml
348 .lookup("cfg_condition")
349 .and_then(Value::as_str)
350 .map(ToOwned::to_owned);
351 let parameters = Parameters::parse(toml.lookup("parameter"), object_name);
352 let ret = Return::parse(toml.lookup("return"), object_name);
353 let doc_hidden = toml
354 .lookup("doc_hidden")
355 .and_then(Value::as_bool)
356 .unwrap_or(false);
357 let doc_ignore_parameters = toml
358 .lookup_vec("doc_ignore_parameters", "Invalid doc_ignore_parameters")
359 .map(|v| {
360 v.iter()
361 .filter_map(|v| v.as_str().map(String::from))
362 .collect()
363 })
364 .unwrap_or_default();
365 let disable_length_detect = toml
366 .lookup("disable_length_detect")
367 .and_then(Value::as_bool)
368 .unwrap_or(false);
369 let doc_trait_name = toml
370 .lookup("doc_trait_name")
371 .and_then(Value::as_str)
372 .map(ToOwned::to_owned);
373 let doc_struct_name = toml
374 .lookup("doc_struct_name")
375 .and_then(Value::as_str)
376 .map(ToOwned::to_owned);
377 let no_future = toml
378 .lookup("no_future")
379 .and_then(Value::as_bool)
380 .unwrap_or(false);
381 let unsafe_ = toml
382 .lookup("unsafe")
383 .and_then(Value::as_bool)
384 .unwrap_or(false);
385 let rename = toml
386 .lookup("rename")
387 .and_then(Value::as_str)
388 .map(ToOwned::to_owned);
389 if !check_rename(&rename, object_name, &ident) {
390 return None;
391 }
392 let bypass_auto_rename = toml
393 .lookup("bypass_auto_rename")
394 .and_then(Value::as_bool)
395 .unwrap_or(false);
396 let is_constructor = toml.lookup("constructor").and_then(Value::as_bool);
397 let assertion = toml
398 .lookup("assertion")
399 .and_then(Value::as_str)
400 .map(|s| s.parse::<SafetyAssertionMode>())
401 .transpose();
402 if let Err(ref err) = assertion {
403 error!("{}", err);
404 }
405 let assertion = assertion.ok().flatten();
406 let visibility = toml
407 .lookup("visibility")
408 .and_then(Value::as_str)
409 .map(std::str::FromStr::from_str)
410 .transpose();
411 if let Err(ref err) = visibility {
412 error!("{}", err);
413 }
414 let visibility = visibility.ok().flatten();
415 let generate_doc = toml
416 .lookup("generate_doc")
417 .and_then(Value::as_bool)
418 .unwrap_or(true);
419 Some(Self {
420 ident,
421 status,
422 version,
423 cfg_condition,
424 parameters,
425 ret,
426 doc_hidden,
427 doc_ignore_parameters,
428 disable_length_detect,
429 doc_trait_name,
430 doc_struct_name,
431 no_future,
432 unsafe_,
433 rename,
434 visibility,
435 bypass_auto_rename,
436 is_constructor,
437 assertion,
438 generate_doc,
439 })
440 }
441}
442
443impl Functionlike for Function {
444 type Parameter = self::Parameter;
445
446 fn parameters(&self) -> &[Self::Parameter] {
447 &self.parameters
448 }
449}
450
451impl AsRef<Ident> for Function {
452 fn as_ref(&self) -> &Ident {
453 &self.ident
454 }
455}
456
457pub type Functions = Vec<Function>;
458
459#[cfg(test)]
460mod tests {
461 use super::{
462 super::{
463 ident::Ident,
464 matchable::Matchable,
465 parameter_matchable::ParameterMatchable,
466 parsable::{Parsable, Parse},
467 },
468 *,
469 };
470 use crate::{library::Nullable, version::Version};
471
472 fn functions_toml(input: &str) -> ::toml::Value {
473 let mut value: ::toml::value::Table = ::toml::from_str(input).unwrap();
474 value.remove("f").unwrap()
475 }
476
477 fn toml(input: &str) -> ::toml::Value {
478 let value = ::toml::from_str(input);
479 assert!(value.is_ok());
480 value.unwrap()
481 }
482
483 #[test]
484 fn function_parse_ignore() {
485 let toml = toml(
486 r#"
487name = "func1"
488ignore = true
489"#,
490 );
491 let f = Function::parse(&toml, "a").unwrap();
492 assert_eq!(f.ident, Ident::Name("func1".into()));
493 assert!(f.status.ignored());
494 }
495
496 #[test]
497 fn function_parse_manual() {
498 let toml = toml(
499 r#"
500name = "func1"
501manual = true
502"#,
503 );
504 let f = Function::parse(&toml, "a").unwrap();
505 assert_eq!(f.ident, Ident::Name("func1".into()));
506 assert!(f.status.manual());
507 }
508
509 #[test]
510 fn function_parse_version_default() {
511 let toml = toml(
512 r#"
513name = "func1"
514"#,
515 );
516 let f = Function::parse(&toml, "a").unwrap();
517 assert_eq!(f.version, None);
518 assert!(f.status.need_generate());
519 }
520
521 #[test]
522 fn function_parse_version() {
523 let toml = toml(
524 r#"
525name = "func1"
526version = "3.20"
527"#,
528 );
529 let f = Function::parse(&toml, "a").unwrap();
530 assert_eq!(f.version, Some(Version::new(3, 20, 0)));
531 }
532
533 #[test]
534 fn function_parse_cfg_condition_default() {
535 let toml = toml(
536 r#"
537name = "func1"
538"#,
539 );
540 let f = Function::parse(&toml, "a").unwrap();
541 assert_eq!(f.cfg_condition, None);
542 }
543
544 #[test]
545 fn function_parse_cfg_condition() {
546 let toml = toml(
547 r#"
548name = "func1"
549cfg_condition = 'unix'
550"#,
551 );
552 let f = Function::parse(&toml, "a").unwrap();
553 assert_eq!(f.cfg_condition, Some("unix".to_string()));
554 }
555
556 #[test]
557 fn function_parse_return_nullable_default1() {
558 let toml = toml(
559 r#"
560name = "func1"
561"#,
562 );
563 let f = Function::parse(&toml, "a").unwrap();
564 assert_eq!(f.ret.nullable, None);
565 }
566
567 #[test]
568 fn function_parse_return_nullable_default2() {
569 let toml = toml(
570 r#"
571name = "func1"
572[return]
573"#,
574 );
575 let f = Function::parse(&toml, "a").unwrap();
576 assert_eq!(f.ret.nullable, None);
577 }
578
579 #[test]
580 fn function_parse_parameters() {
581 let toml = toml(
582 r#"
583name = "func1"
584[[parameter]]
585name = "par1"
586[[parameter]]
587name = "par2"
588const = false
589nullable = false
590[[parameter]]
591name = "par3"
592const = true
593nullable = true
594[[parameter]]
595pattern = "par4"
596const = true
597"#,
598 );
599 let f = Function::parse(&toml, "a").unwrap();
600 let pars = f.parameters;
601 assert_eq!(pars.len(), 4);
602 assert_eq!(pars[0].ident, Ident::Name("par1".into()));
603 assert!(!pars[0].constant);
604 assert_eq!(pars[0].nullable, None);
605 assert_eq!(pars[1].ident, Ident::Name("par2".into()));
606 assert!(!pars[1].constant);
607 assert_eq!(pars[1].nullable, Some(Nullable(false)));
608 assert_eq!(pars[2].ident, Ident::Name("par3".into()));
609 assert!(pars[2].constant);
610 assert_eq!(pars[2].nullable, Some(Nullable(true)));
611 assert!(matches!(pars[3].ident, Ident::Pattern(_)));
612 assert!(pars[3].constant);
613 assert_eq!(pars[3].nullable, None);
614 }
615
616 #[test]
617 fn function_parse_return_nullable_false() {
618 let toml = toml(
619 r#"
620name = "func1"
621[return]
622nullable = false
623"#,
624 );
625 let f = Function::parse(&toml, "a").unwrap();
626 assert_eq!(f.ret.nullable, Some(Nullable(false)));
627 }
628
629 #[test]
630 fn function_parse_return_nullable_true() {
631 let toml = toml(
632 r#"
633name = "func1"
634[return]
635nullable = true
636"#,
637 );
638 let f = Function::parse(&toml, "a").unwrap();
639 assert_eq!(f.ret.nullable, Some(Nullable(true)));
640 }
641
642 #[test]
643 fn function_parse_generate_doc() {
644 let r = toml(
645 r#"
646name = "prop"
647generate_doc = false
648"#,
649 );
650 let f = Function::parse(&r, "a").unwrap();
651 assert!(!f.generate_doc);
652
653 let r = toml(
655 r#"
656name = "prop"
657"#,
658 );
659 let f = Function::parse(&r, "a").unwrap();
660 assert!(f.generate_doc);
661 }
662
663 #[test]
664 fn functions_parse_empty_for_none() {
665 let fns = Functions::parse(None, "a");
666 assert!(fns.is_empty());
667 }
668
669 #[test]
670 fn functions_parse_ident() {
671 let toml = functions_toml(
672 r#"
673[[f]]
674name = "func1"
675[[f]]
676not_name = "func1.5"
677[[f]]
678name = "func2"
679[[f]]
680pattern = 'func3\w+'
681[[f]]
682pattern = 'bad_func4[\w+'
683"#,
684 );
685 let fns = Functions::parse(Some(&toml), "a");
686 assert_eq!(fns.len(), 3);
687 assert_eq!(fns[0].ident, Ident::Name("func1".into()));
688 assert_eq!(fns[1].ident, Ident::Name("func2".into()));
689 assert!(matches!(fns[2].ident, Ident::Pattern(_)));
690 }
691
692 #[test]
693 fn functions_parse_matches() {
694 let toml = functions_toml(
695 r#"
696[[f]]
697name = "func1"
698[[f]]
699name = "f1.5"
700[[f]]
701name = "func2"
702[[f]]
703pattern = 'func\d+'
704"#,
705 );
706 let fns = Functions::parse(Some(&toml), "a");
707 assert_eq!(fns.len(), 3);
708
709 assert_eq!(fns.matched("func1").len(), 2);
710 assert_eq!(fns.matched("func2").len(), 2);
711 assert_eq!(fns.matched("func3").len(), 1);
712 assert_eq!(fns.matched("f1.5").len(), 0);
714 assert_eq!(fns.matched("none").len(), 0);
715 }
716
717 #[test]
718 fn functions_parse_matched_parameters() {
719 let toml = functions_toml(
720 r#"
721[[f]]
722name = "func"
723[[f.parameter]]
724name="par1"
725[[f.parameter]]
726name="par2"
727[[f.parameter]]
728pattern='par\d+'
729[[f]]
730name = "func"
731[[f.parameter]]
732name="par2"
733[[f.parameter]]
734name="par3"
735[[f.parameter]]
736pattern='par\d+'
737"#,
738 );
739 let fns = Functions::parse(Some(&toml), "a");
740 assert_eq!(fns.len(), 2);
741 let m = fns.matched("func");
742 assert_eq!(m.len(), 2);
743
744 assert_eq!(m.matched_parameters("param").len(), 0);
745 assert_eq!(m.matched_parameters("par1").len(), 3);
746 assert_eq!(m.matched_parameters("par2").len(), 4);
747 assert_eq!(m.matched_parameters("par3").len(), 3);
748 assert_eq!(m.matched_parameters("par4").len(), 2);
749 }
750
751 #[test]
752 fn functions_parse_rename() {
753 let toml = toml(
754 r#"
755name = "func1"
756rename = "another"
757"#,
758 );
759 let f = Function::parse(&toml, "a").unwrap();
760 assert_eq!(f.rename, Some("another".to_owned()));
761 }
762
763 #[test]
764 fn functions_parse_rename_fail() {
765 let toml = toml(
766 r#"
767name = "func1"
768rename = "anoth er"
769"#,
770 );
771 let f = Function::parse(&toml, "a");
772 assert!(f.is_none());
773 }
774
775 #[test]
776 fn function_bypass_auto_rename() {
777 let toml = toml(
778 r#"
779name = "func1"
780bypass_auto_rename = true
781"#,
782 );
783 let f = Function::parse(&toml, "a").unwrap();
784 assert_eq!(f.ident, Ident::Name("func1".into()));
785 assert!(f.bypass_auto_rename);
786 }
787
788 #[test]
789 fn parse_return_mandatory_default() {
790 let toml = toml(
791 r#"
792name = "func1"
793"#,
794 );
795 let f = Function::parse(&toml, "a");
796 let f = f.unwrap();
797 assert!(f.ret.mandatory.is_none());
798 }
799
800 #[test]
801 fn parse_return_mandatory() {
802 let toml = toml(
803 r#"
804name = "func1"
805 [return]
806 mandatory = true
807"#,
808 );
809 let f = Function::parse(&toml, "a");
810 let f = f.unwrap();
811 assert_eq!(f.ret.mandatory, Some(Mandatory(true)));
812 }
813
814 #[test]
815 fn parse_return_non_mandatory() {
816 let toml = toml(
817 r#"
818name = "func1"
819 [return]
820 mandatory = false
821"#,
822 );
823 let f = Function::parse(&toml, "a");
824 let f = f.unwrap();
825 assert_eq!(f.ret.mandatory, Some(Mandatory(false)));
826 }
827
828 #[test]
829 fn parse_parameter_mandatory_default() {
830 let toml = toml(
831 r#"
832name = "func1"
833 [[parameter]]
834 name = "param1"
835"#,
836 );
837 let f = Function::parse(&toml, "a");
838 let f = f.unwrap();
839 let param1 = &f.parameters[0];
840 assert!(param1.mandatory.is_none());
841 }
842
843 #[test]
844 fn parse_parameter_mandatory() {
845 let toml = toml(
846 r#"
847name = "func1"
848 [[parameter]]
849 name = "param1"
850 mandatory = true
851"#,
852 );
853 let f = Function::parse(&toml, "a");
854 let f = f.unwrap();
855 let param1 = &f.parameters[0];
856 assert_eq!(param1.mandatory, Some(Mandatory(true)));
857 }
858
859 #[test]
860 fn parse_parameter_non_mandatory() {
861 let toml = toml(
862 r#"
863name = "func1"
864 [[parameter]]
865 name = "param1"
866 mandatory = false
867"#,
868 );
869 let f = Function::parse(&toml, "a");
870 let f = f.unwrap();
871 let param1 = &f.parameters[0];
872 assert_eq!(param1.mandatory, Some(Mandatory(false)));
873 }
874
875 #[test]
876 fn parse_return_infallible_default() {
877 let toml = toml(
878 r#"
879name = "func1"
880"#,
881 );
882 let f = Function::parse(&toml, "a");
883 let f = f.unwrap();
884 assert!(f.ret.infallible.is_none());
885 }
886
887 #[test]
888 fn parse_return_infallible() {
889 let toml = toml(
890 r#"
891name = "func1"
892 [return]
893 infallible = true
894"#,
895 );
896 let f = Function::parse(&toml, "a");
897 let f = f.unwrap();
898 assert_eq!(f.ret.infallible, Some(Infallible(true)));
899 }
900
901 #[test]
902 fn parse_return_faillible() {
903 let toml = toml(
904 r#"
905name = "func1"
906 [return]
907 infallible = false
908"#,
909 );
910 let f = Function::parse(&toml, "a");
911 let f = f.unwrap();
912 assert_eq!(f.ret.infallible, Some(Infallible(false)));
913 }
914
915 #[test]
916 fn parse_parameter_infallible_default() {
917 let toml = toml(
918 r#"
919name = "func1"
920 [[parameter]]
921 name = "param1"
922"#,
923 );
924 let f = Function::parse(&toml, "a");
925 let f = f.unwrap();
926 let param1 = &f.parameters[0];
927 assert!(param1.infallible.is_none());
928 }
929
930 #[test]
931 fn parse_parameter_infallible() {
932 let toml = toml(
933 r#"
934name = "func1"
935 [[parameter]]
936 name = "param1"
937 infallible = true
938"#,
939 );
940 let f = Function::parse(&toml, "a");
941 let f = f.unwrap();
942 let param1 = &f.parameters[0];
943 assert_eq!(param1.infallible, Some(Infallible(true)));
944 }
945
946 #[test]
947 fn parse_parameter_faillible() {
948 let toml = toml(
949 r#"
950name = "func1"
951 [[parameter]]
952 name = "param1"
953 infallible = false
954"#,
955 );
956 let f = Function::parse(&toml, "a");
957 let f = f.unwrap();
958 let param1 = &f.parameters[0];
959 assert_eq!(param1.infallible, Some(Infallible(false)));
960 }
961}