1#![allow(clippy::use_self)]
18
19use super::models;
20use cedar_policy_core::{ast, evaluator, extensions};
21use cedar_policy_validator::types;
22
23impl From<&cedar_policy_validator::ValidatorSchema> for models::ValidatorSchema {
24 fn from(v: &cedar_policy_validator::ValidatorSchema) -> Self {
25 Self {
26 entity_types: v
27 .entity_types()
28 .map(|ety| models::EntityTypeWithTypesMap {
29 key: Some(models::EntityType::from(ety.name())),
30 value: Some(models::ValidatorEntityType::from(ety)),
31 })
32 .collect(),
33 action_ids: v
34 .action_ids()
35 .map(|id| models::EntityUidWithActionIdsMap {
36 key: Some(models::EntityUid::from(id.name())),
37 value: Some(models::ValidatorActionId::from(id)),
38 })
39 .collect(),
40 }
41 }
42}
43
44impl From<&models::ValidatorSchema> for cedar_policy_validator::ValidatorSchema {
45 #[allow(clippy::expect_used)]
47 fn from(v: &models::ValidatorSchema) -> Self {
48 Self::new(
49 v.entity_types
50 .iter()
51 .map(|models::EntityTypeWithTypesMap { key, value }| {
52 let key = key.as_ref().expect("key field should exist");
53 let value = value.as_ref().expect("value field should exist");
54 assert_eq!(key, value.name.as_ref().expect("name field should exist"));
55 cedar_policy_validator::ValidatorEntityType::from(value)
56 }),
57 v.action_ids
58 .iter()
59 .map(|models::EntityUidWithActionIdsMap { key, value }| {
60 let key = key.as_ref().expect("key field should exist");
61 let value = value.as_ref().expect("value field should exist");
62 assert_eq!(key, value.name.as_ref().expect("name field should exist"));
63 cedar_policy_validator::ValidatorActionId::from(value)
64 }),
65 )
66 }
67}
68
69impl From<&cedar_policy_validator::ValidationMode> for models::ValidationMode {
70 #[allow(clippy::unimplemented)]
72 fn from(v: &cedar_policy_validator::ValidationMode) -> Self {
73 match v {
74 cedar_policy_validator::ValidationMode::Strict => models::ValidationMode::Strict,
75 cedar_policy_validator::ValidationMode::Permissive => {
76 models::ValidationMode::Permissive
77 }
78 #[cfg(feature = "partial-validate")]
79 cedar_policy_validator::ValidationMode::Partial => unimplemented!(),
80 }
81 }
82}
83
84impl From<&models::ValidationMode> for cedar_policy_validator::ValidationMode {
85 fn from(v: &models::ValidationMode) -> Self {
86 match v {
87 models::ValidationMode::Strict => cedar_policy_validator::ValidationMode::Strict,
88 models::ValidationMode::Permissive => {
89 cedar_policy_validator::ValidationMode::Permissive
90 }
91 }
92 }
93}
94
95impl From<&cedar_policy_validator::ValidatorActionId> for models::ValidatorActionId {
96 fn from(v: &cedar_policy_validator::ValidatorActionId) -> Self {
97 Self {
98 name: Some(models::EntityUid::from(v.name())),
99 applies_to: Some(models::ValidatorApplySpec {
100 principal_apply_spec: v
101 .applies_to_principals()
102 .map(models::EntityType::from)
103 .collect(),
104 resource_apply_spec: v
105 .applies_to_resources()
106 .map(models::EntityType::from)
107 .collect(),
108 }),
109 descendants: v.descendants().map(models::EntityUid::from).collect(),
110 context: Some(models::Type::from(v.context())),
111 attribute_types: Some(models::Attributes::from(v.attribute_types())),
112 attributes: v
113 .attributes()
114 .map(|(k, v)| {
115 let value =
116 models::Expr::from(&ast::Expr::from(ast::PartialValue::from(v.to_owned())));
117 (k.to_string(), value)
118 })
119 .collect(),
120 }
121 }
122}
123
124impl From<&models::ValidatorActionId> for cedar_policy_validator::ValidatorActionId {
125 #[allow(clippy::expect_used)]
127 fn from(v: &models::ValidatorActionId) -> Self {
128 let extensions_none = extensions::Extensions::none();
129 let eval = evaluator::RestrictedEvaluator::new(extensions_none);
130 Self::new(
131 ast::EntityUID::from(v.name.as_ref().expect("name field should exist")),
132 v.applies_to
133 .as_ref()
134 .expect("applies_to field should exist")
135 .principal_apply_spec
136 .iter()
137 .map(ast::EntityType::from),
138 v.applies_to
139 .as_ref()
140 .expect("applies_to field should exist")
141 .resource_apply_spec
142 .iter()
143 .map(ast::EntityType::from),
144 v.descendants.iter().map(ast::EntityUID::from),
145 types::Type::from(v.context.as_ref().expect("context field should exist")),
146 types::Attributes::from(
147 v.attribute_types
148 .as_ref()
149 .expect("attribute_types field should exist"),
150 ),
151 v.attributes
152 .iter()
153 .map(|(k, v)| {
154 let pval = eval
155 .partial_interpret(
156 ast::BorrowedRestrictedExpr::new(&ast::Expr::from(v))
157 .expect("RestrictedExpr"),
158 )
159 .expect("interpret on RestrictedExpr");
160 (k.into(), pval.into())
161 })
162 .collect(),
163 )
164 }
165}
166
167impl From<&cedar_policy_validator::ValidatorEntityType> for models::ValidatorEntityType {
168 fn from(v: &cedar_policy_validator::ValidatorEntityType) -> Self {
169 Self {
170 name: Some(models::EntityType::from(v.name())),
171 descendants: v.descendants.iter().map(models::EntityType::from).collect(),
172 attributes: Some(models::Attributes::from(v.attributes())),
173 open_attributes: models::OpenTag::from(&v.open_attributes()).into(),
174 tags: v.tag_type().map(|tags| models::Tag {
175 optional_type: Some(models::Type::from(tags)),
176 }),
177 }
178 }
179}
180
181impl From<&models::ValidatorEntityType> for cedar_policy_validator::ValidatorEntityType {
182 #[allow(clippy::expect_used)]
184 fn from(v: &models::ValidatorEntityType) -> Self {
185 Self::new(
186 ast::EntityType::from(v.name.as_ref().expect("name field should exist")),
187 v.descendants.iter().map(ast::EntityType::from),
188 types::Attributes::from(
189 v.attributes
190 .as_ref()
191 .expect("attributes field should exist"),
192 ),
193 types::OpenTag::from(
194 &models::OpenTag::try_from(v.open_attributes).expect("decode should succeed"),
195 ),
196 v.tags
197 .as_ref()
198 .and_then(|tags| tags.optional_type.as_ref().map(types::Type::from)),
199 )
200 }
201}
202
203impl From<&models::Type> for types::Type {
204 #[allow(clippy::expect_used)]
206 fn from(v: &models::Type) -> Self {
207 match v.data.as_ref().expect("data field should exist") {
208 models::r#type::Data::Ty(vt) => {
209 match models::r#type::Ty::try_from(vt.to_owned()).expect("decode should succeed") {
210 models::r#type::Ty::Never => types::Type::Never,
211 models::r#type::Ty::True => types::Type::True,
212 models::r#type::Ty::False => types::Type::False,
213 models::r#type::Ty::EmptySetType => types::Type::Set { element_type: None },
214 models::r#type::Ty::Bool => types::Type::primitive_boolean(),
215 models::r#type::Ty::String => types::Type::primitive_string(),
216 models::r#type::Ty::Long => types::Type::primitive_long(),
217 }
218 }
219 models::r#type::Data::SetType(tt) => types::Type::Set {
220 element_type: Some(Box::new(types::Type::from(tt.as_ref()))),
221 },
222 models::r#type::Data::EntityOrRecord(er) => {
223 types::Type::EntityOrRecord(types::EntityRecordKind::from(er))
224 }
225 models::r#type::Data::Name(name) => types::Type::ExtensionType {
226 name: ast::Name::from(name),
227 },
228 }
229 }
230}
231
232impl From<&types::Type> for models::Type {
233 #[allow(clippy::expect_used)]
235 fn from(v: &types::Type) -> Self {
236 match v {
237 types::Type::Never => Self {
238 data: Some(models::r#type::Data::Ty(models::r#type::Ty::Never.into())),
239 },
240 types::Type::True => Self {
241 data: Some(models::r#type::Data::Ty(models::r#type::Ty::True.into())),
242 },
243
244 types::Type::False => Self {
245 data: Some(models::r#type::Data::Ty(models::r#type::Ty::False.into())),
246 },
247 types::Type::Primitive { primitive_type } => match primitive_type {
248 types::Primitive::Bool => Self {
249 data: Some(models::r#type::Data::Ty(models::r#type::Ty::Bool.into())),
250 },
251 types::Primitive::Long => Self {
252 data: Some(models::r#type::Data::Ty(models::r#type::Ty::Long.into())),
253 },
254 types::Primitive::String => Self {
255 data: Some(models::r#type::Data::Ty(models::r#type::Ty::String.into())),
256 },
257 },
258 types::Type::Set { element_type } => Self {
259 data: Some(models::r#type::Data::SetType(Box::new(models::Type::from(
260 element_type
261 .as_ref()
262 .expect("element_type field should exist")
263 .as_ref(),
264 )))),
265 },
266 types::Type::EntityOrRecord(er) => Self {
267 data: Some(models::r#type::Data::EntityOrRecord(
268 models::EntityRecordKind::from(er),
269 )),
270 },
271 types::Type::ExtensionType { name } => Self {
272 data: Some(models::r#type::Data::Name(models::Name::from(name))),
273 },
274 }
275 }
276}
277
278impl From<&models::Attributes> for types::Attributes {
279 fn from(v: &models::Attributes) -> Self {
280 Self::with_attributes(
281 v.attrs
282 .iter()
283 .map(|(k, v)| (k.into(), types::AttributeType::from(v))),
284 )
285 }
286}
287
288impl From<&types::Attributes> for models::Attributes {
289 fn from(v: &types::Attributes) -> Self {
290 Self {
291 attrs: v
292 .iter()
293 .map(|(k, v)| (k.to_string(), models::AttributeType::from(v)))
294 .collect(),
295 }
296 }
297}
298
299impl From<&models::OpenTag> for types::OpenTag {
300 fn from(v: &models::OpenTag) -> Self {
301 match v {
302 models::OpenTag::OpenAttributes => types::OpenTag::OpenAttributes,
303 models::OpenTag::ClosedAttributes => types::OpenTag::ClosedAttributes,
304 }
305 }
306}
307
308impl From<&types::OpenTag> for models::OpenTag {
309 fn from(v: &types::OpenTag) -> Self {
310 match v {
311 types::OpenTag::OpenAttributes => models::OpenTag::OpenAttributes,
312 types::OpenTag::ClosedAttributes => models::OpenTag::ClosedAttributes,
313 }
314 }
315}
316
317impl From<&models::EntityRecordKind> for types::EntityRecordKind {
318 #[allow(clippy::expect_used)]
320 fn from(v: &models::EntityRecordKind) -> Self {
321 match v.data.as_ref().expect("data field should exist") {
322 models::entity_record_kind::Data::Ty(ty) => {
323 match models::entity_record_kind::Ty::try_from(ty.to_owned())
324 .expect("decode should succeed")
325 {
326 models::entity_record_kind::Ty::AnyEntity => Self::AnyEntity,
327 }
328 }
329 models::entity_record_kind::Data::Record(p_record) => Self::Record {
330 attrs: types::Attributes::from(
331 p_record.attrs.as_ref().expect("attrs field should exist"),
332 ),
333 open_attributes: types::OpenTag::from(
334 &models::OpenTag::try_from(p_record.open_attributes)
335 .expect("decode should succeed"),
336 ),
337 },
338 models::entity_record_kind::Data::Entity(p_entity) => {
339 Self::Entity(types::EntityLUB::single_entity(ast::EntityType::from(
340 p_entity.e.as_ref().expect("e field should exist"),
341 )))
342 }
343 models::entity_record_kind::Data::ActionEntity(p_action_entity) => Self::ActionEntity {
344 name: ast::EntityType::from(
345 p_action_entity
346 .name
347 .as_ref()
348 .expect("name field should exist"),
349 ),
350 attrs: types::Attributes::from(
351 p_action_entity
352 .attrs
353 .as_ref()
354 .expect("attrs field should exist"),
355 ),
356 },
357 }
358 }
359}
360
361impl From<&types::EntityRecordKind> for models::EntityRecordKind {
362 #[allow(clippy::expect_used)]
364 fn from(v: &types::EntityRecordKind) -> Self {
365 let data = match v {
366 types::EntityRecordKind::Record {
367 attrs,
368 open_attributes,
369 } => models::entity_record_kind::Data::Record(models::entity_record_kind::Record {
370 attrs: Some(models::Attributes::from(attrs)),
371 open_attributes: models::OpenTag::from(open_attributes).into(),
372 }),
373 types::EntityRecordKind::AnyEntity => models::entity_record_kind::Data::Ty(
374 models::entity_record_kind::Ty::AnyEntity.into(),
375 ),
376 types::EntityRecordKind::Entity(e) => {
377 models::entity_record_kind::Data::Entity(models::entity_record_kind::Entity {
378 e: Some(models::EntityType::from(
379 &e.clone()
380 .into_single_entity()
381 .expect("will be single EntityType"),
382 )),
383 })
384 }
385 types::EntityRecordKind::ActionEntity { name, attrs } => {
386 models::entity_record_kind::Data::ActionEntity(
387 models::entity_record_kind::ActionEntity {
388 name: Some(models::EntityType::from(name)),
389 attrs: Some(models::Attributes::from(attrs)),
390 },
391 )
392 }
393 };
394 Self { data: Some(data) }
395 }
396}
397
398impl From<&models::AttributeType> for types::AttributeType {
399 #[allow(clippy::expect_used)]
401 fn from(v: &models::AttributeType) -> Self {
402 Self {
403 attr_type: types::Type::from(
404 v.attr_type.as_ref().expect("attr_type field should exist"),
405 ),
406 is_required: v.is_required,
407 }
408 }
409}
410
411impl From<&types::AttributeType> for models::AttributeType {
412 fn from(v: &types::AttributeType) -> Self {
413 Self {
414 attr_type: Some(models::Type::from(&v.attr_type)),
415 is_required: v.is_required,
416 }
417 }
418}