mers_lib/program/run/
field.rs

1use 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}