teo_parser/ast/
field.rs

1use std::cell::RefCell;
2use crate::ast::span::Span;
3use crate::ast::doc_comment::DocComment;
4use crate::ast::decorator::Decorator;
5use crate::ast::type_expr::TypeExpr;
6use crate::ast::identifier::Identifier;
7use crate::ast::reference_space::ReferenceSpace;
8use crate::{declare_container_node, impl_container_node_defaults, node_child_fn, node_children_iter, node_children_iter_fn, node_optional_child_fn};
9use crate::format::Writer;
10use crate::traits::has_availability::HasAvailability;
11use crate::traits::info_provider::InfoProvider;
12use crate::traits::resolved::Resolve;
13use crate::traits::write::Write;
14
15#[derive(Debug, Copy, Clone)]
16pub enum FieldHint {
17    ModelField,
18    InterfaceField,
19}
20
21#[derive(Debug, Copy, Clone)]
22pub struct ModelPrimitiveFieldSettings {
23    pub dropped: bool,
24    pub r#virtual: bool,
25}
26
27#[derive(Debug, Copy, Clone)]
28pub struct ModelRelationSettings {
29    pub direct: bool,
30}
31
32#[derive(Debug, Copy, Clone)]
33pub struct ModelPropertyFieldSettings {
34   pub cached: bool,
35}
36
37#[derive(Debug, Copy, Clone)]
38pub enum FieldClass {
39    ModelPrimitiveField(ModelPrimitiveFieldSettings),
40    ModelRelation(ModelRelationSettings),
41    ModelProperty(ModelPropertyFieldSettings),
42    InterfaceField,
43    ConfigDeclarationField,
44}
45
46impl FieldClass {
47
48    pub fn is_model_relation(&self) -> bool {
49        self.as_model_relation().is_some()
50    }
51
52    pub fn as_model_relation(&self) -> Option<&ModelRelationSettings> {
53        match self {
54            FieldClass::ModelRelation(s) => Some(s),
55            _ => None,
56        }
57    }
58
59    pub fn is_model_primitive_field(&self) -> bool {
60        self.as_model_primitive_field().is_some()
61    }
62
63    pub fn as_model_primitive_field(&self) -> Option<&ModelPrimitiveFieldSettings> {
64        match self {
65            FieldClass::ModelPrimitiveField(s) => Some(s),
66            _ => None,
67        }
68    }
69
70    pub fn is_model_property(&self) -> bool {
71        self.as_model_property().is_some()
72    }
73
74    pub fn as_model_property(&self) -> Option<&ModelPropertyFieldSettings> {
75        match self {
76            FieldClass::ModelProperty(s) => Some(s),
77            _ => None,
78        }
79    }
80
81    pub fn is_interface_field(&self) -> bool {
82        match self {
83            FieldClass::InterfaceField => true,
84            _ => false,
85        }
86    }
87
88    pub fn is_model_field(&self) -> bool {
89        self.is_model_field() ||
90        self.is_model_relation() ||
91        self.is_model_property()
92    }
93
94    pub fn reference_type(&self) -> ReferenceSpace {
95        match self {
96            FieldClass::ModelPrimitiveField(_) => ReferenceSpace::ModelFieldDecorator,
97            FieldClass::ModelRelation(_) => ReferenceSpace::ModelRelationDecorator,
98            FieldClass::ModelProperty(_) => ReferenceSpace::ModelPropertyDecorator,
99            FieldClass::InterfaceField => ReferenceSpace::InterfaceFieldDecorator,
100            FieldClass::ConfigDeclarationField => ReferenceSpace::Default,
101        }
102    }
103}
104
105#[derive(Debug)]
106pub struct FieldResolved {
107    pub class: FieldClass,
108}
109
110declare_container_node!(Field, named, availability,
111    pub(crate) comment: Option<usize>,
112    pub(crate) decorators: Vec<usize>,
113    pub(crate) empty_decorator_spans: Vec<Span>,
114    pub(crate) identifier: usize,
115    pub(crate) type_expr: usize,
116    pub(crate) resolved: RefCell<Option<FieldResolved>>,
117);
118
119impl_container_node_defaults!(Field, named, availability);
120
121node_children_iter!(Field, Decorator, DecoratorsIter, decorators);
122
123impl Field {
124
125    node_optional_child_fn!(comment, DocComment);
126
127    node_children_iter_fn!(decorators, DecoratorsIter);
128
129    node_child_fn!(identifier, Identifier);
130
131    node_child_fn!(type_expr, TypeExpr);
132}
133
134impl InfoProvider for Field {
135    fn namespace_skip(&self) -> usize {
136        1
137    }
138}
139
140impl Resolve<FieldResolved> for Field {
141    fn resolved_ref_cell(&self) -> &RefCell<Option<FieldResolved>> {
142        &self.resolved
143    }
144}
145
146impl Write for Field {
147    fn write<'a>(&'a self, writer: &mut Writer<'a>) {
148        writer.write_children(self, self.children.values())
149    }
150
151    fn is_block_level_element(&self) -> bool {
152        true
153    }
154}
155