-
Notifications
You must be signed in to change notification settings - Fork 213
/
map.rs
122 lines (107 loc) 路 3.35 KB
/
map.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use crate::{
ast::{self, WithName, WithSpan},
coerce,
context::Context,
types::{CompositeTypeField, ModelAttributes, ScalarField},
DatamodelError, StringId,
};
pub(super) fn model(model_attributes: &mut ModelAttributes, ctx: &mut Context<'_>) {
let mapped_name = match visit_map_attribute(ctx) {
Some(name) => name,
None => return,
};
model_attributes.mapped_name = Some(mapped_name);
}
pub(super) fn scalar_field(
ast_model: &ast::Model,
ast_field: &ast::Field,
model_id: ast::ModelId,
field_id: ast::FieldId,
scalar_field_data: &mut ScalarField,
ctx: &mut Context<'_>,
) {
let mapped_name = match visit_map_attribute(ctx) {
Some(name) => name,
None => return,
};
scalar_field_data.mapped_name = Some(mapped_name);
if ctx
.mapped_model_scalar_field_names
.insert((model_id, mapped_name), field_id)
.is_some()
{
ctx.push_error(DatamodelError::new_duplicate_field_error(
ast_model.name(),
ast_field.name(),
ast_field.span(),
));
}
if let Some(field_id) = ctx.names.model_fields.get(&(model_id, mapped_name)) {
// @map only conflicts with _scalar_ fields
if !ctx.types.scalar_fields.contains_key(&(model_id, *field_id)) {
return;
}
match ctx
.types
.scalar_fields
.get(&(model_id, *field_id))
.and_then(|sf| sf.mapped_name)
{
Some(name) if name != mapped_name => {}
_ => ctx.push_error(DatamodelError::new_duplicate_field_error(
ast_model.name(),
ast_field.name(),
ast_field.span(),
)),
}
}
}
pub(super) fn composite_type_field(
ct: &ast::CompositeType,
ast_field: &ast::Field,
ctid: ast::CompositeTypeId,
field_id: ast::FieldId,
field: &mut CompositeTypeField,
ctx: &mut Context<'_>,
) {
let mapped_name_id = match visit_map_attribute(ctx) {
Some(name) => name,
None => return,
};
field.mapped_name = Some(mapped_name_id);
if ctx
.mapped_composite_type_names
.insert((ctid, mapped_name_id), field_id)
.is_some()
{
ctx.push_error(DatamodelError::new_composite_type_duplicate_field_error(
ct.name(),
&ctx[mapped_name_id],
ast_field.span(),
));
}
if let Some(f) = ctx.names.composite_type_fields.get(&(ctid, mapped_name_id)) {
let other_field = &ctx.types.composite_type_fields[&(ctid, *f)];
// We check mapped name collisions above. In this part, if the other
// field has a mapped name, they cannot collide.
if other_field.mapped_name.is_some() {
return;
}
ctx.push_error(DatamodelError::new_composite_type_duplicate_field_error(
ct.name(),
ast_field.name(),
ast_field.span(),
));
}
}
pub(super) fn visit_map_attribute(ctx: &mut Context<'_>) -> Option<StringId> {
match ctx
.visit_default_arg("name")
.map(|value| coerce::string(value, ctx.diagnostics))
{
Ok(Some(name)) => return Some(ctx.interner.intern(name)),
Err(err) => ctx.push_error(err), // not flattened for error handing legacy reasons
Ok(None) => (),
};
None
}