use serde::{Deserialize, Serialize};
use crate::{declare_resource_type, declare_schema, meta::Meta, reference::Reference};
declare_schema!(SchemaSchema = "urn:ietf:params:scim:schemas:core:2.0:Schema");
declare_resource_type!(SchemaResourceType = "Schema");
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Schema {
#[serde(skip_deserializing)]
pub schemas: [SchemaSchema; 1],
pub id: String,
pub name: String,
pub description: String,
pub attributes: Vec<Attribute>,
#[serde(skip_deserializing)]
pub meta: Meta<SchemaResourceType>,
}
impl Schema {
pub fn locate(&mut self) {
self.meta.location = Some(Reference::new_relative(&format!("/Schemas/{}", self.id)));
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Attribute {
pub name: String,
#[serde(rename = "type")]
pub type_: Type,
#[serde(default)]
pub multi_valued: bool,
#[serde(default)]
pub description: String,
#[serde(default)]
pub required: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub canonical_values: Option<Vec<String>>,
#[serde(default)]
pub case_exact: bool,
#[serde(default)]
pub mutability: Mutability,
#[serde(default)]
pub returned: Returned,
#[serde(default)]
pub uniqueness: Uniqueness,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reference_types: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub sub_attributes: Option<Vec<Attribute>>,
}
impl Attribute {
pub fn new(name: String, type_: Type) -> Self {
Self {
name,
type_,
multi_valued: false,
description: "".into(),
required: false,
canonical_values: None,
case_exact: false,
mutability: Mutability::ReadWrite,
returned: Returned::Default,
uniqueness: Uniqueness::None,
reference_types: None,
sub_attributes: None,
}
}
pub fn multi_valued(mut self) -> Self {
self.multi_valued = true;
self
}
pub fn required(mut self) -> Self {
self.required = true;
self
}
pub fn case_exact(mut self) -> Self {
self.case_exact = true;
self
}
pub fn sub_attributes(mut self, sub_attributes: Vec<Attribute>) -> Self {
self.sub_attributes = Some(sub_attributes);
self
}
pub fn immutable(mut self) -> Self {
self.mutability = Mutability::Immutable;
self
}
pub fn read_only(mut self) -> Self {
self.mutability = Mutability::ReadOnly;
self
}
pub fn write_only(mut self) -> Self {
self.mutability = Mutability::WriteOnly;
self
}
pub fn always_returned(mut self) -> Self {
self.returned = Returned::Always;
self
}
pub fn never_returned(mut self) -> Self {
self.returned = Returned::Never;
self
}
pub fn returned_on_request(mut self) -> Self {
self.returned = Returned::Request;
self
}
pub fn unique(mut self) -> Self {
self.uniqueness = Uniqueness::Server;
self
}
pub fn globally_unique(mut self) -> Self {
self.uniqueness = Uniqueness::Global;
self
}
pub fn reference_types(mut self, reference_types: Vec<String>) -> Self {
self.reference_types = Some(reference_types);
self
}
}
#[allow(unused)]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub enum Mutability {
ReadOnly,
ReadWrite,
Immutable,
WriteOnly,
}
impl Default for Mutability {
fn default() -> Self {
Self::ReadWrite
}
}
#[allow(unused)]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub enum Returned {
Always,
Never,
Default,
Request,
}
impl Default for Returned {
fn default() -> Self {
Self::Default
}
}
#[allow(unused)]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub enum Uniqueness {
None,
Server,
Global,
}
impl Default for Uniqueness {
fn default() -> Self {
Self::None
}
}
#[allow(unused)]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub enum Type {
String,
Boolean,
Decimal,
Integer,
DateTime,
Binary,
Reference,
Complex,
}
impl Default for Type {
fn default() -> Self {
Self::String
}
}