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