Skip to content

Commit 0dec8ba

Browse files
authored
Merge pull request #24 from Virtual-Repetitions/join-team-with-code
bumping to 0.29
2 parents 3415193 + 0fe0b30 commit 0dec8ba

25 files changed

Lines changed: 1534 additions & 388 deletions

File tree

Cargo.lock

Lines changed: 385 additions & 357 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[workspace.package]
2-
version = "0.28.1"
2+
version = "0.29.0"
33
edition = "2024"
44

55
# See https://github.com/mozilla/application-services/blob/main/Cargo.toml for the reasons why we use this structure

crates/builder/src/lib.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,17 @@ pub fn load_subsystem_builders(
179179

180180
if builder.is_none() {
181181
// Then try to load a dynamic builder
182-
subsystem_builders.push(
183-
core_plugin_interface::interface::load_subsystem_builder(
184-
&entry.path(),
185-
)?,
186-
);
182+
match core_plugin_interface::interface::load_subsystem_builder(
183+
&entry.path(),
184+
) {
185+
Ok(builder) => subsystem_builders.push(builder),
186+
Err(err) => {
187+
eprintln!(
188+
"Skipping dynamic subsystem builder {:?} due to error: {err}",
189+
entry.path()
190+
);
191+
}
192+
}
187193
};
188194
}
189195
}

crates/postgres-subsystem/postgres-builder/src/plugin.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@ impl SubsystemBuilder for PostgresSubsystemBuilder {
8484
mapped_params: None,
8585
},
8686
),
87+
(
88+
"relationPath",
89+
AnnotationSpec {
90+
targets: &[AnnotationTarget::Field],
91+
no_params: false,
92+
single_params: true,
93+
mapped_params: None,
94+
},
95+
),
8796
(
8897
"dbtype",
8998
AnnotationSpec {

crates/postgres-subsystem/postgres-core-builder/src/resolved_builder.rs

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,71 @@ fn resolve_composite_type_fields(
758758
},
759759
};
760760

761+
let relation_path = field.annotations.get("relationPath").and_then(|params| {
762+
match params {
763+
AstAnnotationParams::Single(expr, _) => match expr {
764+
AstExpr::StringLiteral(path, _) => {
765+
let segments: Vec<String> = path
766+
.split('.')
767+
.map(|segment| segment.trim().to_string())
768+
.filter(|segment| !segment.is_empty())
769+
.collect();
770+
771+
if segments.is_empty() {
772+
errors.push(Diagnostic {
773+
level: Level::Error,
774+
message: format!(
775+
"@relationPath for field '{}' must contain at least one segment",
776+
field.name
777+
),
778+
code: Some("C000".to_string()),
779+
spans: vec![SpanLabel {
780+
span: field.span,
781+
style: SpanStyle::Primary,
782+
label: None,
783+
}],
784+
});
785+
None
786+
} else {
787+
Some(segments)
788+
}
789+
}
790+
_ => {
791+
errors.push(Diagnostic {
792+
level: Level::Error,
793+
message: format!(
794+
"@relationPath for field '{}' must be a string literal",
795+
field.name
796+
),
797+
code: Some("C000".to_string()),
798+
spans: vec![SpanLabel {
799+
span: field.span,
800+
style: SpanStyle::Primary,
801+
label: None,
802+
}],
803+
});
804+
None
805+
}
806+
},
807+
_ => {
808+
errors.push(Diagnostic {
809+
level: Level::Error,
810+
message: format!(
811+
"@relationPath for field '{}' must use the syntax @relationPath(\"segment1.segment2\")",
812+
field.name
813+
),
814+
code: Some("C000".to_string()),
815+
spans: vec![SpanLabel {
816+
span: field.span,
817+
style: SpanStyle::Primary,
818+
label: None,
819+
}],
820+
});
821+
None
822+
}
823+
}
824+
});
825+
761826
let typ = resolve_field_type(
762827
&field.typ.to_typ(&typechecked_system.types),
763828
&typechecked_system.types,
@@ -768,6 +833,23 @@ fn resolve_composite_type_fields(
768833
.as_ref()
769834
.map(|v| resolve_field_default_type(v, &typ, errors));
770835

836+
if relation_path.is_some() && field.annotations.get("computed").is_some() {
837+
errors.push(Diagnostic {
838+
level: Level::Error,
839+
message: format!(
840+
"Field '{}' cannot use both @computed and @relationPath",
841+
field.name
842+
),
843+
code: Some("C000".to_string()),
844+
spans: vec![SpanLabel {
845+
span: field.span,
846+
style: SpanStyle::Primary,
847+
label: None,
848+
}],
849+
});
850+
continue;
851+
}
852+
771853
if let Some(computed_params) = field.annotations.get("computed") {
772854
let resolved_computed =
773855
match parse_computed_field(module_base_path, field, computed_params, errors) {
@@ -791,14 +873,29 @@ fn resolve_composite_type_fields(
791873
default_value: None,
792874
update_sync: false,
793875
readonly: true,
876+
relation_path: None,
794877
doc_comments: field.doc_comments.clone(),
795878
computed: Some(resolved_computed),
796879
span: field.span,
797880
});
798881
continue;
799882
}
800883

801-
let column_info = compute_column_info(ct, field, &typechecked_system.types, table_managed);
884+
if relation_path.is_some() {
885+
readonly = true;
886+
}
887+
888+
let column_info = if relation_path.is_some() {
889+
Ok(ColumnInfo {
890+
names: vec![],
891+
self_column: false,
892+
unique_constraints: vec![],
893+
indices: vec![],
894+
cardinality: None,
895+
})
896+
} else {
897+
compute_column_info(ct, field, &typechecked_system.types, table_managed)
898+
};
802899

803900
let ColumnInfo {
804901
names: column_names,
@@ -860,6 +957,7 @@ fn resolve_composite_type_fields(
860957
default_value: field_default,
861958
update_sync,
862959
readonly,
960+
relation_path,
863961
doc_comments: field.doc_comments.clone(),
864962
computed: None,
865963
span: field.span,

crates/postgres-subsystem/postgres-core-builder/src/resolved_type.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ pub struct ResolvedField {
9494
pub default_value: Option<ResolvedFieldDefault>,
9595
pub update_sync: bool,
9696
pub readonly: bool,
97+
#[serde(skip_serializing_if = "Option::is_none")]
98+
pub relation_path: Option<Vec<String>>,
9799
pub doc_comments: Option<String>,
98100
pub computed: Option<ResolvedComputedField>,
99101
#[serde(skip_serializing)]

0 commit comments

Comments
 (0)