1use crate::ids::{QualifiedTypeName, SchemaNodeIrId, TypeId};
2
3#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
4pub enum IrBuildError {
5 #[error("type `{type_id}` declares both proxy and opaque targets")]
6 ProxyOpaqueConflict { type_id: String },
7
8 #[error(
9 "variant `{variant}` in type `{type_id}` sets allow_unknown_fields on a non-record variant"
10 )]
11 VariantAllowUnknownFieldsInvalid { type_id: String, variant: String },
12
13 #[error("field `{field}` in type `{type_id}` has conflicting mode attrs: {detail}")]
14 FieldModeConflict {
15 type_id: String,
16 field: String,
17 detail: String,
18 },
19
20 #[error("field `{field}` in type `{type_id}` cannot use `via` with flatten/flatten_ext")]
21 ViaWithFlatten { type_id: String, field: String },
22
23 #[error("field `{field}` in type `{type_id}` cannot use default with flatten/flatten_ext")]
24 DefaultWithFlatten { type_id: String, field: String },
25
26 #[error(
27 "field `{field}` in type `{type_id}` uses flatten in parse_ext container; use flatten_ext"
28 )]
29 FlattenInParseExt { type_id: String, field: String },
30
31 #[error("name_index entry `{name:?}` references missing type `{missing}`")]
32 NameIndexMissingType {
33 name: QualifiedTypeName,
34 missing: String,
35 },
36
37 #[error(
38 "name_index entry `{name:?}` points to type `{pointed}` but type carries schema name `{actual:?}`"
39 )]
40 NameIndexMismatch {
41 name: QualifiedTypeName,
42 pointed: String,
43 actual: Option<QualifiedTypeName>,
44 },
45
46 #[error("type `{type_id}` root node `{node:?}` does not exist")]
47 MissingSemanticRoot {
48 type_id: String,
49 node: SchemaNodeIrId,
50 },
51
52 #[error(
53 "type `{type_id}` node `{node:?}` references missing schema node `{target:?}` at {path}"
54 )]
55 MissingSchemaNodeReference {
56 type_id: String,
57 node: SchemaNodeIrId,
58 target: SchemaNodeIrId,
59 path: String,
60 },
61
62 #[error(
63 "type `{type_id}` union node `{node:?}` has policy entry `{variant}` not present in variants"
64 )]
65 UnionPolicyUnknownVariant {
66 type_id: String,
67 node: SchemaNodeIrId,
68 variant: String,
69 },
70
71 #[error(
72 "type `{type_id}` exists in name_index but is duplicated for schema name `{schema_name:?}`"
73 )]
74 DuplicateSchemaName {
75 type_id: String,
76 schema_name: QualifiedTypeName,
77 },
78
79 #[error("type `{type_id}` is missing from module roots while declared as root")]
80 RootMissingType { type_id: String },
81
82 #[error("codegen override at `{path}` in type `{type_id}` cannot be empty")]
83 EmptyCodegenOverride { type_id: String, path: String },
84
85 #[error("root codegen override at `{path}` cannot be empty")]
86 EmptyRootCodegenOverride { path: String },
87
88 #[error(
89 "root codegen type name `{root_type_name}` conflicts with root type `{type_id}` codegen type name `{type_type_name}`"
90 )]
91 RootTypeNameConflict {
92 type_id: String,
93 root_type_name: String,
94 type_type_name: String,
95 },
96}
97
98#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
99#[error("structural mismatch at {path}: {message}")]
100pub struct StructuralDiff {
101 pub path: String,
102 pub message: String,
103}
104
105impl StructuralDiff {
106 pub fn new(path: impl Into<String>, message: impl Into<String>) -> Self {
107 Self {
108 path: path.into(),
109 message: message.into(),
110 }
111 }
112}
113
114pub fn type_id_string(id: &TypeId) -> String {
115 id.0.clone()
116}