cedar_policy/proto/
api.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 super::super::api;
18use super::{models, traits};
19
20/// Macro that implements From<> both ways for cases where the `A` type is a
21/// simple wrapper around a different type `C` which already has From<>
22/// conversions both ways with `B`
23macro_rules! standard_conversions {
24    ( $A:ty, $A_expr:expr, $B:ty ) => {
25        impl From<&$A> for $B {
26            fn from(v: &$A) -> $B {
27                Self::from(&v.0)
28            }
29        }
30
31        impl From<&$B> for $A {
32            fn from(v: &$B) -> $A {
33                $A_expr(v.into())
34            }
35        }
36    };
37}
38
39// standard conversions
40
41standard_conversions!(api::Entity, api::Entity, models::Entity);
42standard_conversions!(api::Entities, api::Entities, models::Entities);
43standard_conversions!(api::Schema, api::Schema, models::ValidatorSchema);
44standard_conversions!(api::EntityTypeName, api::EntityTypeName, models::Name);
45standard_conversions!(api::EntityNamespace, api::EntityNamespace, models::Name);
46standard_conversions!(api::Expression, api::Expression, models::Expr);
47standard_conversions!(api::Request, api::Request, models::Request);
48
49// nonstandard conversions
50
51impl From<&api::Template> for models::TemplateBody {
52    fn from(v: &api::Template) -> Self {
53        Self::from(&v.ast)
54    }
55}
56
57impl From<&models::TemplateBody> for api::Template {
58    fn from(v: &models::TemplateBody) -> Self {
59        Self::from_ast(v.into())
60    }
61}
62
63impl From<&api::Policy> for models::LiteralPolicy {
64    fn from(v: &api::Policy) -> Self {
65        Self::from(&v.ast)
66    }
67}
68
69impl TryFrom<&models::LiteralPolicy> for api::Policy {
70    type Error = cedar_policy_core::ast::ReificationError;
71    fn try_from(v: &models::LiteralPolicy) -> Result<Self, Self::Error> {
72        let p = cedar_policy_core::ast::Policy::try_from(v)?;
73        Ok(Self::from_ast(p))
74    }
75}
76
77impl From<&api::PolicySet> for models::LiteralPolicySet {
78    fn from(v: &api::PolicySet) -> Self {
79        Self::from(&v.ast)
80    }
81}
82
83impl TryFrom<&models::LiteralPolicySet> for api::PolicySet {
84    type Error = api::PolicySetError;
85    fn try_from(v: &models::LiteralPolicySet) -> Result<Self, Self::Error> {
86        // PANIC SAFETY: experimental feature
87        #[allow(clippy::expect_used)]
88        Self::from_ast(
89            v.try_into()
90                .expect("proto-encoded policy set should be a valid policy set"),
91        )
92    }
93}
94
95/// Macro that implements `traits::Protobuf` for cases where From<> conversions
96/// exist both ways between the api type `$api` and the protobuf model type `$model`
97macro_rules! standard_protobuf_impl {
98    ( $api:ty, $model:ty ) => {
99        impl traits::Protobuf for $api {
100            fn encode(&self) -> Vec<u8> {
101                traits::encode_to_vec::<$model>(self)
102            }
103            fn decode(buf: impl prost::bytes::Buf) -> Result<Self, prost::DecodeError> {
104                traits::decode::<$model, _>(buf)
105            }
106        }
107    };
108}
109
110// standard implementations of `traits::Protobuf`
111
112standard_protobuf_impl!(api::Entity, models::Entity);
113standard_protobuf_impl!(api::Entities, models::Entities);
114standard_protobuf_impl!(api::Schema, models::ValidatorSchema);
115standard_protobuf_impl!(api::EntityTypeName, models::Name);
116standard_protobuf_impl!(api::EntityNamespace, models::Name);
117standard_protobuf_impl!(api::Template, models::TemplateBody);
118standard_protobuf_impl!(api::Expression, models::Expr);
119standard_protobuf_impl!(api::Request, models::Request);
120
121// nonstandard implementations of `traits::Protobuf`
122
123impl traits::Protobuf for api::PolicySet {
124    fn encode(&self) -> Vec<u8> {
125        traits::encode_to_vec::<models::LiteralPolicySet>(self)
126    }
127    fn decode(buf: impl prost::bytes::Buf) -> Result<Self, prost::DecodeError> {
128        // PANIC SAFETY: experimental feature
129        #[allow(clippy::expect_used)]
130        Ok(
131            traits::try_decode::<models::LiteralPolicySet, _, Self>(buf)?
132                .expect("protobuf-encoded policy set should be a valid policy set"),
133        )
134    }
135}
136
137impl traits::Protobuf for api::Policy {
138    fn encode(&self) -> Vec<u8> {
139        traits::encode_to_vec::<models::LiteralPolicy>(self)
140    }
141    fn decode(buf: impl prost::bytes::Buf) -> Result<Self, prost::DecodeError> {
142        // PANIC SAFETY: experimental feature
143        #[allow(clippy::expect_used)]
144        Ok(traits::try_decode::<models::LiteralPolicy, _, Self>(buf)?
145            .expect("protobuf-encoded policy should be a valid policy"))
146    }
147}