cream_core/
schema.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{declare_resource_type, declare_schema, meta::Meta, reference::Reference};
4
5declare_schema!(SchemaSchema = "urn:ietf:params:scim:schemas:core:2.0:Schema");
6declare_resource_type!(SchemaResourceType = "Schema");
7
8/// A SCIM schema
9#[derive(Serialize, Deserialize, Debug, Clone)]
10#[serde(rename_all = "camelCase")]
11pub struct Schema {
12    /// ["urn:ietf:params:scim:schemas:core:2.0:Schema"]
13    #[serde(skip_deserializing)]
14    pub schemas: [SchemaSchema; 1],
15    /// The unique identifier for the schema.
16    pub id: String,
17    /// The name of the schema.
18    pub name: String,
19    /// A human-readable description of the schema.
20    pub description: String,
21    /// A list of attributes that form the schema.
22    pub attributes: Vec<Attribute>,
23    /// Metadata about the schema.
24    #[serde(skip_deserializing)]
25    pub meta: Meta<SchemaResourceType>,
26}
27
28impl Schema {
29    /// Adds the location metadata to this schema.
30    pub fn locate(&mut self) {
31        self.meta.location = Some(Reference::new_relative(&format!("/Schemas/{}", self.id)));
32    }
33}
34
35/// A single attribute of a SCIM schema.
36#[derive(Serialize, Deserialize, Debug, Clone)]
37#[serde(rename_all = "camelCase")]
38pub struct Attribute {
39    /// The name of the attribute.
40    pub name: String,
41    /// The data type of the attribute.
42    #[serde(rename = "type")]
43    pub type_: Type,
44    /// Whether the attribute is multi-valued.
45    #[serde(default)]
46    pub multi_valued: bool,
47    /// A human-readable description of the attribute.
48    #[serde(default)]
49    pub description: String,
50    /// Whether the attribute is required.
51    #[serde(default)]
52    pub required: bool,
53    /// A list of canonical values for the attribute.
54    #[serde(default, skip_serializing_if = "Option::is_none")]
55    pub canonical_values: Option<Vec<String>>,
56    /// Whether the attribute is case-sensitive.
57    #[serde(default)]
58    pub case_exact: bool,
59    /// The mutability of the attribute.
60    #[serde(default)]
61    pub mutability: Mutability,
62    /// When the attribute is returned.
63    #[serde(default)]
64    pub returned: Returned,
65    /// The uniqueness of the attribute.
66    #[serde(default)]
67    pub uniqueness: Uniqueness,
68    /// If this attribute is a reference, the types of resources it references.
69    #[serde(default, skip_serializing_if = "Option::is_none")]
70    pub reference_types: Option<Vec<String>>,
71    /// If this attribute is a complex type, the sub-attributes that form it.
72    #[serde(default, skip_serializing_if = "Option::is_none")]
73    pub sub_attributes: Option<Vec<Attribute>>,
74}
75
76impl Attribute {
77    /// Construct a new attribute.
78    pub fn new(name: String, type_: Type) -> Self {
79        Self {
80            name,
81            type_,
82            multi_valued: false,
83            description: "".into(),
84            required: false,
85            canonical_values: None,
86            case_exact: false,
87            mutability: Mutability::ReadWrite,
88            returned: Returned::Default,
89            uniqueness: Uniqueness::None,
90            reference_types: None,
91            sub_attributes: None,
92        }
93    }
94    /// Set whether the attribute is multi-valued.
95    pub fn multi_valued(mut self) -> Self {
96        self.multi_valued = true;
97        self
98    }
99    /// Set whether the attribute is required.
100    pub fn required(mut self) -> Self {
101        self.required = true;
102        self
103    }
104    /// Set whether the attribute is case-sensitive.
105    pub fn case_exact(mut self) -> Self {
106        self.case_exact = true;
107        self
108    }
109    /// Set the sub-attributes of this attribute.
110    pub fn sub_attributes(mut self, sub_attributes: Vec<Attribute>) -> Self {
111        self.sub_attributes = Some(sub_attributes);
112        self
113    }
114    /// Set this attribute as immutable
115    pub fn immutable(mut self) -> Self {
116        self.mutability = Mutability::Immutable;
117        self
118    }
119    /// Set this attribute as read-only
120    pub fn read_only(mut self) -> Self {
121        self.mutability = Mutability::ReadOnly;
122        self
123    }
124    /// Set this attribute as write-only
125    pub fn write_only(mut self) -> Self {
126        self.mutability = Mutability::WriteOnly;
127        self
128    }
129    /// Set this attribute as always returned
130    pub fn always_returned(mut self) -> Self {
131        self.returned = Returned::Always;
132        self
133    }
134    /// Set this attribute as never returned
135    pub fn never_returned(mut self) -> Self {
136        self.returned = Returned::Never;
137        self
138    }
139    /// Set this attribute as returned on request
140    pub fn returned_on_request(mut self) -> Self {
141        self.returned = Returned::Request;
142        self
143    }
144    /// Set this attribute as unique on this server
145    pub fn unique(mut self) -> Self {
146        self.uniqueness = Uniqueness::Server;
147        self
148    }
149    /// Set this attribute as globally unique
150    pub fn globally_unique(mut self) -> Self {
151        self.uniqueness = Uniqueness::Global;
152        self
153    }
154    /// Set the types of resources this attribute can reference.
155    pub fn reference_types(mut self, reference_types: Vec<String>) -> Self {
156        self.reference_types = Some(reference_types);
157        self
158    }
159}
160
161/// The mutability of an attribute.
162#[allow(unused)]
163#[derive(Serialize, Deserialize, Debug, Clone)]
164#[serde(rename_all = "camelCase")]
165pub enum Mutability {
166    /// Clients can only read this attribute.
167    ReadOnly,
168    /// Clients can read and write this attribute (default).
169    ReadWrite,
170    /// Clients can set this value on creation, but not update it.
171    Immutable,
172    /// Clients can write this attribute, but not read it.
173    WriteOnly,
174}
175
176impl Default for Mutability {
177    fn default() -> Self {
178        Self::ReadWrite
179    }
180}
181
182/// When an attribute is returned.
183#[allow(unused)]
184#[derive(Serialize, Deserialize, Debug, Clone)]
185#[serde(rename_all = "camelCase")]
186pub enum Returned {
187    /// The attribute is always returned.
188    Always,
189    /// The attribute is never returned.
190    Never,
191    /// The attribute is returned by default (default).
192    Default,
193    /// The attribute is returned on request.
194    Request,
195}
196
197impl Default for Returned {
198    fn default() -> Self {
199        Self::Default
200    }
201}
202
203/// The uniqueness of an attribute.
204#[allow(unused)]
205#[derive(Serialize, Deserialize, Debug, Clone)]
206#[serde(rename_all = "camelCase")]
207pub enum Uniqueness {
208    /// The attribute is not unique (default).
209    None,
210    /// The attribute is unique on this server.
211    Server,
212    /// The attribute is globally unique.
213    Global,
214}
215
216impl Default for Uniqueness {
217    fn default() -> Self {
218        Self::None
219    }
220}
221
222/// The data type of an attribute.
223#[allow(unused)]
224#[derive(Serialize, Deserialize, Debug, Clone)]
225#[serde(rename_all = "camelCase")]
226pub enum Type {
227    /// A string.
228    String,
229    /// A boolean.
230    Boolean,
231    /// A decimal number.
232    Decimal,
233    /// An integer.
234    Integer,
235    /// A date and time.
236    DateTime,
237    /// Binary data (encoded in base64).
238    Binary,
239    /// A reference to another resource or external URL.
240    Reference,
241    /// A complex type with sub-attributes.
242    Complex,
243}
244
245impl Default for Type {
246    fn default() -> Self {
247        Self::String
248    }
249}