scuffle_cedar_policy_codegen/
types.rs1use std::collections::{BTreeMap, BTreeSet};
2use std::fmt::Write;
3
4use cedar_policy_core::ast::Id;
5use cedar_policy_core::validator::RawName;
6
7use crate::utils::{to_snake_ident, to_upper_camel_ident};
8
9#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
11pub(crate) struct CedarRef {
12 pub(crate) id: Id,
13 pub(crate) namespace: NamespaceId,
14}
15
16impl From<RawName> for CedarRef {
17 fn from(value: RawName) -> Self {
18 let qualified_value = value.qualify_with(None);
19 Self {
20 id: qualified_value.basename().clone(),
21 namespace: NamespaceId {
22 items: qualified_value.namespace_components().cloned().collect(),
23 },
24 }
25 }
26}
27
28impl CedarRef {
29 pub(crate) fn into_cedar_ty(self) -> CedarType {
31 match self.id.as_ref() {
32 "Bool" => CedarType::Bool,
33 "Long" => CedarType::Long,
34 "String" => CedarType::String,
35 _ => CedarType::Reference(self),
36 }
37 }
38
39 pub(crate) fn ident_path(&self) -> Vec<syn::Ident> {
41 self.namespace
42 .items
43 .iter()
44 .map(to_snake_ident)
45 .chain(std::iter::once(&self.id).map(to_upper_camel_ident))
46 .collect()
47 }
48}
49
50#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Default, Clone)]
52pub(crate) struct NamespaceId {
53 pub items: Vec<Id>,
54}
55
56#[derive(Debug)]
58pub(crate) struct CedarTypeStructField {
59 pub ty: CedarType,
60 pub optional: bool,
61}
62
63#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
65pub(crate) struct ActionEid {
66 pub id: Option<CedarRef>,
67 pub name: String,
68}
69
70#[derive(Debug)]
72pub(crate) enum CedarType {
73 String,
74 Long,
75 Bool,
76 Record {
77 fields: BTreeMap<String, CedarTypeStructField>,
78 allows_additional: bool,
79 },
80 Set(Box<CedarType>),
81 Enum(BTreeSet<String>),
82 Reference(CedarRef),
83 Entity {
84 parents: Vec<CedarRef>,
85 shape: Box<CedarType>,
86 tag_type: Option<Box<CedarType>>,
87 },
88}
89
90impl CedarType {
91 pub(crate) fn is_entity(&self) -> bool {
93 matches!(self, Self::Entity { .. } | Self::Enum(_))
94 }
95}
96
97impl std::fmt::Display for ActionEid {
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 if let Some(id) = &self.id {
100 id.fmt(f)?;
101 f.write_str("::")?;
102 }
103
104 f.write_char('"')?;
105 f.write_str(&self.name)?;
106 f.write_char('"')
107 }
108}
109
110impl std::fmt::Debug for NamespaceId {
111 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112 write!(f, "NamespaceId(\"{self}\")")
113 }
114}
115
116impl std::fmt::Display for CedarRef {
117 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118 self.namespace.fmt(f)?;
119 if !self.namespace.items.is_empty() {
120 f.write_str("::")?;
121 }
122 self.id.fmt(f)
123 }
124}
125
126impl std::fmt::Display for NamespaceId {
127 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128 let mut first = true;
129 for part in &self.items {
130 if !first {
131 f.write_str("::")?;
132 }
133 part.fmt(f)?;
134 first = false;
135 }
136 Ok(())
137 }
138}