cedar_policy_core/transitive_closure/err.rs
1/*
2 * Copyright Cedar Contributors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17use miette::Diagnostic;
18use std::fmt::Debug;
19use std::fmt::Display;
20use thiserror::Error;
21
22/// Error type for errors raised during transitive closure computation. This
23/// error type is parametrized by a type `K` which is the type of a unique
24/// identifier for graph nodes and the type returned by `get_key` on the
25/// `TCNode` trait.
26#[derive(Debug, Diagnostic, Error, PartialEq, Eq)]
27pub enum TcError<K: Debug + Display> {
28 /// Error raised when `TCComputation::EnforceAlreadyComputed` finds that the
29 /// TC was in fact not already computed
30 #[error("expected all transitive edges to exist, but `{}` -> `{}` and `{}` -> `{}` exists, while `{}` -> `{}` does not", .0.child, .0.parent, .0.parent, .0.grandparent, .0.child, .0.grandparent)]
31 MissingTcEdge(MissingTcEdge<K>),
32 /// Error raised when enforce_dag finds that the graph is not a DAG
33 #[error("input graph has a cycle containing vertex `{}`", .0.vertex_with_loop)]
34 HasCycle(HasCycle<K>),
35}
36
37impl<K: Debug + Display> TcError<K> {
38 pub(crate) fn missing_tc_edge(child: K, parent: K, grandparent: K) -> Self {
39 Self::MissingTcEdge(MissingTcEdge {
40 child,
41 parent,
42 grandparent,
43 })
44 }
45
46 pub(crate) fn has_cycle(vertex_with_loop: K) -> Self {
47 Self::HasCycle(HasCycle { vertex_with_loop })
48 }
49}
50
51/// Error raised when `TCComputation::EnforceAlreadyComputed` finds that the
52/// TC was in fact not already computed
53#[derive(Debug, PartialEq, Eq)]
54pub struct MissingTcEdge<K: Debug + Display> {
55 child: K,
56 parent: K,
57 grandparent: K,
58}
59
60/// Error raised when enforce_dag finds that the graph is not a DAG
61#[derive(Debug, PartialEq, Eq)]
62pub struct HasCycle<K: Debug + Display> {
63 /// Because DAG enforcement can only be called after compute_tc/enforce_tc, a cycle will manifest as a vertex with a loop
64 vertex_with_loop: K,
65}
66
67impl<K: Debug + Display> HasCycle<K> {
68 /// Graph vertex that contained a loop
69 pub fn vertex_with_loop(&self) -> &K {
70 &self.vertex_with_loop
71 }
72}
73
74/// Type alias for convenience
75pub type Result<T, K> = std::result::Result<T, TcError<K>>;