mers_lib/program/run/
field.rs1use crate::{
2 data::{self, object::ObjectT, Data, MersDataWInfo, MersTypeWInfo, Type},
3 errors::{CheckError, EColor, SourceRange},
4};
5
6use super::MersStatement;
7
8#[derive(Debug)]
9pub struct Field {
10 pub pos_in_src: SourceRange,
11 pub object: Box<dyn MersStatement>,
12 pub field_str: String,
13 pub field: usize,
14}
15impl MersStatement for Field {
16 fn check_custom(
17 &self,
18 info: &mut super::CheckInfo,
19 init_to: Option<&Type>,
20 ) -> Result<data::Type, super::CheckError> {
21 if init_to.is_some() {
22 return Err("can't init to statement type Field".to_string().into());
23 }
24 let object = self.object.check(info, init_to)?;
25 let mut o = Type::empty();
26 for t in object.types.iter() {
27 if let Some(t) = t.as_any().downcast_ref::<ObjectT>() {
28 if let Some(t) = t.get(self.field) {
29 o.add_all(t);
30 } else {
31 return Err(CheckError::new().msg(vec![
32 ("can't get field ".to_owned(), None),
33 (self.field_str.clone(), Some(EColor::ObjectField)),
34 (" of object ".to_owned(), None),
35 (t.with_info(info).to_string(), Some(EColor::InitFrom)),
36 ]));
37 }
38 } else {
39 return Err(CheckError::new().msg(vec![
40 ("can't get field ".to_owned(), None),
41 (self.field_str.clone(), Some(EColor::ObjectField)),
42 (" of non-object type ".to_owned(), None),
43 (t.with_info(info).to_string(), Some(EColor::InitFrom)),
44 ]));
45 }
46 }
47 Ok(o)
48 }
49 fn run_custom(&self, info: &mut super::Info) -> Result<Data, CheckError> {
50 let object = self.object.run(info)?;
51 let object = object.get();
52 let object = object
53 .as_any()
54 .downcast_ref::<data::object::Object>()
55 .ok_or_else(|| {
56 format!(
57 "couldn't extract field {} from non-object value {}",
58 self.field_str,
59 object.with_info(info)
60 )
61 })?;
62 Ok(object
63 .get(self.field)
64 .ok_or_else(|| {
65 format!(
66 "couldn't extract field {} from object {}",
67 self.field_str,
68 object.with_info(info)
69 )
70 })?
71 .clone())
72 }
73 fn has_scope(&self) -> bool {
74 false
75 }
76 fn source_range(&self) -> SourceRange {
77 self.pos_in_src.clone()
78 }
79 fn inner_statements(&self) -> Vec<&dyn MersStatement> {
80 vec![&*self.object]
81 }
82 fn as_any(&self) -> &dyn std::any::Any {
83 self
84 }
85}