cedar_policy_validator/
err.rs1use std::collections::HashSet;
18
19use cedar_policy_core::{
20 ast::{EntityUID, Name},
21 parser::err::ParseError,
22 transitive_closure,
23};
24use itertools::Itertools;
25use thiserror::Error;
26
27#[derive(Debug, Error)]
28pub enum SchemaError {
29 #[error("JSON Schema file could not be parsed: {0}")]
31 ParseFileFormat(serde_json::Error),
32 #[error("Transitive closure error on action hierarchy: {0}")]
35 ActionTransitiveClosureError(Box<transitive_closure::TcError<EntityUID>>),
36 #[error("Transitive closure error on entity hierarchy: {0}")]
39 EntityTransitiveClosureError(transitive_closure::TcError<Name>),
40 #[error("Unsupported feature used in schema: {0}")]
43 UnsupportedSchemaFeature(UnsupportedFeature),
44 #[error("Undeclared entity types: {0:?}")]
49 UndeclaredEntityTypes(HashSet<String>),
50 #[error("Undeclared actions: {0:?}")]
52 UndeclaredActions(HashSet<String>),
53 #[error("Undeclared common types: {0:?}")]
55 UndeclaredCommonType(HashSet<String>),
56 #[error("Duplicate entity type {0}")]
59 DuplicateEntityType(String),
60 #[error("Duplicate action {0}")]
63 DuplicateAction(String),
64 #[error("Duplicate common type {0}")]
66 DuplicateCommonType(String),
67 #[error("Cycle in action hierarchy")]
69 CycleInActionHierarchy,
70 #[error("Parse error in entity type: {}", Self::format_parse_errs(.0))]
72 EntityTypeParseError(Vec<ParseError>),
73 #[error("Parse error in namespace identifier: {}", Self::format_parse_errs(.0))]
75 NamespaceParseError(Vec<ParseError>),
76 #[error("Parse error in extension type: {}", Self::format_parse_errs(.0))]
78 ExtensionTypeParseError(Vec<ParseError>),
79 #[error("Parse error in common type identifier: {}", Self::format_parse_errs(.0))]
82 CommonTypeParseError(Vec<ParseError>),
83 #[error("Entity type `Action` declared in `entityTypes` list")]
88 ActionEntityTypeDeclared,
89 #[error("Actions declared with `attributes`: [{}]", .0.iter().join(", "))]
92 ActionEntityAttributes(Vec<String>),
93 #[error("{0} is declared with a type other than `Record`")]
94 ContextOrShapeNotRecord(ContextOrShape),
95 #[error("An action entity has an attribute that is an empty set")]
97 ActionEntityAttributeEmptySet,
98 #[error("An action entity has attribute with unsupported type: (escaped expression, entity or extension)")]
100 ActionEntityAttributeUnsupportedType,
101}
102
103impl From<transitive_closure::TcError<EntityUID>> for SchemaError {
104 fn from(e: transitive_closure::TcError<EntityUID>) -> Self {
105 match e {
109 transitive_closure::TcError::MissingTcEdge { .. } => {
110 SchemaError::ActionTransitiveClosureError(Box::new(e))
111 }
112 transitive_closure::TcError::HasCycle { .. } => SchemaError::CycleInActionHierarchy,
113 }
114 }
115}
116
117impl From<serde_json::Error> for SchemaError {
118 fn from(e: serde_json::Error) -> Self {
119 SchemaError::ParseFileFormat(e)
120 }
121}
122
123impl From<transitive_closure::TcError<Name>> for SchemaError {
124 fn from(e: transitive_closure::TcError<Name>) -> Self {
125 SchemaError::EntityTransitiveClosureError(e)
126 }
127}
128
129pub type Result<T> = std::result::Result<T, SchemaError>;
130
131impl SchemaError {
132 fn format_parse_errs(errs: &[ParseError]) -> String {
133 errs.iter().map(|e| e.to_string()).join(", ")
134 }
135}
136
137#[derive(Debug)]
138pub enum ContextOrShape {
139 ActionContext(EntityUID),
140 EntityTypeShape(Name),
141}
142
143impl std::fmt::Display for ContextOrShape {
144 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145 match self {
146 ContextOrShape::ActionContext(action) => write!(f, "Context for action {}", action),
147 ContextOrShape::EntityTypeShape(entity_type) => {
148 write!(f, "Shape for entity type {}", entity_type)
149 }
150 }
151 }
152}
153
154#[derive(Debug)]
155pub enum UnsupportedFeature {
156 OpenRecordsAndEntities,
157}
158
159impl std::fmt::Display for UnsupportedFeature {
160 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
161 match self {
162 UnsupportedFeature::OpenRecordsAndEntities => write!(
163 f,
164 "Records and entities with additional attributes are not yet implemented."
165 ),
166 }
167 }
168}