/* * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ // This file is auto-generated. Do not edit directly. use crate::schema::prelude::*; impl ObjectImpl for Account { const FLAGS: u64 = OBJ_FILTER_TENANT | OBJ_SEQ_ID; const VERSION: u8 = 1; const OBJECT: ObjectType = ObjectType::Account; fn validate(&self, errors: &mut Vec) -> bool { match self { Account::User(inner) => inner.validate(errors), Account::Group(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { Account::User(object) => { i.typ(0); object.index(i); } Account::Group(object) => { i.typ(1); object.index(i); } } } } impl Default for Account { fn default() -> Self { Account::User(Default::default()) } } impl Pickle for Account { fn pickle(&self, out: &mut Vec) { match self { Account::User(inner) => { 0u16.pickle(out); inner.pickle(out); } Account::Group(inner) => { 1u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(Account::User), 1 => Pickle::unpickle(stream).map(Account::Group), _ => None, } } } impl IntoValue for Account { fn into_value(self) -> JmapValue<'static> { match self { Account::User(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("User".into())); obj } Account::Group(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Group".into())); obj } } } } impl RegistryJsonPatch for Account { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { AccountType::User => *self = Account::User(Default::default()), AccountType::Group => *self = Account::Group(Default::default()), } } match self { Account::User(inner) => inner.patch(pointer, value), Account::Group(inner) => inner.patch(pointer, value), } } } impl Account { pub fn object_type(&self) -> AccountType { match self { Account::User(_) => AccountType::User, Account::Group(_) => AccountType::Group, } } } impl ObjectImpl for AccountPassword { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::AccountPassword; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.secret { if value.is_empty() { errors.push(ValidationError::required(Property::Secret)); } } if let Some(value) = &self.current_secret { if value.is_empty() { errors.push(ValidationError::required(Property::CurrentSecret)); } } let value = &self.otp_auth; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for AccountPassword { fn pickle(&self, out: &mut Vec) { self.secret.pickle(out); self.current_secret.pickle(out); self.otp_auth.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.secret = Pickle::unpickle(stream)?; this.current_secret = Pickle::unpickle(stream)?; this.otp_auth = Pickle::unpickle(stream)?; Some(this) } } impl Default for AccountPassword { fn default() -> Self { Self { secret: Default::default(), current_secret: Default::default(), otp_auth: Default::default(), } } } impl IntoValue for AccountPassword { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); if self.secret.is_some() { map.insert_unchecked(Property::Secret, JmapValue::Str(MASKED_PASSWORD.into())); } if self.current_secret.is_some() { map.insert_unchecked( Property::CurrentSecret, JmapValue::Str(MASKED_PASSWORD.into()), ); } map.insert_unchecked(Property::OtpAuth, self.otp_auth.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for AccountPassword { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Secret) => self.secret.patch(pointer, value), Some(Property::CurrentSecret) => self.current_secret.patch(pointer, value), Some(Property::OtpAuth) => self.otp_auth.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for AccountSettings { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::AccountSettings; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.encryption_at_rest; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { if let Some(value) = &self.description { i.text(Property::Text, value); } self.encryption_at_rest.index(i); } } impl Pickle for AccountSettings { fn pickle(&self, out: &mut Vec) { self.description.pickle(out); self.locale.pickle(out); self.time_zone.pickle(out); self.encryption_at_rest.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.description = Pickle::unpickle(stream)?; this.locale = Pickle::unpickle(stream)?; this.time_zone = Pickle::unpickle(stream)?; this.encryption_at_rest = Pickle::unpickle(stream)?; Some(this) } } impl Default for AccountSettings { fn default() -> Self { Self { description: Default::default(), locale: Locale::EnUS, time_zone: Default::default(), encryption_at_rest: Default::default(), } } } impl IntoValue for AccountSettings { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Locale, self.locale.into_value()); map.insert_unchecked(Property::TimeZone, self.time_zone.into_value()); map.insert_unchecked( Property::EncryptionAtRest, self.encryption_at_rest.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for AccountSettings { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Locale) => self.locale.patch(pointer, value), Some(Property::TimeZone) => self.time_zone.patch(pointer, value), Some(Property::EncryptionAtRest) => self.encryption_at_rest.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for AcmeProvider { const FLAGS: u64 = OBJ_FILTER_TENANT; const VERSION: u8 = 2; const OBJECT: ObjectType = ObjectType::AcmeProvider; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.contact; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::Contact)); } } if value.len() < 1 { errors.push(ValidationError::min_items(Property::Contact, 1)); } let value = &self.directory; if value.is_empty() { errors.push(ValidationError::required(Property::Directory)); } let value = &self.account_key; if value.is_empty() { errors.push(ValidationError::required(Property::AccountKey)); } let value = &self.account_uri; if value.is_empty() { errors.push(ValidationError::required(Property::AccountUri)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } if let Some(value) = &self.preferred_chain { if value.is_empty() { errors.push(ValidationError::required(Property::PreferredChain)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { for value in self.contact.iter() { i.text(Property::Text, value); } i.text(Property::Text, &self.directory); i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for AcmeProvider { fn pickle(&self, out: &mut Vec) { self.challenge_type.pickle(out); self.contact.pickle(out); self.directory.pickle(out); self.account_key.pickle(out); self.account_uri.pickle(out); self.renew_before.pickle(out); self.max_retries.pickle(out); self.member_tenant_id.pickle(out); self.preferred_chain.pickle(out); self.reuse_key.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.challenge_type = Pickle::unpickle(stream)?; this.contact = Pickle::unpickle(stream)?; this.directory = Pickle::unpickle(stream)?; this.account_key = Pickle::unpickle(stream)?; this.account_uri = Pickle::unpickle(stream)?; this.renew_before = Pickle::unpickle(stream)?; this.max_retries = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; if stream.version() >= 1 { this.preferred_chain = Pickle::unpickle(stream)?; } if stream.version() >= 2 { this.reuse_key = Pickle::unpickle(stream)?; } Some(this) } } impl Default for AcmeProvider { fn default() -> Self { Self { challenge_type: AcmeChallengeType::TlsAlpn01, contact: Default::default(), directory: "https://acme-v02.api.letsencrypt.org/directory".to_string(), account_key: Default::default(), account_uri: Default::default(), renew_before: AcmeRenewBefore::R23, max_retries: 10i64, member_tenant_id: Default::default(), preferred_chain: Default::default(), reuse_key: false, } } } impl IntoValue for AcmeProvider { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(12); map.insert_unchecked(Property::ChallengeType, self.challenge_type.into_value()); map.insert_unchecked(Property::Contact, self.contact.into_value()); map.insert_unchecked(Property::Directory, self.directory.into_value()); map.insert_unchecked(Property::AccountKey, JmapValue::Str(MASKED_PASSWORD.into())); map.insert_unchecked(Property::AccountUri, self.account_uri.into_value()); map.insert_unchecked(Property::RenewBefore, self.renew_before.into_value()); map.insert_unchecked(Property::MaxRetries, self.max_retries.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::PreferredChain, self.preferred_chain.into_value()); map.insert_unchecked(Property::ReuseKey, self.reuse_key.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for AcmeProvider { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ChallengeType) => self.challenge_type.patch(pointer, value), Some(Property::Contact) => self .contact .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::Directory) => self.directory.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::Trim]), value, ), Some(property @ Property::EabHmacKey) => { Ok(MaybeUnpatched::Unpatched { property, value }) } Some(property @ Property::EabKeyId) => { Ok(MaybeUnpatched::Unpatched { property, value }) } Some(Property::AccountKey) => pointer.assert_server_set(), Some(Property::AccountUri) => pointer.assert_server_set(), Some(Property::RenewBefore) => self.renew_before.patch(pointer, value), Some(Property::MaxRetries) => self.max_retries.patch(pointer, value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::PreferredChain) => self .preferred_chain .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ReuseKey) => self.reuse_key.patch(pointer, value), Some(Property::Description) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Action { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Action; fn validate(&self, errors: &mut Vec) -> bool { match self { Action::ReloadSettings => true, Action::ReloadTlsCertificates => true, Action::ReloadLookupStores => true, Action::ReloadBlockedIps => true, Action::UpdateApps => true, Action::TroubleshootDmarc(inner) => inner.validate(errors), Action::ClassifySpam(inner) => inner.validate(errors), Action::InvalidateCaches => true, Action::InvalidateNegativeCaches => true, Action::PauseMtaQueue => true, Action::ResumeMtaQueue => true, } } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Default for Action { fn default() -> Self { Action::ReloadSettings } } impl Pickle for Action { fn pickle(&self, out: &mut Vec) { match self { Action::ReloadSettings => { 0u16.pickle(out); } Action::ReloadTlsCertificates => { 1u16.pickle(out); } Action::ReloadLookupStores => { 2u16.pickle(out); } Action::ReloadBlockedIps => { 3u16.pickle(out); } Action::UpdateApps => { 4u16.pickle(out); } Action::TroubleshootDmarc(inner) => { 5u16.pickle(out); inner.pickle(out); } Action::ClassifySpam(inner) => { 6u16.pickle(out); inner.pickle(out); } Action::InvalidateCaches => { 7u16.pickle(out); } Action::InvalidateNegativeCaches => { 8u16.pickle(out); } Action::PauseMtaQueue => { 9u16.pickle(out); } Action::ResumeMtaQueue => { 10u16.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(Action::ReloadSettings), 1 => Some(Action::ReloadTlsCertificates), 2 => Some(Action::ReloadLookupStores), 3 => Some(Action::ReloadBlockedIps), 4 => Some(Action::UpdateApps), 5 => Pickle::unpickle(stream).map(Action::TroubleshootDmarc), 6 => Pickle::unpickle(stream).map(Action::ClassifySpam), 7 => Some(Action::InvalidateCaches), 8 => Some(Action::InvalidateNegativeCaches), 9 => Some(Action::PauseMtaQueue), 10 => Some(Action::ResumeMtaQueue), _ => None, } } } impl IntoValue for Action { fn into_value(self) -> JmapValue<'static> { match self { Action::ReloadSettings => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("ReloadSettings".into())); JmapValue::Object(obj) } Action::ReloadTlsCertificates => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked( Property::Type, JmapValue::Str("ReloadTlsCertificates".into()), ); JmapValue::Object(obj) } Action::ReloadLookupStores => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("ReloadLookupStores".into())); JmapValue::Object(obj) } Action::ReloadBlockedIps => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("ReloadBlockedIps".into())); JmapValue::Object(obj) } Action::UpdateApps => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("UpdateApps".into())); JmapValue::Object(obj) } Action::TroubleshootDmarc(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("TroubleshootDmarc".into())); obj } Action::ClassifySpam(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("ClassifySpam".into())); obj } Action::InvalidateCaches => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("InvalidateCaches".into())); JmapValue::Object(obj) } Action::InvalidateNegativeCaches => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked( Property::Type, JmapValue::Str("InvalidateNegativeCaches".into()), ); JmapValue::Object(obj) } Action::PauseMtaQueue => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("PauseMtaQueue".into())); JmapValue::Object(obj) } Action::ResumeMtaQueue => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("ResumeMtaQueue".into())); JmapValue::Object(obj) } } } } impl RegistryJsonPatch for Action { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { ActionType::ReloadSettings => *self = Action::ReloadSettings, ActionType::ReloadTlsCertificates => *self = Action::ReloadTlsCertificates, ActionType::ReloadLookupStores => *self = Action::ReloadLookupStores, ActionType::ReloadBlockedIps => *self = Action::ReloadBlockedIps, ActionType::UpdateApps => *self = Action::UpdateApps, ActionType::TroubleshootDmarc => { *self = Action::TroubleshootDmarc(Default::default()) } ActionType::ClassifySpam => *self = Action::ClassifySpam(Default::default()), ActionType::InvalidateCaches => *self = Action::InvalidateCaches, ActionType::InvalidateNegativeCaches => *self = Action::InvalidateNegativeCaches, ActionType::PauseMtaQueue => *self = Action::PauseMtaQueue, ActionType::ResumeMtaQueue => *self = Action::ResumeMtaQueue, } } match self { Action::ReloadSettings => pointer.assert_eof(), Action::ReloadTlsCertificates => pointer.assert_eof(), Action::ReloadLookupStores => pointer.assert_eof(), Action::ReloadBlockedIps => pointer.assert_eof(), Action::UpdateApps => pointer.assert_eof(), Action::TroubleshootDmarc(inner) => inner.patch(pointer, value), Action::ClassifySpam(inner) => inner.patch(pointer, value), Action::InvalidateCaches => pointer.assert_eof(), Action::InvalidateNegativeCaches => pointer.assert_eof(), Action::PauseMtaQueue => pointer.assert_eof(), Action::ResumeMtaQueue => pointer.assert_eof(), } } } impl Action { pub fn object_type(&self) -> ActionType { match self { Action::ReloadSettings => ActionType::ReloadSettings, Action::ReloadTlsCertificates => ActionType::ReloadTlsCertificates, Action::ReloadLookupStores => ActionType::ReloadLookupStores, Action::ReloadBlockedIps => ActionType::ReloadBlockedIps, Action::UpdateApps => ActionType::UpdateApps, Action::TroubleshootDmarc(_) => ActionType::TroubleshootDmarc, Action::ClassifySpam(_) => ActionType::ClassifySpam, Action::InvalidateCaches => ActionType::InvalidateCaches, Action::InvalidateNegativeCaches => ActionType::InvalidateNegativeCaches, Action::PauseMtaQueue => ActionType::PauseMtaQueue, Action::ResumeMtaQueue => ActionType::ResumeMtaQueue, } } } impl ObjectImpl for AddressBook { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 1; const OBJECT: ObjectType = ObjectType::AddressBook; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.default_display_name { if value.is_empty() { errors.push(ValidationError::required(Property::DefaultDisplayName)); } } if let Some(value) = &self.default_href_name { if value.is_empty() { errors.push(ValidationError::required(Property::DefaultHrefName)); } } if let Some(value) = &self.max_address_books { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxAddressBooks, 1)); } } if let Some(value) = &self.max_contacts { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxContacts, 1)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for AddressBook { fn pickle(&self, out: &mut Vec) { self.default_display_name.pickle(out); self.default_href_name.pickle(out); self.max_v_card_size.pickle(out); self.max_address_books.pickle(out); self.max_contacts.pickle(out); self.v_card_version.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.default_display_name = Pickle::unpickle(stream)?; this.default_href_name = Pickle::unpickle(stream)?; this.max_v_card_size = Pickle::unpickle(stream)?; this.max_address_books = Pickle::unpickle(stream)?; this.max_contacts = Pickle::unpickle(stream)?; if stream.version() >= 1 { this.v_card_version = Pickle::unpickle(stream)?; } Some(this) } } impl Default for AddressBook { fn default() -> Self { Self { default_display_name: Some("INBUXA Address Book".to_string()), default_href_name: Some("default".to_string()), max_v_card_size: 524288u64, max_address_books: Some(250u64), max_contacts: Default::default(), v_card_version: VCardVersion::V4, } } } impl IntoValue for AddressBook { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked( Property::DefaultDisplayName, self.default_display_name.into_value(), ); map.insert_unchecked( Property::DefaultHrefName, self.default_href_name.into_value(), ); map.insert_unchecked(Property::MaxVCardSize, self.max_v_card_size.into_value()); map.insert_unchecked( Property::MaxAddressBooks, self.max_address_books.into_value(), ); map.insert_unchecked(Property::MaxContacts, self.max_contacts.into_value()); map.insert_unchecked(Property::VCardVersion, self.v_card_version.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for AddressBook { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::DefaultDisplayName) => self .default_display_name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::DefaultHrefName) => self .default_href_name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MaxVCardSize) => self.max_v_card_size.patch(pointer, value), Some(Property::MaxAddressBooks) => self.max_address_books.patch(pointer, value), Some(Property::MaxContacts) => self.max_contacts.patch(pointer, value), Some(Property::VCardVersion) => self.v_card_version.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for AiModel { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::AiModel; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } let value = &self.temperature; if *value > Float::new(1.0) { errors.push(ValidationError::max_value(Property::Temperature, 1)); } if *value < Float::new(0.0) { errors.push(ValidationError::min_value(Property::Temperature, 0)); } let value = &self.model; if value.is_empty() { errors.push(ValidationError::required(Property::Model)); } let value = &self.url; if value.is_empty() { errors.push(ValidationError::required(Property::Url)); } let value = &self.http_auth; value.validate(errors); let value = &self.http_headers; for value in value.values() { if value.is_empty() { errors.push(ValidationError::required(Property::HttpHeaders)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for AiModel { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.allow_invalid_certs.pickle(out); self.temperature.pickle(out); self.model.pickle(out); self.timeout.pickle(out); self.model_type.pickle(out); self.url.pickle(out); self.http_auth.pickle(out); self.http_headers.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.allow_invalid_certs = Pickle::unpickle(stream)?; this.temperature = Pickle::unpickle(stream)?; this.model = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.model_type = Pickle::unpickle(stream)?; this.url = Pickle::unpickle(stream)?; this.http_auth = Pickle::unpickle(stream)?; this.http_headers = Pickle::unpickle(stream)?; Some(this) } } impl Default for AiModel { fn default() -> Self { Self { name: Default::default(), allow_invalid_certs: false, temperature: Float::new(0.7f64), model: Default::default(), timeout: Duration::from_millis(120000), model_type: AiModelType::Chat, url: Default::default(), http_auth: Default::default(), http_headers: Default::default(), } } } impl IntoValue for AiModel { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked( Property::AllowInvalidCerts, self.allow_invalid_certs.into_value(), ); map.insert_unchecked(Property::Temperature, self.temperature.into_value()); map.insert_unchecked(Property::Model, self.model.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::ModelType, self.model_type.into_value()); map.insert_unchecked(Property::Url, self.url.into_value()); map.insert_unchecked(Property::HttpAuth, self.http_auth.into_value()); map.insert_unchecked(Property::HttpHeaders, self.http_headers.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for AiModel { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self .name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AllowInvalidCerts) => self.allow_invalid_certs.patch(pointer, value), Some(Property::Temperature) => self.temperature.patch(pointer, value), Some(Property::Model) => self .model .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::ModelType) => self.model_type.patch(pointer, value), Some(Property::Url) => self .url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::HttpAuth) => self.http_auth.patch(pointer, value), Some(Property::HttpHeaders) => self .http_headers .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Alert { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Alert; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.condition; value.validate(errors); let value = &self.email_alert; value.validate(errors); let value = &self.event_alert; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Alert { pub fn ctx_condition(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.condition, default: None, property: Property::Condition, allowed_variables: &[], allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_condition()] } } impl Pickle for Alert { fn pickle(&self, out: &mut Vec) { self.condition.pickle(out); self.email_alert.pickle(out); self.event_alert.pickle(out); self.enable.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.condition = Pickle::unpickle(stream)?; this.email_alert = Pickle::unpickle(stream)?; this.event_alert = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; Some(this) } } impl Default for Alert { fn default() -> Self { Self { condition: Default::default(), email_alert: Default::default(), event_alert: Default::default(), enable: true, } } } impl IntoValue for Alert { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Condition, self.condition.into_value()); map.insert_unchecked(Property::EmailAlert, self.email_alert.into_value()); map.insert_unchecked(Property::EventAlert, self.event_alert.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Alert { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Condition) => self.condition.patch(pointer, value), Some(Property::EmailAlert) => self.email_alert.patch(pointer, value), Some(Property::EventAlert) => self.event_alert.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl AlertEmail { fn validate(&self, errors: &mut Vec) -> bool { match self { AlertEmail::Disabled => true, AlertEmail::Enabled(inner) => inner.validate(errors), } } } impl Default for AlertEmail { fn default() -> Self { AlertEmail::Disabled } } impl Pickle for AlertEmail { fn pickle(&self, out: &mut Vec) { match self { AlertEmail::Disabled => { 0u16.pickle(out); } AlertEmail::Enabled(inner) => { 1u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(AlertEmail::Disabled), 1 => Pickle::unpickle(stream).map(AlertEmail::Enabled), _ => None, } } } impl IntoValue for AlertEmail { fn into_value(self) -> JmapValue<'static> { match self { AlertEmail::Disabled => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Disabled".into())); JmapValue::Object(obj) } AlertEmail::Enabled(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Enabled".into())); obj } } } } impl RegistryJsonPatch for AlertEmail { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { AlertEmailType::Disabled => *self = AlertEmail::Disabled, AlertEmailType::Enabled => *self = AlertEmail::Enabled(Default::default()), } } match self { AlertEmail::Disabled => pointer.assert_eof(), AlertEmail::Enabled(inner) => inner.patch(pointer, value), } } } impl AlertEmail { pub fn object_type(&self) -> AlertEmailType { match self { AlertEmail::Disabled => AlertEmailType::Disabled, AlertEmail::Enabled(_) => AlertEmailType::Enabled, } } } impl AlertEmailProperties { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.body; if value.is_empty() { errors.push(ValidationError::required(Property::Body)); } let value = &self.from_address; if value.is_empty() { errors.push(ValidationError::required(Property::FromAddress)); } if let Some(value) = &self.from_name { if value.is_empty() { errors.push(ValidationError::required(Property::FromName)); } } let value = &self.subject; if value.is_empty() { errors.push(ValidationError::required(Property::Subject)); } let value = &self.to; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::To)); } } if value.len() < 1 { errors.push(ValidationError::min_items(Property::To, 1)); } errors.len() == neb } } impl Pickle for AlertEmailProperties { fn pickle(&self, out: &mut Vec) { self.body.pickle(out); self.from_address.pickle(out); self.from_name.pickle(out); self.subject.pickle(out); self.to.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.body = Pickle::unpickle(stream)?; this.from_address = Pickle::unpickle(stream)?; this.from_name = Pickle::unpickle(stream)?; this.subject = Pickle::unpickle(stream)?; this.to = Pickle::unpickle(stream)?; Some(this) } } impl Default for AlertEmailProperties { fn default() -> Self { Self { body: Default::default(), from_address: Default::default(), from_name: Default::default(), subject: Default::default(), to: Default::default(), } } } impl IntoValue for AlertEmailProperties { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Body, self.body.into_value()); map.insert_unchecked(Property::FromAddress, self.from_address.into_value()); map.insert_unchecked(Property::FromName, self.from_name.into_value()); map.insert_unchecked(Property::Subject, self.subject.into_value()); map.insert_unchecked(Property::To, self.to.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for AlertEmailProperties { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Body) => self.body.patch(pointer, value), Some(Property::FromAddress) => self .from_address .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::FromName) => self.from_name.patch(pointer, value), Some(Property::Subject) => self.subject.patch(pointer, value), Some(Property::To) => self .to .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl AlertEvent { fn validate(&self, errors: &mut Vec) -> bool { match self { AlertEvent::Disabled => true, AlertEvent::Enabled(inner) => inner.validate(errors), } } } impl Default for AlertEvent { fn default() -> Self { AlertEvent::Disabled } } impl Pickle for AlertEvent { fn pickle(&self, out: &mut Vec) { match self { AlertEvent::Disabled => { 0u16.pickle(out); } AlertEvent::Enabled(inner) => { 1u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(AlertEvent::Disabled), 1 => Pickle::unpickle(stream).map(AlertEvent::Enabled), _ => None, } } } impl IntoValue for AlertEvent { fn into_value(self) -> JmapValue<'static> { match self { AlertEvent::Disabled => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Disabled".into())); JmapValue::Object(obj) } AlertEvent::Enabled(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Enabled".into())); obj } } } } impl RegistryJsonPatch for AlertEvent { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { AlertEventType::Disabled => *self = AlertEvent::Disabled, AlertEventType::Enabled => *self = AlertEvent::Enabled(Default::default()), } } match self { AlertEvent::Disabled => pointer.assert_eof(), AlertEvent::Enabled(inner) => inner.patch(pointer, value), } } } impl AlertEvent { pub fn object_type(&self) -> AlertEventType { match self { AlertEvent::Disabled => AlertEventType::Disabled, AlertEvent::Enabled(_) => AlertEventType::Enabled, } } } impl AlertEventProperties { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.event_message { if value.is_empty() { errors.push(ValidationError::required(Property::EventMessage)); } } errors.len() == neb } } impl Pickle for AlertEventProperties { fn pickle(&self, out: &mut Vec) { self.event_message.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.event_message = Pickle::unpickle(stream)?; Some(this) } } impl Default for AlertEventProperties { fn default() -> Self { Self { event_message: Default::default(), } } } impl IntoValue for AlertEventProperties { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::EventMessage, self.event_message.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for AlertEventProperties { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::EventMessage) => self.event_message.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for AllowedIp { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::AllowedIp; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.address; if !value.is_valid() { errors.push(ValidationError::invalid(Property::Address, value)); } if let Some(value) = &self.reason { if value.is_empty() { errors.push(ValidationError::required(Property::Reason)); } } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } if let Some(value) = &self.expires_at { if !value.is_valid() { errors.push(ValidationError::invalid(Property::ExpiresAt, value)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Address, &self.address); } } impl Pickle for AllowedIp { fn pickle(&self, out: &mut Vec) { self.address.pickle(out); self.reason.pickle(out); self.created_at.pickle(out); self.expires_at.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.address = Pickle::unpickle(stream)?; this.reason = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.expires_at = Pickle::unpickle(stream)?; Some(this) } } impl Default for AllowedIp { fn default() -> Self { Self { address: Default::default(), reason: Default::default(), created_at: Default::default(), expires_at: Default::default(), } } } impl IntoValue for AllowedIp { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Address, self.address.into_value()); map.insert_unchecked(Property::Reason, self.reason.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::ExpiresAt, self.expires_at.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for AllowedIp { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Address) => self.address.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::Trim]), value, ), Some(Property::Reason) => self .reason .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::CreatedAt) => self.created_at.patch(pointer.assert_read_only()?, value), Some(Property::ExpiresAt) => self.expires_at.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for ApiKey { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::ApiKey; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } let value = &self.secret; if value.is_empty() { errors.push(ValidationError::required(Property::Secret)); } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } if let Some(value) = &self.expires_at { if !value.is_valid() { errors.push(ValidationError::invalid(Property::ExpiresAt, value)); } } let value = &self.permissions; value.validate(errors); let value = &self.allowed_ips; for value in value.iter() { if !value.is_valid() { errors.push(ValidationError::invalid(Property::AllowedIps, value)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for ApiKey { fn pickle(&self, out: &mut Vec) { self.description.pickle(out); self.secret.pickle(out); self.created_at.pickle(out); self.expires_at.pickle(out); self.permissions.pickle(out); self.allowed_ips.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.description = Pickle::unpickle(stream)?; this.secret = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.expires_at = Pickle::unpickle(stream)?; this.permissions = Pickle::unpickle(stream)?; this.allowed_ips = Pickle::unpickle(stream)?; Some(this) } } impl Default for ApiKey { fn default() -> Self { Self { description: Default::default(), secret: Default::default(), created_at: Default::default(), expires_at: Default::default(), permissions: Default::default(), allowed_ips: Default::default(), } } } impl IntoValue for ApiKey { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Secret, JmapValue::Str(MASKED_PASSWORD.into())); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::ExpiresAt, self.expires_at.into_value()); map.insert_unchecked(Property::Permissions, self.permissions.into_value()); map.insert_unchecked(Property::AllowedIps, self.allowed_ips.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ApiKey { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Secret) => pointer.assert_server_set(), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::ExpiresAt) => self.expires_at.patch(pointer, value), Some(Property::Permissions) => self.permissions.patch(pointer, value), Some(Property::AllowedIps) => self.allowed_ips.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for AppPassword { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::AppPassword; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } let value = &self.secret; if value.is_empty() { errors.push(ValidationError::required(Property::Secret)); } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } if let Some(value) = &self.expires_at { if !value.is_valid() { errors.push(ValidationError::invalid(Property::ExpiresAt, value)); } } let value = &self.permissions; value.validate(errors); let value = &self.allowed_ips; for value in value.iter() { if !value.is_valid() { errors.push(ValidationError::invalid(Property::AllowedIps, value)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for AppPassword { fn pickle(&self, out: &mut Vec) { self.description.pickle(out); self.secret.pickle(out); self.created_at.pickle(out); self.expires_at.pickle(out); self.permissions.pickle(out); self.allowed_ips.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.description = Pickle::unpickle(stream)?; this.secret = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.expires_at = Pickle::unpickle(stream)?; this.permissions = Pickle::unpickle(stream)?; this.allowed_ips = Pickle::unpickle(stream)?; Some(this) } } impl Default for AppPassword { fn default() -> Self { Self { description: Default::default(), secret: Default::default(), created_at: Default::default(), expires_at: Default::default(), permissions: Default::default(), allowed_ips: Default::default(), } } } impl IntoValue for AppPassword { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Secret, JmapValue::Str(MASKED_PASSWORD.into())); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::ExpiresAt, self.expires_at.into_value()); map.insert_unchecked(Property::Permissions, self.permissions.into_value()); map.insert_unchecked(Property::AllowedIps, self.allowed_ips.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for AppPassword { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Secret) => pointer.assert_server_set(), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::ExpiresAt) => self.expires_at.patch(pointer, value), Some(Property::Permissions) => self.permissions.patch(pointer, value), Some(Property::AllowedIps) => self.allowed_ips.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Application { const FLAGS: u64 = 0; const VERSION: u8 = 1; const OBJECT: ObjectType = ObjectType::Application; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } let value = &self.resource_url; if value.is_empty() { errors.push(ValidationError::required(Property::ResourceUrl)); } let value = &self.url_prefix; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::UrlPrefix)); } } if value.len() < 1 { errors.push(ValidationError::min_items(Property::UrlPrefix, 1)); } if let Some(value) = &self.unpack_directory { if value.is_empty() { errors.push(ValidationError::required(Property::UnpackDirectory)); } } if let Some(value) = &self.oauth_client_id { if value.is_empty() { errors.push(ValidationError::required(Property::OauthClientId)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for Application { fn pickle(&self, out: &mut Vec) { self.enabled.pickle(out); self.description.pickle(out); self.resource_url.pickle(out); self.url_prefix.pickle(out); self.auto_update_frequency.pickle(out); self.unpack_directory.pickle(out); self.oauth_client_id.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.enabled = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.resource_url = Pickle::unpickle(stream)?; this.url_prefix = Pickle::unpickle(stream)?; this.auto_update_frequency = Pickle::unpickle(stream)?; this.unpack_directory = Pickle::unpickle(stream)?; if stream.version() >= 1 { this.oauth_client_id = Pickle::unpickle(stream)?; } Some(this) } } impl Default for Application { fn default() -> Self { Self { enabled: true, description: Default::default(), resource_url: Default::default(), url_prefix: Default::default(), auto_update_frequency: Duration::from_millis(7776000000), unpack_directory: Default::default(), oauth_client_id: Default::default(), } } } impl IntoValue for Application { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked(Property::Enabled, self.enabled.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::ResourceUrl, self.resource_url.into_value()); map.insert_unchecked(Property::UrlPrefix, self.url_prefix.into_value()); map.insert_unchecked( Property::AutoUpdateFrequency, self.auto_update_frequency.into_value(), ); map.insert_unchecked( Property::UnpackDirectory, self.unpack_directory.into_value(), ); map.insert_unchecked(Property::OauthClientId, self.oauth_client_id.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Application { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Enabled) => self.enabled.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ResourceUrl) => self .resource_url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::UrlPrefix) => self .url_prefix .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AutoUpdateFrequency) => self.auto_update_frequency.patch(pointer, value), Some(Property::UnpackDirectory) => self .unpack_directory .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::OauthClientId) => self .oauth_client_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ArchivedCalendarEvent { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.title; if value.is_empty() { errors.push(ValidationError::required(Property::Title)); } if let Some(value) = &self.start_time { if !value.is_valid() { errors.push(ValidationError::invalid(Property::StartTime, value)); } } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } let value = &self.account_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } let value = &self.archived_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ArchivedAt, value)); } let value = &self.archived_until; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ArchivedUntil, value)); } let value = &self.blob_id; if value.is_empty() { errors.push(ValidationError::required(Property::BlobId)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id.into(), None); i.search(Property::AccountId, &self.account_id); } } impl Pickle for ArchivedCalendarEvent { fn pickle(&self, out: &mut Vec) { self.title.pickle(out); self.start_time.pickle(out); self.created_at.pickle(out); self.account_id.pickle(out); self.archived_at.pickle(out); self.archived_until.pickle(out); self.blob_id.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.title = Pickle::unpickle(stream)?; this.start_time = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.account_id = Pickle::unpickle(stream)?; this.archived_at = Pickle::unpickle(stream)?; this.archived_until = Pickle::unpickle(stream)?; this.blob_id = Pickle::unpickle(stream)?; Some(this) } } impl Default for ArchivedCalendarEvent { fn default() -> Self { Self { title: Default::default(), start_time: Default::default(), created_at: Default::default(), account_id: Default::default(), archived_at: Default::default(), archived_until: Default::default(), blob_id: Default::default(), } } } impl IntoValue for ArchivedCalendarEvent { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked(Property::Title, self.title.into_value()); map.insert_unchecked(Property::StartTime, self.start_time.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked(Property::ArchivedAt, self.archived_at.into_value()); map.insert_unchecked(Property::ArchivedUntil, self.archived_until.into_value()); map.insert_unchecked(Property::BlobId, self.blob_id.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ArchivedCalendarEvent { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Title) => self.title.patch(pointer, value), Some(Property::StartTime) => self.start_time.patch(pointer, value), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::AccountId) => self .account_id .patch(pointer.assert_can_set_account()?, value), Some(Property::ArchivedAt) => self.archived_at.patch(pointer, value), Some(Property::ArchivedUntil) => self.archived_until.patch(pointer, value), Some(Property::BlobId) => self.blob_id.patch(pointer, value), Some(property @ Property::Status) => Ok(MaybeUnpatched::Unpatched { property, value }), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ArchivedContactCard { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.name { if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } let value = &self.account_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } let value = &self.archived_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ArchivedAt, value)); } let value = &self.archived_until; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ArchivedUntil, value)); } let value = &self.blob_id; if value.is_empty() { errors.push(ValidationError::required(Property::BlobId)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id.into(), None); i.search(Property::AccountId, &self.account_id); } } impl Pickle for ArchivedContactCard { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.created_at.pickle(out); self.account_id.pickle(out); self.archived_at.pickle(out); self.archived_until.pickle(out); self.blob_id.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.account_id = Pickle::unpickle(stream)?; this.archived_at = Pickle::unpickle(stream)?; this.archived_until = Pickle::unpickle(stream)?; this.blob_id = Pickle::unpickle(stream)?; Some(this) } } impl Default for ArchivedContactCard { fn default() -> Self { Self { name: Default::default(), created_at: Default::default(), account_id: Default::default(), archived_at: Default::default(), archived_until: Default::default(), blob_id: Default::default(), } } } impl IntoValue for ArchivedContactCard { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked(Property::ArchivedAt, self.archived_at.into_value()); map.insert_unchecked(Property::ArchivedUntil, self.archived_until.into_value()); map.insert_unchecked(Property::BlobId, self.blob_id.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ArchivedContactCard { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self.name.patch(pointer, value), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::AccountId) => self .account_id .patch(pointer.assert_can_set_account()?, value), Some(Property::ArchivedAt) => self.archived_at.patch(pointer, value), Some(Property::ArchivedUntil) => self.archived_until.patch(pointer, value), Some(Property::BlobId) => self.blob_id.patch(pointer, value), Some(property @ Property::Status) => Ok(MaybeUnpatched::Unpatched { property, value }), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ArchivedEmail { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.from; if value.is_empty() { errors.push(ValidationError::required(Property::From)); } let value = &self.subject; if value.is_empty() { errors.push(ValidationError::required(Property::Subject)); } let value = &self.received_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ReceivedAt, value)); } let value = &self.account_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } let value = &self.archived_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ArchivedAt, value)); } let value = &self.archived_until; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ArchivedUntil, value)); } let value = &self.blob_id; if value.is_empty() { errors.push(ValidationError::required(Property::BlobId)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id.into(), None); i.search(Property::AccountId, &self.account_id); } } impl Pickle for ArchivedEmail { fn pickle(&self, out: &mut Vec) { self.from.pickle(out); self.subject.pickle(out); self.received_at.pickle(out); self.size.pickle(out); self.account_id.pickle(out); self.archived_at.pickle(out); self.archived_until.pickle(out); self.blob_id.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.from = Pickle::unpickle(stream)?; this.subject = Pickle::unpickle(stream)?; this.received_at = Pickle::unpickle(stream)?; this.size = Pickle::unpickle(stream)?; this.account_id = Pickle::unpickle(stream)?; this.archived_at = Pickle::unpickle(stream)?; this.archived_until = Pickle::unpickle(stream)?; this.blob_id = Pickle::unpickle(stream)?; Some(this) } } impl Default for ArchivedEmail { fn default() -> Self { Self { from: Default::default(), subject: Default::default(), received_at: Default::default(), size: 0u64, account_id: Default::default(), archived_at: Default::default(), archived_until: Default::default(), blob_id: Default::default(), } } } impl IntoValue for ArchivedEmail { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(10); map.insert_unchecked(Property::From, self.from.into_value()); map.insert_unchecked(Property::Subject, self.subject.into_value()); map.insert_unchecked(Property::ReceivedAt, self.received_at.into_value()); map.insert_unchecked(Property::Size, self.size.into_value()); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked(Property::ArchivedAt, self.archived_at.into_value()); map.insert_unchecked(Property::ArchivedUntil, self.archived_until.into_value()); map.insert_unchecked(Property::BlobId, self.blob_id.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ArchivedEmail { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::From) => self.from.patch(pointer, value), Some(Property::Subject) => self.subject.patch(pointer, value), Some(Property::ReceivedAt) => self.received_at.patch(pointer, value), Some(Property::Size) => self.size.patch(pointer.assert_read_only()?, value), Some(Property::AccountId) => self .account_id .patch(pointer.assert_can_set_account()?, value), Some(Property::ArchivedAt) => self.archived_at.patch(pointer, value), Some(Property::ArchivedUntil) => self.archived_until.patch(pointer, value), Some(Property::BlobId) => self.blob_id.patch(pointer, value), Some(property @ Property::Status) => Ok(MaybeUnpatched::Unpatched { property, value }), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ArchivedFileNode { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } let value = &self.account_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } let value = &self.archived_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ArchivedAt, value)); } let value = &self.archived_until; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ArchivedUntil, value)); } let value = &self.blob_id; if value.is_empty() { errors.push(ValidationError::required(Property::BlobId)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id.into(), None); i.search(Property::AccountId, &self.account_id); } } impl Pickle for ArchivedFileNode { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.created_at.pickle(out); self.account_id.pickle(out); self.archived_at.pickle(out); self.archived_until.pickle(out); self.blob_id.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.account_id = Pickle::unpickle(stream)?; this.archived_at = Pickle::unpickle(stream)?; this.archived_until = Pickle::unpickle(stream)?; this.blob_id = Pickle::unpickle(stream)?; Some(this) } } impl Default for ArchivedFileNode { fn default() -> Self { Self { name: Default::default(), created_at: Default::default(), account_id: Default::default(), archived_at: Default::default(), archived_until: Default::default(), blob_id: Default::default(), } } } impl IntoValue for ArchivedFileNode { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked(Property::ArchivedAt, self.archived_at.into_value()); map.insert_unchecked(Property::ArchivedUntil, self.archived_until.into_value()); map.insert_unchecked(Property::BlobId, self.blob_id.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ArchivedFileNode { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self.name.patch(pointer, value), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::AccountId) => self .account_id .patch(pointer.assert_can_set_account()?, value), Some(Property::ArchivedAt) => self.archived_at.patch(pointer, value), Some(Property::ArchivedUntil) => self.archived_until.patch(pointer, value), Some(Property::BlobId) => self.blob_id.patch(pointer, value), Some(property @ Property::Status) => Ok(MaybeUnpatched::Unpatched { property, value }), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for ArchivedItem { const FLAGS: u64 = OBJ_FILTER_ACCOUNT; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::ArchivedItem; fn validate(&self, errors: &mut Vec) -> bool { match self { ArchivedItem::Email(inner) => inner.validate(errors), ArchivedItem::FileNode(inner) => inner.validate(errors), ArchivedItem::CalendarEvent(inner) => inner.validate(errors), ArchivedItem::ContactCard(inner) => inner.validate(errors), ArchivedItem::SieveScript(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { ArchivedItem::Email(object) => { object.index(i); } ArchivedItem::FileNode(object) => { object.index(i); } ArchivedItem::CalendarEvent(object) => { object.index(i); } ArchivedItem::ContactCard(object) => { object.index(i); } ArchivedItem::SieveScript(object) => { object.index(i); } } } } impl Default for ArchivedItem { fn default() -> Self { ArchivedItem::Email(Default::default()) } } impl Pickle for ArchivedItem { fn pickle(&self, out: &mut Vec) { match self { ArchivedItem::Email(inner) => { 0u16.pickle(out); inner.pickle(out); } ArchivedItem::FileNode(inner) => { 1u16.pickle(out); inner.pickle(out); } ArchivedItem::CalendarEvent(inner) => { 2u16.pickle(out); inner.pickle(out); } ArchivedItem::ContactCard(inner) => { 3u16.pickle(out); inner.pickle(out); } ArchivedItem::SieveScript(inner) => { 4u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(ArchivedItem::Email), 1 => Pickle::unpickle(stream).map(ArchivedItem::FileNode), 2 => Pickle::unpickle(stream).map(ArchivedItem::CalendarEvent), 3 => Pickle::unpickle(stream).map(ArchivedItem::ContactCard), 4 => Pickle::unpickle(stream).map(ArchivedItem::SieveScript), _ => None, } } } impl IntoValue for ArchivedItem { fn into_value(self) -> JmapValue<'static> { match self { ArchivedItem::Email(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Email".into())); obj } ArchivedItem::FileNode(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("FileNode".into())); obj } ArchivedItem::CalendarEvent(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("CalendarEvent".into())); obj } ArchivedItem::ContactCard(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("ContactCard".into())); obj } ArchivedItem::SieveScript(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("SieveScript".into())); obj } } } } impl RegistryJsonPatch for ArchivedItem { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { ArchivedItemType::Email => *self = ArchivedItem::Email(Default::default()), ArchivedItemType::FileNode => *self = ArchivedItem::FileNode(Default::default()), ArchivedItemType::CalendarEvent => { *self = ArchivedItem::CalendarEvent(Default::default()) } ArchivedItemType::ContactCard => { *self = ArchivedItem::ContactCard(Default::default()) } ArchivedItemType::SieveScript => { *self = ArchivedItem::SieveScript(Default::default()) } } } match self { ArchivedItem::Email(inner) => inner.patch(pointer, value), ArchivedItem::FileNode(inner) => inner.patch(pointer, value), ArchivedItem::CalendarEvent(inner) => inner.patch(pointer, value), ArchivedItem::ContactCard(inner) => inner.patch(pointer, value), ArchivedItem::SieveScript(inner) => inner.patch(pointer, value), } } } impl ArchivedItem { pub fn object_type(&self) -> ArchivedItemType { match self { ArchivedItem::Email(_) => ArchivedItemType::Email, ArchivedItem::FileNode(_) => ArchivedItemType::FileNode, ArchivedItem::CalendarEvent(_) => ArchivedItemType::CalendarEvent, ArchivedItem::ContactCard(_) => ArchivedItemType::ContactCard, ArchivedItem::SieveScript(_) => ArchivedItemType::SieveScript, } } } impl ArchivedSieveScript { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } let value = &self.content; if value.is_empty() { errors.push(ValidationError::required(Property::Content)); } let value = &self.account_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } let value = &self.archived_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ArchivedAt, value)); } let value = &self.archived_until; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ArchivedUntil, value)); } let value = &self.blob_id; if value.is_empty() { errors.push(ValidationError::required(Property::BlobId)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id.into(), None); i.search(Property::AccountId, &self.account_id); } } impl Pickle for ArchivedSieveScript { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.created_at.pickle(out); self.content.pickle(out); self.account_id.pickle(out); self.archived_at.pickle(out); self.archived_until.pickle(out); self.blob_id.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.content = Pickle::unpickle(stream)?; this.account_id = Pickle::unpickle(stream)?; this.archived_at = Pickle::unpickle(stream)?; this.archived_until = Pickle::unpickle(stream)?; this.blob_id = Pickle::unpickle(stream)?; Some(this) } } impl Default for ArchivedSieveScript { fn default() -> Self { Self { name: Default::default(), created_at: Default::default(), content: Default::default(), account_id: Default::default(), archived_at: Default::default(), archived_until: Default::default(), blob_id: Default::default(), } } } impl IntoValue for ArchivedSieveScript { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::Content, self.content.into_value()); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked(Property::ArchivedAt, self.archived_at.into_value()); map.insert_unchecked(Property::ArchivedUntil, self.archived_until.into_value()); map.insert_unchecked(Property::BlobId, self.blob_id.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ArchivedSieveScript { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self.name.patch(pointer, value), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::Content) => self.content.patch(pointer, value), Some(Property::AccountId) => self .account_id .patch(pointer.assert_can_set_account()?, value), Some(Property::ArchivedAt) => self.archived_at.patch(pointer, value), Some(Property::ArchivedUntil) => self.archived_until.patch(pointer, value), Some(Property::BlobId) => self.blob_id.patch(pointer, value), Some(property @ Property::Status) => Ok(MaybeUnpatched::Unpatched { property, value }), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for ArfExternalReport { const FLAGS: u64 = OBJ_FILTER_TENANT; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::ArfExternalReport; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.report; value.validate(errors); let value = &self.from; if value.is_empty() { errors.push(ValidationError::required(Property::From)); } let value = &self.subject; if value.is_empty() { errors.push(ValidationError::required(Property::Subject)); } let value = &self.to; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::To)); } } let value = &self.received_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ReceivedAt, value)); } let value = &self.expires_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ExpiresAt, value)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); } } impl Pickle for ArfExternalReport { fn pickle(&self, out: &mut Vec) { self.report.pickle(out); self.from.pickle(out); self.subject.pickle(out); self.to.pickle(out); self.received_at.pickle(out); self.expires_at.pickle(out); self.member_tenant_id.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.report = Pickle::unpickle(stream)?; this.from = Pickle::unpickle(stream)?; this.subject = Pickle::unpickle(stream)?; this.to = Pickle::unpickle(stream)?; this.received_at = Pickle::unpickle(stream)?; this.expires_at = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; Some(this) } } impl Default for ArfExternalReport { fn default() -> Self { Self { report: Default::default(), from: Default::default(), subject: Default::default(), to: Default::default(), received_at: Default::default(), expires_at: Default::default(), member_tenant_id: Default::default(), } } } impl IntoValue for ArfExternalReport { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked(Property::Report, self.report.into_value()); map.insert_unchecked(Property::From, self.from.into_value()); map.insert_unchecked(Property::Subject, self.subject.into_value()); map.insert_unchecked(Property::To, self.to.into_value()); map.insert_unchecked(Property::ReceivedAt, self.received_at.into_value()); map.insert_unchecked(Property::ExpiresAt, self.expires_at.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ArfExternalReport { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Report) => self.report.patch(pointer, value), Some(Property::From) => self .from .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::Subject) => self.subject.patch(pointer, value), Some(Property::To) => self .to .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::ReceivedAt) => self.received_at.patch(pointer, value), Some(Property::ExpiresAt) => self.expires_at.patch(pointer, value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ArfFeedbackReport { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.arrival_date { if !value.is_valid() { errors.push(ValidationError::invalid(Property::ArrivalDate, value)); } } let value = &self.authentication_results; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::AuthenticationResults)); } } if let Some(value) = &self.original_envelope_id { if value.is_empty() { errors.push(ValidationError::required(Property::OriginalEnvelopeId)); } } if let Some(value) = &self.original_mail_from { if value.is_empty() { errors.push(ValidationError::required(Property::OriginalMailFrom)); } } if let Some(value) = &self.original_rcpt_to { if value.is_empty() { errors.push(ValidationError::required(Property::OriginalRcptTo)); } } let value = &self.reported_domains; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::ReportedDomains)); } } let value = &self.reported_uris; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::ReportedUris)); } } if let Some(value) = &self.reporting_mta { if value.is_empty() { errors.push(ValidationError::required(Property::ReportingMta)); } } if let Some(value) = &self.source_ip { if !value.is_valid() { errors.push(ValidationError::invalid(Property::SourceIp, value)); } } if let Some(value) = &self.source_port { if *value < 1 { errors.push(ValidationError::min_value(Property::SourcePort, 1)); } if *value > 65535 { errors.push(ValidationError::max_value(Property::SourcePort, 65535)); } } if let Some(value) = &self.user_agent { if value.is_empty() { errors.push(ValidationError::required(Property::UserAgent)); } } if let Some(value) = &self.dkim_adsp_dns { if value.is_empty() { errors.push(ValidationError::required(Property::DkimAdspDns)); } } if let Some(value) = &self.dkim_canonicalized_body { if value.is_empty() { errors.push(ValidationError::required(Property::DkimCanonicalizedBody)); } } if let Some(value) = &self.dkim_canonicalized_header { if value.is_empty() { errors.push(ValidationError::required(Property::DkimCanonicalizedHeader)); } } if let Some(value) = &self.dkim_domain { if value.is_empty() { errors.push(ValidationError::required(Property::DkimDomain)); } } if let Some(value) = &self.dkim_identity { if value.is_empty() { errors.push(ValidationError::required(Property::DkimIdentity)); } } if let Some(value) = &self.dkim_selector { if value.is_empty() { errors.push(ValidationError::required(Property::DkimSelector)); } } if let Some(value) = &self.dkim_selector_dns { if value.is_empty() { errors.push(ValidationError::required(Property::DkimSelectorDns)); } } if let Some(value) = &self.spf_dns { if value.is_empty() { errors.push(ValidationError::required(Property::SpfDns)); } } if let Some(value) = &self.message { if value.is_empty() { errors.push(ValidationError::required(Property::Message)); } } if let Some(value) = &self.headers { if value.is_empty() { errors.push(ValidationError::required(Property::Headers)); } } errors.len() == neb } } impl Pickle for ArfFeedbackReport { fn pickle(&self, out: &mut Vec) { self.feedback_type.pickle(out); self.arrival_date.pickle(out); self.authentication_results.pickle(out); self.incidents.pickle(out); self.original_envelope_id.pickle(out); self.original_mail_from.pickle(out); self.original_rcpt_to.pickle(out); self.reported_domains.pickle(out); self.reported_uris.pickle(out); self.reporting_mta.pickle(out); self.source_ip.pickle(out); self.source_port.pickle(out); self.user_agent.pickle(out); self.version.pickle(out); self.auth_failure.pickle(out); self.delivery_result.pickle(out); self.dkim_adsp_dns.pickle(out); self.dkim_canonicalized_body.pickle(out); self.dkim_canonicalized_header.pickle(out); self.dkim_domain.pickle(out); self.dkim_identity.pickle(out); self.dkim_selector.pickle(out); self.dkim_selector_dns.pickle(out); self.spf_dns.pickle(out); self.identity_alignment.pickle(out); self.message.pickle(out); self.headers.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.feedback_type = Pickle::unpickle(stream)?; this.arrival_date = Pickle::unpickle(stream)?; this.authentication_results = Pickle::unpickle(stream)?; this.incidents = Pickle::unpickle(stream)?; this.original_envelope_id = Pickle::unpickle(stream)?; this.original_mail_from = Pickle::unpickle(stream)?; this.original_rcpt_to = Pickle::unpickle(stream)?; this.reported_domains = Pickle::unpickle(stream)?; this.reported_uris = Pickle::unpickle(stream)?; this.reporting_mta = Pickle::unpickle(stream)?; this.source_ip = Pickle::unpickle(stream)?; this.source_port = Pickle::unpickle(stream)?; this.user_agent = Pickle::unpickle(stream)?; this.version = Pickle::unpickle(stream)?; this.auth_failure = Pickle::unpickle(stream)?; this.delivery_result = Pickle::unpickle(stream)?; this.dkim_adsp_dns = Pickle::unpickle(stream)?; this.dkim_canonicalized_body = Pickle::unpickle(stream)?; this.dkim_canonicalized_header = Pickle::unpickle(stream)?; this.dkim_domain = Pickle::unpickle(stream)?; this.dkim_identity = Pickle::unpickle(stream)?; this.dkim_selector = Pickle::unpickle(stream)?; this.dkim_selector_dns = Pickle::unpickle(stream)?; this.spf_dns = Pickle::unpickle(stream)?; this.identity_alignment = Pickle::unpickle(stream)?; this.message = Pickle::unpickle(stream)?; this.headers = Pickle::unpickle(stream)?; Some(this) } } impl Default for ArfFeedbackReport { fn default() -> Self { Self { feedback_type: Default::default(), arrival_date: Default::default(), authentication_results: Default::default(), incidents: 0u64, original_envelope_id: Default::default(), original_mail_from: Default::default(), original_rcpt_to: Default::default(), reported_domains: Default::default(), reported_uris: Default::default(), reporting_mta: Default::default(), source_ip: Default::default(), source_port: Default::default(), user_agent: Default::default(), version: 1u64, auth_failure: Default::default(), delivery_result: Default::default(), dkim_adsp_dns: Default::default(), dkim_canonicalized_body: Default::default(), dkim_canonicalized_header: Default::default(), dkim_domain: Default::default(), dkim_identity: Default::default(), dkim_selector: Default::default(), dkim_selector_dns: Default::default(), spf_dns: Default::default(), identity_alignment: Default::default(), message: Default::default(), headers: Default::default(), } } } impl IntoValue for ArfFeedbackReport { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(29); map.insert_unchecked(Property::FeedbackType, self.feedback_type.into_value()); map.insert_unchecked(Property::ArrivalDate, self.arrival_date.into_value()); map.insert_unchecked( Property::AuthenticationResults, self.authentication_results.into_value(), ); map.insert_unchecked(Property::Incidents, self.incidents.into_value()); map.insert_unchecked( Property::OriginalEnvelopeId, self.original_envelope_id.into_value(), ); map.insert_unchecked( Property::OriginalMailFrom, self.original_mail_from.into_value(), ); map.insert_unchecked(Property::OriginalRcptTo, self.original_rcpt_to.into_value()); map.insert_unchecked( Property::ReportedDomains, self.reported_domains.into_value(), ); map.insert_unchecked(Property::ReportedUris, self.reported_uris.into_value()); map.insert_unchecked(Property::ReportingMta, self.reporting_mta.into_value()); map.insert_unchecked(Property::SourceIp, self.source_ip.into_value()); map.insert_unchecked(Property::SourcePort, self.source_port.into_value()); map.insert_unchecked(Property::UserAgent, self.user_agent.into_value()); map.insert_unchecked(Property::Version, self.version.into_value()); map.insert_unchecked(Property::AuthFailure, self.auth_failure.into_value()); map.insert_unchecked(Property::DeliveryResult, self.delivery_result.into_value()); map.insert_unchecked(Property::DkimAdspDns, self.dkim_adsp_dns.into_value()); map.insert_unchecked( Property::DkimCanonicalizedBody, self.dkim_canonicalized_body.into_value(), ); map.insert_unchecked( Property::DkimCanonicalizedHeader, self.dkim_canonicalized_header.into_value(), ); map.insert_unchecked(Property::DkimDomain, self.dkim_domain.into_value()); map.insert_unchecked(Property::DkimIdentity, self.dkim_identity.into_value()); map.insert_unchecked(Property::DkimSelector, self.dkim_selector.into_value()); map.insert_unchecked( Property::DkimSelectorDns, self.dkim_selector_dns.into_value(), ); map.insert_unchecked(Property::SpfDns, self.spf_dns.into_value()); map.insert_unchecked( Property::IdentityAlignment, self.identity_alignment.into_value(), ); map.insert_unchecked(Property::Message, self.message.into_value()); map.insert_unchecked(Property::Headers, self.headers.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ArfFeedbackReport { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::FeedbackType) => self.feedback_type.patch(pointer, value), Some(Property::ArrivalDate) => self.arrival_date.patch(pointer, value), Some(Property::AuthenticationResults) => { self.authentication_results.patch(pointer, value) } Some(Property::Incidents) => self.incidents.patch(pointer, value), Some(Property::OriginalEnvelopeId) => self.original_envelope_id.patch(pointer, value), Some(Property::OriginalMailFrom) => self .original_mail_from .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::OriginalRcptTo) => self .original_rcpt_to .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::ReportedDomains) => self .reported_domains .patch(pointer.with_validators(&[StringValidator::Domain]), value), Some(Property::ReportedUris) => self.reported_uris.patch(pointer, value), Some(Property::ReportingMta) => self.reporting_mta.patch(pointer, value), Some(Property::SourceIp) => self.source_ip.patch(pointer, value), Some(Property::SourcePort) => self.source_port.patch(pointer, value), Some(Property::UserAgent) => self.user_agent.patch(pointer, value), Some(Property::Version) => self.version.patch(pointer, value), Some(Property::AuthFailure) => self.auth_failure.patch(pointer, value), Some(Property::DeliveryResult) => self.delivery_result.patch(pointer, value), Some(Property::DkimAdspDns) => self.dkim_adsp_dns.patch(pointer, value), Some(Property::DkimCanonicalizedBody) => { self.dkim_canonicalized_body.patch(pointer, value) } Some(Property::DkimCanonicalizedHeader) => { self.dkim_canonicalized_header.patch(pointer, value) } Some(Property::DkimDomain) => self.dkim_domain.patch(pointer, value), Some(Property::DkimIdentity) => self.dkim_identity.patch(pointer, value), Some(Property::DkimSelector) => self.dkim_selector.patch(pointer, value), Some(Property::DkimSelectorDns) => self.dkim_selector_dns.patch(pointer, value), Some(Property::SpfDns) => self.spf_dns.patch(pointer, value), Some(Property::IdentityAlignment) => self.identity_alignment.patch(pointer, value), Some(Property::Message) => self.message.patch(pointer, value), Some(Property::Headers) => self.headers.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Asn { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Asn; fn validate(&self, errors: &mut Vec) -> bool { match self { Asn::Disabled => true, Asn::Resource(inner) => inner.validate(errors), Asn::Dns(inner) => inner.validate(errors), } } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Default for Asn { fn default() -> Self { Asn::Disabled } } impl Pickle for Asn { fn pickle(&self, out: &mut Vec) { match self { Asn::Disabled => { 0u16.pickle(out); } Asn::Resource(inner) => { 1u16.pickle(out); inner.pickle(out); } Asn::Dns(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(Asn::Disabled), 1 => Pickle::unpickle(stream).map(Asn::Resource), 2 => Pickle::unpickle(stream).map(Asn::Dns), _ => None, } } } impl IntoValue for Asn { fn into_value(self) -> JmapValue<'static> { match self { Asn::Disabled => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Disabled".into())); JmapValue::Object(obj) } Asn::Resource(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Resource".into())); obj } Asn::Dns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Dns".into())); obj } } } } impl RegistryJsonPatch for Asn { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { AsnType::Disabled => *self = Asn::Disabled, AsnType::Resource => *self = Asn::Resource(Default::default()), AsnType::Dns => *self = Asn::Dns(Default::default()), } } match self { Asn::Disabled => pointer.assert_eof(), Asn::Resource(inner) => inner.patch(pointer, value), Asn::Dns(inner) => inner.patch(pointer, value), } } } impl Asn { pub fn object_type(&self) -> AsnType { match self { Asn::Disabled => AsnType::Disabled, Asn::Resource(_) => AsnType::Resource, Asn::Dns(_) => AsnType::Dns, } } } impl AsnDns { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.separator; if value.is_empty() { errors.push(ValidationError::required(Property::Separator)); } let value = &self.zone_ip_v4; if value.is_empty() { errors.push(ValidationError::required(Property::ZoneIpV4)); } let value = &self.zone_ip_v6; if value.is_empty() { errors.push(ValidationError::required(Property::ZoneIpV6)); } errors.len() == neb } } impl Pickle for AsnDns { fn pickle(&self, out: &mut Vec) { self.index_asn.pickle(out); self.index_asn_name.pickle(out); self.index_country.pickle(out); self.separator.pickle(out); self.zone_ip_v4.pickle(out); self.zone_ip_v6.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.index_asn = Pickle::unpickle(stream)?; this.index_asn_name = Pickle::unpickle(stream)?; this.index_country = Pickle::unpickle(stream)?; this.separator = Pickle::unpickle(stream)?; this.zone_ip_v4 = Pickle::unpickle(stream)?; this.zone_ip_v6 = Pickle::unpickle(stream)?; Some(this) } } impl Default for AsnDns { fn default() -> Self { Self { index_asn: 0u64, index_asn_name: Default::default(), index_country: Default::default(), separator: "|".to_string(), zone_ip_v4: Default::default(), zone_ip_v6: Default::default(), } } } impl IntoValue for AsnDns { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::IndexAsn, self.index_asn.into_value()); map.insert_unchecked(Property::IndexAsnName, self.index_asn_name.into_value()); map.insert_unchecked(Property::IndexCountry, self.index_country.into_value()); map.insert_unchecked(Property::Separator, self.separator.into_value()); map.insert_unchecked(Property::ZoneIpV4, self.zone_ip_v4.into_value()); map.insert_unchecked(Property::ZoneIpV6, self.zone_ip_v6.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for AsnDns { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::IndexAsn) => self.index_asn.patch(pointer, value), Some(Property::IndexAsnName) => self.index_asn_name.patch(pointer, value), Some(Property::IndexCountry) => self.index_country.patch(pointer, value), Some(Property::Separator) => self .separator .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ZoneIpV4) => self .zone_ip_v4 .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ZoneIpV6) => self .zone_ip_v6 .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl AsnResource { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.asn_urls; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::AsnUrls)); } } let value = &self.geo_urls; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::GeoUrls)); } } let value = &self.http_auth; value.validate(errors); let value = &self.http_headers; for value in value.values() { if value.is_empty() { errors.push(ValidationError::required(Property::HttpHeaders)); } } errors.len() == neb } } impl Pickle for AsnResource { fn pickle(&self, out: &mut Vec) { self.expires.pickle(out); self.max_size.pickle(out); self.timeout.pickle(out); self.asn_urls.pickle(out); self.geo_urls.pickle(out); self.http_auth.pickle(out); self.http_headers.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.expires = Pickle::unpickle(stream)?; this.max_size = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.asn_urls = Pickle::unpickle(stream)?; this.geo_urls = Pickle::unpickle(stream)?; this.http_auth = Pickle::unpickle(stream)?; this.http_headers = Pickle::unpickle(stream)?; Some(this) } } impl Default for AsnResource { fn default() -> Self { Self { expires: Duration::from_millis(86400000), max_size: 104857600, timeout: Duration::from_millis(300000), asn_urls: Default::default(), geo_urls: Default::default(), http_auth: Default::default(), http_headers: Default::default(), } } } impl IntoValue for AsnResource { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked(Property::Expires, self.expires.into_value()); map.insert_unchecked(Property::MaxSize, self.max_size.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::AsnUrls, self.asn_urls.into_value()); map.insert_unchecked(Property::GeoUrls, self.geo_urls.into_value()); map.insert_unchecked(Property::HttpAuth, self.http_auth.into_value()); map.insert_unchecked(Property::HttpHeaders, self.http_headers.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for AsnResource { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Expires) => self.expires.patch(pointer, value), Some(Property::MaxSize) => self.max_size.patch(pointer, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::AsnUrls) => self .asn_urls .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::GeoUrls) => self .geo_urls .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::HttpAuth) => self.http_auth.patch(pointer, value), Some(Property::HttpHeaders) => self .http_headers .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Authentication { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Authentication; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.directory_id { if !value.is_valid() { errors.push(ValidationError::required(Property::DirectoryId)); } } let value = &self.default_user_role_ids; for value in value.iter() { if !value.is_valid() { errors.push(ValidationError::required(Property::DefaultUserRoleIds)); } } let value = &self.default_group_role_ids; for value in value.iter() { if !value.is_valid() { errors.push(ValidationError::required(Property::DefaultGroupRoleIds)); } } let value = &self.default_tenant_role_ids; for value in value.iter() { if !value.is_valid() { errors.push(ValidationError::required(Property::DefaultTenantRoleIds)); } } let value = &self.default_admin_role_ids; for value in value.iter() { if !value.is_valid() { errors.push(ValidationError::required(Property::DefaultAdminRoleIds)); } } let value = &self.password_min_length; if *value < 1 { errors.push(ValidationError::min_value(Property::PasswordMinLength, 1)); } if *value > 100 { errors.push(ValidationError::max_value(Property::PasswordMinLength, 100)); } let value = &self.password_max_length; if *value < 1 { errors.push(ValidationError::min_value(Property::PasswordMaxLength, 1)); } if *value > 1000 { errors.push(ValidationError::max_value( Property::PasswordMaxLength, 1000, )); } if let Some(value) = &self.max_app_passwords { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxAppPasswords, 1)); } } if let Some(value) = &self.max_api_keys { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxApiKeys, 1)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Directory, self.directory_id, None); for id in self.default_user_role_ids.iter() { i.foreign_key(ObjectType::Role, Some(*id), None); } for id in self.default_group_role_ids.iter() { i.foreign_key(ObjectType::Role, Some(*id), None); } for id in self.default_tenant_role_ids.iter() { i.foreign_key(ObjectType::Role, Some(*id), None); } for id in self.default_admin_role_ids.iter() { i.foreign_key(ObjectType::Role, Some(*id), None); } } } impl Pickle for Authentication { fn pickle(&self, out: &mut Vec) { self.directory_id.pickle(out); self.default_user_role_ids.pickle(out); self.default_group_role_ids.pickle(out); self.default_tenant_role_ids.pickle(out); self.default_admin_role_ids.pickle(out); self.password_hash_algorithm.pickle(out); self.password_min_length.pickle(out); self.password_max_length.pickle(out); self.password_min_strength.pickle(out); self.password_default_expiry.pickle(out); self.max_app_passwords.pickle(out); self.max_api_keys.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.directory_id = Pickle::unpickle(stream)?; this.default_user_role_ids = Pickle::unpickle(stream)?; this.default_group_role_ids = Pickle::unpickle(stream)?; this.default_tenant_role_ids = Pickle::unpickle(stream)?; this.default_admin_role_ids = Pickle::unpickle(stream)?; this.password_hash_algorithm = Pickle::unpickle(stream)?; this.password_min_length = Pickle::unpickle(stream)?; this.password_max_length = Pickle::unpickle(stream)?; this.password_min_strength = Pickle::unpickle(stream)?; this.password_default_expiry = Pickle::unpickle(stream)?; this.max_app_passwords = Pickle::unpickle(stream)?; this.max_api_keys = Pickle::unpickle(stream)?; Some(this) } } impl Default for Authentication { fn default() -> Self { Self { directory_id: Default::default(), default_user_role_ids: Default::default(), default_group_role_ids: Default::default(), default_tenant_role_ids: Default::default(), default_admin_role_ids: Default::default(), password_hash_algorithm: PasswordHashAlgorithm::Argon2id, password_min_length: 8u64, password_max_length: 128u64, password_min_strength: PasswordStrength::Three, password_default_expiry: Default::default(), max_app_passwords: Some(5u64), max_api_keys: Some(5u64), } } } impl IntoValue for Authentication { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked(Property::DirectoryId, self.directory_id.into_value()); map.insert_unchecked( Property::DefaultUserRoleIds, self.default_user_role_ids.into_value(), ); map.insert_unchecked( Property::DefaultGroupRoleIds, self.default_group_role_ids.into_value(), ); map.insert_unchecked( Property::DefaultTenantRoleIds, self.default_tenant_role_ids.into_value(), ); map.insert_unchecked( Property::DefaultAdminRoleIds, self.default_admin_role_ids.into_value(), ); map.insert_unchecked( Property::PasswordHashAlgorithm, self.password_hash_algorithm.into_value(), ); map.insert_unchecked( Property::PasswordMinLength, self.password_min_length.into_value(), ); map.insert_unchecked( Property::PasswordMaxLength, self.password_max_length.into_value(), ); map.insert_unchecked( Property::PasswordMinStrength, self.password_min_strength.into_value(), ); map.insert_unchecked( Property::PasswordDefaultExpiry, self.password_default_expiry.into_value(), ); map.insert_unchecked( Property::MaxAppPasswords, self.max_app_passwords.into_value(), ); map.insert_unchecked(Property::MaxApiKeys, self.max_api_keys.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Authentication { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::DirectoryId) => self.directory_id.patch(pointer, value), Some(Property::DefaultUserRoleIds) => self.default_user_role_ids.patch(pointer, value), Some(Property::DefaultGroupRoleIds) => { self.default_group_role_ids.patch(pointer, value) } Some(Property::DefaultTenantRoleIds) => { self.default_tenant_role_ids.patch(pointer, value) } Some(Property::DefaultAdminRoleIds) => { self.default_admin_role_ids.patch(pointer, value) } Some(Property::PasswordHashAlgorithm) => { self.password_hash_algorithm.patch(pointer, value) } Some(Property::PasswordMinLength) => self.password_min_length.patch(pointer, value), Some(Property::PasswordMaxLength) => self.password_max_length.patch(pointer, value), Some(Property::PasswordMinStrength) => self.password_min_strength.patch(pointer, value), Some(Property::PasswordDefaultExpiry) => { self.password_default_expiry.patch(pointer, value) } Some(Property::MaxAppPasswords) => self.max_app_passwords.patch(pointer, value), Some(Property::MaxApiKeys) => self.max_api_keys.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl AzureStore { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.storage_account; if value.is_empty() { errors.push(ValidationError::required(Property::StorageAccount)); } let value = &self.container; if value.is_empty() { errors.push(ValidationError::required(Property::Container)); } let value = &self.access_key; value.validate(errors); let value = &self.sas_token; value.validate(errors); let value = &self.max_retries; if *value > 10 { errors.push(ValidationError::max_value(Property::MaxRetries, 10)); } if *value < 1 { errors.push(ValidationError::min_value(Property::MaxRetries, 1)); } if let Some(value) = &self.key_prefix { if value.is_empty() { errors.push(ValidationError::required(Property::KeyPrefix)); } } errors.len() == neb } } impl Pickle for AzureStore { fn pickle(&self, out: &mut Vec) { self.storage_account.pickle(out); self.container.pickle(out); self.access_key.pickle(out); self.sas_token.pickle(out); self.timeout.pickle(out); self.max_retries.pickle(out); self.key_prefix.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.storage_account = Pickle::unpickle(stream)?; this.container = Pickle::unpickle(stream)?; this.access_key = Pickle::unpickle(stream)?; this.sas_token = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.max_retries = Pickle::unpickle(stream)?; this.key_prefix = Pickle::unpickle(stream)?; Some(this) } } impl Default for AzureStore { fn default() -> Self { Self { storage_account: Default::default(), container: Default::default(), access_key: Default::default(), sas_token: Default::default(), timeout: Duration::from_millis(30000), max_retries: 3u64, key_prefix: Default::default(), } } } impl IntoValue for AzureStore { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked(Property::StorageAccount, self.storage_account.into_value()); map.insert_unchecked(Property::Container, self.container.into_value()); map.insert_unchecked(Property::AccessKey, self.access_key.into_value()); map.insert_unchecked(Property::SasToken, self.sas_token.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::MaxRetries, self.max_retries.into_value()); map.insert_unchecked(Property::KeyPrefix, self.key_prefix.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for AzureStore { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::StorageAccount) => self .storage_account .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Container) => self .container .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AccessKey) => self.access_key.patch(pointer, value), Some(Property::SasToken) => self.sas_token.patch(pointer, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::MaxRetries) => self.max_retries.patch(pointer, value), Some(Property::KeyPrefix) => self .key_prefix .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for BlobStore { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 1; const OBJECT: ObjectType = ObjectType::BlobStore; fn validate(&self, errors: &mut Vec) -> bool { match self { BlobStore::Default => true, BlobStore::Sharded(inner) => inner.validate(errors), BlobStore::S3(inner) => inner.validate(errors), BlobStore::Azure(inner) => inner.validate(errors), BlobStore::FileSystem(inner) => inner.validate(errors), BlobStore::FoundationDb(inner) => inner.validate(errors), BlobStore::PostgreSql(inner) => inner.validate(errors), BlobStore::MySql(inner) => inner.validate(errors), } } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Default for BlobStore { fn default() -> Self { BlobStore::Default } } impl Pickle for BlobStore { fn pickle(&self, out: &mut Vec) { match self { BlobStore::Default => { 0u16.pickle(out); } BlobStore::Sharded(inner) => { 1u16.pickle(out); inner.pickle(out); } BlobStore::S3(inner) => { 2u16.pickle(out); inner.pickle(out); } BlobStore::Azure(inner) => { 3u16.pickle(out); inner.pickle(out); } BlobStore::FileSystem(inner) => { 4u16.pickle(out); inner.pickle(out); } BlobStore::FoundationDb(inner) => { 5u16.pickle(out); inner.pickle(out); } BlobStore::PostgreSql(inner) => { 6u16.pickle(out); inner.pickle(out); } BlobStore::MySql(inner) => { 7u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(BlobStore::Default), 1 => Pickle::unpickle(stream).map(BlobStore::Sharded), 2 => Pickle::unpickle(stream).map(BlobStore::S3), 3 => Pickle::unpickle(stream).map(BlobStore::Azure), 4 => Pickle::unpickle(stream).map(BlobStore::FileSystem), 5 => Pickle::unpickle(stream).map(BlobStore::FoundationDb), 6 => Pickle::unpickle(stream).map(BlobStore::PostgreSql), 7 => Pickle::unpickle(stream).map(BlobStore::MySql), _ => None, } } } impl IntoValue for BlobStore { fn into_value(self) -> JmapValue<'static> { match self { BlobStore::Default => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Default".into())); JmapValue::Object(obj) } BlobStore::Sharded(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Sharded".into())); obj } BlobStore::S3(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("S3".into())); obj } BlobStore::Azure(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Azure".into())); obj } BlobStore::FileSystem(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("FileSystem".into())); obj } BlobStore::FoundationDb(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("FoundationDb".into())); obj } BlobStore::PostgreSql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("PostgreSql".into())); obj } BlobStore::MySql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("MySql".into())); obj } } } } impl RegistryJsonPatch for BlobStore { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { BlobStoreType::Default => *self = BlobStore::Default, BlobStoreType::Sharded => *self = BlobStore::Sharded(Default::default()), BlobStoreType::S3 => *self = BlobStore::S3(Default::default()), BlobStoreType::Azure => *self = BlobStore::Azure(Default::default()), BlobStoreType::FileSystem => *self = BlobStore::FileSystem(Default::default()), BlobStoreType::FoundationDb => *self = BlobStore::FoundationDb(Default::default()), BlobStoreType::PostgreSql => *self = BlobStore::PostgreSql(Default::default()), BlobStoreType::MySql => *self = BlobStore::MySql(Default::default()), } } match self { BlobStore::Default => pointer.assert_eof(), BlobStore::Sharded(inner) => inner.patch(pointer, value), BlobStore::S3(inner) => inner.patch(pointer, value), BlobStore::Azure(inner) => inner.patch(pointer, value), BlobStore::FileSystem(inner) => inner.patch(pointer, value), BlobStore::FoundationDb(inner) => inner.patch(pointer, value), BlobStore::PostgreSql(inner) => inner.patch(pointer, value), BlobStore::MySql(inner) => inner.patch(pointer, value), } } } impl BlobStore { pub fn object_type(&self) -> BlobStoreType { match self { BlobStore::Default => BlobStoreType::Default, BlobStore::Sharded(_) => BlobStoreType::Sharded, BlobStore::S3(_) => BlobStoreType::S3, BlobStore::Azure(_) => BlobStoreType::Azure, BlobStore::FileSystem(_) => BlobStoreType::FileSystem, BlobStore::FoundationDb(_) => BlobStoreType::FoundationDb, BlobStore::PostgreSql(_) => BlobStoreType::PostgreSql, BlobStore::MySql(_) => BlobStoreType::MySql, } } } impl BlobStoreBase { fn validate(&self, errors: &mut Vec) -> bool { match self { BlobStoreBase::S3(inner) => inner.validate(errors), BlobStoreBase::Azure(inner) => inner.validate(errors), BlobStoreBase::FileSystem(inner) => inner.validate(errors), BlobStoreBase::FoundationDb(inner) => inner.validate(errors), BlobStoreBase::PostgreSql(inner) => inner.validate(errors), BlobStoreBase::MySql(inner) => inner.validate(errors), } } } impl Default for BlobStoreBase { fn default() -> Self { BlobStoreBase::S3(Default::default()) } } impl Pickle for BlobStoreBase { fn pickle(&self, out: &mut Vec) { match self { BlobStoreBase::S3(inner) => { 0u16.pickle(out); inner.pickle(out); } BlobStoreBase::Azure(inner) => { 1u16.pickle(out); inner.pickle(out); } BlobStoreBase::FileSystem(inner) => { 2u16.pickle(out); inner.pickle(out); } BlobStoreBase::FoundationDb(inner) => { 3u16.pickle(out); inner.pickle(out); } BlobStoreBase::PostgreSql(inner) => { 4u16.pickle(out); inner.pickle(out); } BlobStoreBase::MySql(inner) => { 5u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(BlobStoreBase::S3), 1 => Pickle::unpickle(stream).map(BlobStoreBase::Azure), 2 => Pickle::unpickle(stream).map(BlobStoreBase::FileSystem), 3 => Pickle::unpickle(stream).map(BlobStoreBase::FoundationDb), 4 => Pickle::unpickle(stream).map(BlobStoreBase::PostgreSql), 5 => Pickle::unpickle(stream).map(BlobStoreBase::MySql), _ => None, } } } impl IntoValue for BlobStoreBase { fn into_value(self) -> JmapValue<'static> { match self { BlobStoreBase::S3(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("S3".into())); obj } BlobStoreBase::Azure(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Azure".into())); obj } BlobStoreBase::FileSystem(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("FileSystem".into())); obj } BlobStoreBase::FoundationDb(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("FoundationDb".into())); obj } BlobStoreBase::PostgreSql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("PostgreSql".into())); obj } BlobStoreBase::MySql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("MySql".into())); obj } } } } impl RegistryJsonPatch for BlobStoreBase { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { BlobStoreBaseType::S3 => *self = BlobStoreBase::S3(Default::default()), BlobStoreBaseType::Azure => *self = BlobStoreBase::Azure(Default::default()), BlobStoreBaseType::FileSystem => { *self = BlobStoreBase::FileSystem(Default::default()) } BlobStoreBaseType::FoundationDb => { *self = BlobStoreBase::FoundationDb(Default::default()) } BlobStoreBaseType::PostgreSql => { *self = BlobStoreBase::PostgreSql(Default::default()) } BlobStoreBaseType::MySql => *self = BlobStoreBase::MySql(Default::default()), } } match self { BlobStoreBase::S3(inner) => inner.patch(pointer, value), BlobStoreBase::Azure(inner) => inner.patch(pointer, value), BlobStoreBase::FileSystem(inner) => inner.patch(pointer, value), BlobStoreBase::FoundationDb(inner) => inner.patch(pointer, value), BlobStoreBase::PostgreSql(inner) => inner.patch(pointer, value), BlobStoreBase::MySql(inner) => inner.patch(pointer, value), } } } impl BlobStoreBase { pub fn object_type(&self) -> BlobStoreBaseType { match self { BlobStoreBase::S3(_) => BlobStoreBaseType::S3, BlobStoreBase::Azure(_) => BlobStoreBaseType::Azure, BlobStoreBase::FileSystem(_) => BlobStoreBaseType::FileSystem, BlobStoreBase::FoundationDb(_) => BlobStoreBaseType::FoundationDb, BlobStoreBase::PostgreSql(_) => BlobStoreBaseType::PostgreSql, BlobStoreBase::MySql(_) => BlobStoreBaseType::MySql, } } } impl ObjectImpl for BlockedIp { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::BlockedIp; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.address; if !value.is_valid() { errors.push(ValidationError::invalid(Property::Address, value)); } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } if let Some(value) = &self.expires_at { if !value.is_valid() { errors.push(ValidationError::invalid(Property::ExpiresAt, value)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Address, &self.address); } } impl Pickle for BlockedIp { fn pickle(&self, out: &mut Vec) { self.address.pickle(out); self.reason.pickle(out); self.created_at.pickle(out); self.expires_at.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.address = Pickle::unpickle(stream)?; this.reason = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.expires_at = Pickle::unpickle(stream)?; Some(this) } } impl Default for BlockedIp { fn default() -> Self { Self { address: Default::default(), reason: BlockReason::Manual, created_at: Default::default(), expires_at: Default::default(), } } } impl IntoValue for BlockedIp { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Address, self.address.into_value()); map.insert_unchecked(Property::Reason, self.reason.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::ExpiresAt, self.expires_at.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for BlockedIp { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Address) => self.address.patch(pointer.assert_read_only()?, value), Some(Property::Reason) => self.reason.patch(pointer, value), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::ExpiresAt) => self.expires_at.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Bootstrap { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 1; const OBJECT: ObjectType = ObjectType::Bootstrap; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.server_hostname; if value.is_empty() { errors.push(ValidationError::required(Property::ServerHostname)); } let value = &self.default_domain; if value.is_empty() { errors.push(ValidationError::required(Property::DefaultDomain)); } let value = &self.data_store; value.validate(errors); let value = &self.blob_store; value.validate(errors); let value = &self.search_store; value.validate(errors); let value = &self.in_memory_store; value.validate(errors); let value = &self.directory; value.validate(errors); let value = &self.tracer; value.validate(errors); let value = &self.dns_server; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for Bootstrap { fn pickle(&self, out: &mut Vec) { self.server_hostname.pickle(out); self.default_domain.pickle(out); self.request_tls_certificate.pickle(out); self.generate_dkim_keys.pickle(out); self.data_store.pickle(out); self.blob_store.pickle(out); self.search_store.pickle(out); self.in_memory_store.pickle(out); self.directory.pickle(out); self.tracer.pickle(out); self.dns_server.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.server_hostname = Pickle::unpickle(stream)?; this.default_domain = Pickle::unpickle(stream)?; this.request_tls_certificate = Pickle::unpickle(stream)?; this.generate_dkim_keys = Pickle::unpickle(stream)?; this.data_store = Pickle::unpickle(stream)?; this.blob_store = Pickle::unpickle(stream)?; this.search_store = Pickle::unpickle(stream)?; this.in_memory_store = Pickle::unpickle(stream)?; this.directory = Pickle::unpickle(stream)?; this.tracer = Pickle::unpickle(stream)?; this.dns_server = Pickle::unpickle(stream)?; Some(this) } } impl Default for Bootstrap { fn default() -> Self { Self { server_hostname: Default::default(), default_domain: Default::default(), request_tls_certificate: true, generate_dkim_keys: true, data_store: DataStore::RocksDb(RocksDbStore { path: "/var/lib/stalwart/".to_string(), ..Default::default() }), blob_store: BlobStore::Default, search_store: SearchStore::Default, in_memory_store: InMemoryStore::Default, directory: DirectoryBootstrap::Internal, tracer: Tracer::Log(TracerLog { path: "/var/log/stalwart/".to_string(), ..Default::default() }), dns_server: DnsServerBootstrap::Manual, } } } impl IntoValue for Bootstrap { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(13); map.insert_unchecked(Property::ServerHostname, self.server_hostname.into_value()); map.insert_unchecked(Property::DefaultDomain, self.default_domain.into_value()); map.insert_unchecked( Property::RequestTlsCertificate, self.request_tls_certificate.into_value(), ); map.insert_unchecked( Property::GenerateDkimKeys, self.generate_dkim_keys.into_value(), ); map.insert_unchecked(Property::DataStore, self.data_store.into_value()); map.insert_unchecked(Property::BlobStore, self.blob_store.into_value()); map.insert_unchecked(Property::SearchStore, self.search_store.into_value()); map.insert_unchecked(Property::InMemoryStore, self.in_memory_store.into_value()); map.insert_unchecked(Property::Directory, self.directory.into_value()); map.insert_unchecked(Property::Tracer, self.tracer.into_value()); map.insert_unchecked(Property::DnsServer, self.dns_server.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Bootstrap { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ServerHostname) => self.server_hostname.patch(pointer, value), Some(Property::DefaultDomain) => self.default_domain.patch(pointer, value), Some(Property::RequestTlsCertificate) => { self.request_tls_certificate.patch(pointer, value) } Some(Property::GenerateDkimKeys) => self.generate_dkim_keys.patch(pointer, value), Some(Property::DataStore) => self.data_store.patch(pointer, value), Some(Property::BlobStore) => self.blob_store.patch(pointer, value), Some(Property::SearchStore) => self.search_store.patch(pointer, value), Some(Property::InMemoryStore) => self.in_memory_store.patch(pointer, value), Some(Property::Directory) => self.directory.patch(pointer, value), Some(Property::Tracer) => self.tracer.patch(pointer, value), Some(Property::DnsServer) => self.dns_server.patch(pointer, value), Some(Property::Username) => pointer.assert_server_set(), Some(Property::Secret) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Cache { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Cache; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.access_tokens; if *value < 2048 { errors.push(ValidationError::min_value(Property::AccessTokens, 2048)); } let value = &self.contacts; if *value < 2048 { errors.push(ValidationError::min_value(Property::Contacts, 2048)); } let value = &self.dns_ipv4; if *value < 2048 { errors.push(ValidationError::min_value(Property::DnsIpv4, 2048)); } let value = &self.dns_ipv6; if *value < 2048 { errors.push(ValidationError::min_value(Property::DnsIpv6, 2048)); } let value = &self.dns_mta_sts; if *value < 2048 { errors.push(ValidationError::min_value(Property::DnsMtaSts, 2048)); } let value = &self.dns_mx; if *value < 2048 { errors.push(ValidationError::min_value(Property::DnsMx, 2048)); } let value = &self.dns_ptr; if *value < 2048 { errors.push(ValidationError::min_value(Property::DnsPtr, 2048)); } let value = &self.dns_rbl; if *value < 2048 { errors.push(ValidationError::min_value(Property::DnsRbl, 2048)); } let value = &self.dns_tlsa; if *value < 2048 { errors.push(ValidationError::min_value(Property::DnsTlsa, 2048)); } let value = &self.dns_txt; if *value < 2048 { errors.push(ValidationError::min_value(Property::DnsTxt, 2048)); } let value = &self.events; if *value < 2048 { errors.push(ValidationError::min_value(Property::Events, 2048)); } let value = &self.scheduling; if *value < 2048 { errors.push(ValidationError::min_value(Property::Scheduling, 2048)); } let value = &self.files; if *value < 2048 { errors.push(ValidationError::min_value(Property::Files, 2048)); } let value = &self.http_auth; if *value < 2048 { errors.push(ValidationError::min_value(Property::HttpAuth, 2048)); } let value = &self.messages; if *value < 2048 { errors.push(ValidationError::min_value(Property::Messages, 2048)); } let value = &self.domains; if *value < 2048 { errors.push(ValidationError::min_value(Property::Domains, 2048)); } let value = &self.domain_names; if *value < 2048 { errors.push(ValidationError::min_value(Property::DomainNames, 2048)); } let value = &self.domain_names_negative; if *value < 2048 { errors.push(ValidationError::min_value( Property::DomainNamesNegative, 2048, )); } let value = &self.email_addresses; if *value < 2048 { errors.push(ValidationError::min_value(Property::EmailAddresses, 2048)); } let value = &self.email_addresses_negative; if *value < 2048 { errors.push(ValidationError::min_value( Property::EmailAddressesNegative, 2048, )); } let value = &self.accounts; if *value < 2048 { errors.push(ValidationError::min_value(Property::Accounts, 2048)); } let value = &self.roles; if *value < 2048 { errors.push(ValidationError::min_value(Property::Roles, 2048)); } let value = &self.tenants; if *value < 2048 { errors.push(ValidationError::min_value(Property::Tenants, 2048)); } let value = &self.mailing_lists; if *value < 2048 { errors.push(ValidationError::min_value(Property::MailingLists, 2048)); } let value = &self.dkim_signatures; if *value < 2048 { errors.push(ValidationError::min_value(Property::DkimSignatures, 2048)); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for Cache { fn pickle(&self, out: &mut Vec) { self.access_tokens.pickle(out); self.contacts.pickle(out); self.dns_ipv4.pickle(out); self.dns_ipv6.pickle(out); self.dns_mta_sts.pickle(out); self.dns_mx.pickle(out); self.dns_ptr.pickle(out); self.dns_rbl.pickle(out); self.dns_tlsa.pickle(out); self.dns_txt.pickle(out); self.events.pickle(out); self.scheduling.pickle(out); self.files.pickle(out); self.http_auth.pickle(out); self.messages.pickle(out); self.domains.pickle(out); self.domain_names.pickle(out); self.domain_names_negative.pickle(out); self.email_addresses.pickle(out); self.email_addresses_negative.pickle(out); self.accounts.pickle(out); self.roles.pickle(out); self.tenants.pickle(out); self.mailing_lists.pickle(out); self.dkim_signatures.pickle(out); self.negative_ttl.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.access_tokens = Pickle::unpickle(stream)?; this.contacts = Pickle::unpickle(stream)?; this.dns_ipv4 = Pickle::unpickle(stream)?; this.dns_ipv6 = Pickle::unpickle(stream)?; this.dns_mta_sts = Pickle::unpickle(stream)?; this.dns_mx = Pickle::unpickle(stream)?; this.dns_ptr = Pickle::unpickle(stream)?; this.dns_rbl = Pickle::unpickle(stream)?; this.dns_tlsa = Pickle::unpickle(stream)?; this.dns_txt = Pickle::unpickle(stream)?; this.events = Pickle::unpickle(stream)?; this.scheduling = Pickle::unpickle(stream)?; this.files = Pickle::unpickle(stream)?; this.http_auth = Pickle::unpickle(stream)?; this.messages = Pickle::unpickle(stream)?; this.domains = Pickle::unpickle(stream)?; this.domain_names = Pickle::unpickle(stream)?; this.domain_names_negative = Pickle::unpickle(stream)?; this.email_addresses = Pickle::unpickle(stream)?; this.email_addresses_negative = Pickle::unpickle(stream)?; this.accounts = Pickle::unpickle(stream)?; this.roles = Pickle::unpickle(stream)?; this.tenants = Pickle::unpickle(stream)?; this.mailing_lists = Pickle::unpickle(stream)?; this.dkim_signatures = Pickle::unpickle(stream)?; this.negative_ttl = Pickle::unpickle(stream)?; Some(this) } } impl Default for Cache { fn default() -> Self { Self { access_tokens: 10485760, contacts: 10485760, dns_ipv4: 5242880, dns_ipv6: 5242880, dns_mta_sts: 1048576, dns_mx: 5242880, dns_ptr: 1048576, dns_rbl: 5242880, dns_tlsa: 1048576, dns_txt: 5242880, events: 10485760, scheduling: 1048576, files: 10485760, http_auth: 1048576, messages: 52428800, domains: 5242880, domain_names: 10485760, domain_names_negative: 1048576, email_addresses: 10485760, email_addresses_negative: 2097152, accounts: 20971520, roles: 5242880, tenants: 5242880, mailing_lists: 2097152, dkim_signatures: 10485760, negative_ttl: Duration::from_millis(3600000), } } } impl IntoValue for Cache { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(28); map.insert_unchecked(Property::AccessTokens, self.access_tokens.into_value()); map.insert_unchecked(Property::Contacts, self.contacts.into_value()); map.insert_unchecked(Property::DnsIpv4, self.dns_ipv4.into_value()); map.insert_unchecked(Property::DnsIpv6, self.dns_ipv6.into_value()); map.insert_unchecked(Property::DnsMtaSts, self.dns_mta_sts.into_value()); map.insert_unchecked(Property::DnsMx, self.dns_mx.into_value()); map.insert_unchecked(Property::DnsPtr, self.dns_ptr.into_value()); map.insert_unchecked(Property::DnsRbl, self.dns_rbl.into_value()); map.insert_unchecked(Property::DnsTlsa, self.dns_tlsa.into_value()); map.insert_unchecked(Property::DnsTxt, self.dns_txt.into_value()); map.insert_unchecked(Property::Events, self.events.into_value()); map.insert_unchecked(Property::Scheduling, self.scheduling.into_value()); map.insert_unchecked(Property::Files, self.files.into_value()); map.insert_unchecked(Property::HttpAuth, self.http_auth.into_value()); map.insert_unchecked(Property::Messages, self.messages.into_value()); map.insert_unchecked(Property::Domains, self.domains.into_value()); map.insert_unchecked(Property::DomainNames, self.domain_names.into_value()); map.insert_unchecked( Property::DomainNamesNegative, self.domain_names_negative.into_value(), ); map.insert_unchecked(Property::EmailAddresses, self.email_addresses.into_value()); map.insert_unchecked( Property::EmailAddressesNegative, self.email_addresses_negative.into_value(), ); map.insert_unchecked(Property::Accounts, self.accounts.into_value()); map.insert_unchecked(Property::Roles, self.roles.into_value()); map.insert_unchecked(Property::Tenants, self.tenants.into_value()); map.insert_unchecked(Property::MailingLists, self.mailing_lists.into_value()); map.insert_unchecked(Property::DkimSignatures, self.dkim_signatures.into_value()); map.insert_unchecked(Property::NegativeTtl, self.negative_ttl.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Cache { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AccessTokens) => self.access_tokens.patch(pointer, value), Some(Property::Contacts) => self.contacts.patch(pointer, value), Some(Property::DnsIpv4) => self.dns_ipv4.patch(pointer, value), Some(Property::DnsIpv6) => self.dns_ipv6.patch(pointer, value), Some(Property::DnsMtaSts) => self.dns_mta_sts.patch(pointer, value), Some(Property::DnsMx) => self.dns_mx.patch(pointer, value), Some(Property::DnsPtr) => self.dns_ptr.patch(pointer, value), Some(Property::DnsRbl) => self.dns_rbl.patch(pointer, value), Some(Property::DnsTlsa) => self.dns_tlsa.patch(pointer, value), Some(Property::DnsTxt) => self.dns_txt.patch(pointer, value), Some(Property::Events) => self.events.patch(pointer, value), Some(Property::Scheduling) => self.scheduling.patch(pointer, value), Some(Property::Files) => self.files.patch(pointer, value), Some(Property::HttpAuth) => self.http_auth.patch(pointer, value), Some(Property::Messages) => self.messages.patch(pointer, value), Some(Property::Domains) => self.domains.patch(pointer, value), Some(Property::DomainNames) => self.domain_names.patch(pointer, value), Some(Property::DomainNamesNegative) => self.domain_names_negative.patch(pointer, value), Some(Property::EmailAddresses) => self.email_addresses.patch(pointer, value), Some(Property::EmailAddressesNegative) => { self.email_addresses_negative.patch(pointer, value) } Some(Property::Accounts) => self.accounts.patch(pointer, value), Some(Property::Roles) => self.roles.patch(pointer, value), Some(Property::Tenants) => self.tenants.patch(pointer, value), Some(Property::MailingLists) => self.mailing_lists.patch(pointer, value), Some(Property::DkimSignatures) => self.dkim_signatures.patch(pointer, value), Some(Property::NegativeTtl) => self.negative_ttl.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Calendar { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Calendar; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.default_display_name { if value.is_empty() { errors.push(ValidationError::required(Property::DefaultDisplayName)); } } if let Some(value) = &self.default_href_name { if value.is_empty() { errors.push(ValidationError::required(Property::DefaultHrefName)); } } let value = &self.max_attendees; if *value > 100000 { errors.push(ValidationError::max_value(Property::MaxAttendees, 100000)); } if let Some(value) = &self.max_calendars { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxCalendars, 1)); } } if let Some(value) = &self.max_events { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxEvents, 1)); } } if let Some(value) = &self.max_participant_identities { if *value < 1 { errors.push(ValidationError::min_value( Property::MaxParticipantIdentities, 1, )); } } if let Some(value) = &self.max_event_notifications { if *value < 1 { errors.push(ValidationError::min_value( Property::MaxEventNotifications, 1, )); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for Calendar { fn pickle(&self, out: &mut Vec) { self.default_display_name.pickle(out); self.default_href_name.pickle(out); self.max_attendees.pickle(out); self.max_recurrence_expansions.pickle(out); self.max_i_calendar_size.pickle(out); self.max_calendars.pickle(out); self.max_events.pickle(out); self.max_participant_identities.pickle(out); self.max_event_notifications.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.default_display_name = Pickle::unpickle(stream)?; this.default_href_name = Pickle::unpickle(stream)?; this.max_attendees = Pickle::unpickle(stream)?; this.max_recurrence_expansions = Pickle::unpickle(stream)?; this.max_i_calendar_size = Pickle::unpickle(stream)?; this.max_calendars = Pickle::unpickle(stream)?; this.max_events = Pickle::unpickle(stream)?; this.max_participant_identities = Pickle::unpickle(stream)?; this.max_event_notifications = Pickle::unpickle(stream)?; Some(this) } } impl Default for Calendar { fn default() -> Self { Self { default_display_name: Some("INBUXA Calendar".to_string()), default_href_name: Some("default".to_string()), max_attendees: 20u64, max_recurrence_expansions: 3000u64, max_i_calendar_size: 524288, max_calendars: Some(250u64), max_events: Default::default(), max_participant_identities: Some(100u64), max_event_notifications: Default::default(), } } } impl IntoValue for Calendar { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked( Property::DefaultDisplayName, self.default_display_name.into_value(), ); map.insert_unchecked( Property::DefaultHrefName, self.default_href_name.into_value(), ); map.insert_unchecked(Property::MaxAttendees, self.max_attendees.into_value()); map.insert_unchecked( Property::MaxRecurrenceExpansions, self.max_recurrence_expansions.into_value(), ); map.insert_unchecked( Property::MaxICalendarSize, self.max_i_calendar_size.into_value(), ); map.insert_unchecked(Property::MaxCalendars, self.max_calendars.into_value()); map.insert_unchecked(Property::MaxEvents, self.max_events.into_value()); map.insert_unchecked( Property::MaxParticipantIdentities, self.max_participant_identities.into_value(), ); map.insert_unchecked( Property::MaxEventNotifications, self.max_event_notifications.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Calendar { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::DefaultDisplayName) => self .default_display_name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::DefaultHrefName) => self .default_href_name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MaxAttendees) => self.max_attendees.patch(pointer, value), Some(Property::MaxRecurrenceExpansions) => { self.max_recurrence_expansions.patch(pointer, value) } Some(Property::MaxICalendarSize) => self.max_i_calendar_size.patch(pointer, value), Some(Property::MaxCalendars) => self.max_calendars.patch(pointer, value), Some(Property::MaxEvents) => self.max_events.patch(pointer, value), Some(Property::MaxParticipantIdentities) => { self.max_participant_identities.patch(pointer, value) } Some(Property::MaxEventNotifications) => { self.max_event_notifications.patch(pointer, value) } Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for CalendarAlarm { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::CalendarAlarm; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.from_email { if value.is_empty() { errors.push(ValidationError::required(Property::FromEmail)); } } let value = &self.from_name; if value.is_empty() { errors.push(ValidationError::required(Property::FromName)); } if let Some(value) = &self.template { if value.is_empty() { errors.push(ValidationError::required(Property::Template)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for CalendarAlarm { fn pickle(&self, out: &mut Vec) { self.allow_external_rcpts.pickle(out); self.enable.pickle(out); self.from_email.pickle(out); self.from_name.pickle(out); self.min_trigger_interval.pickle(out); self.template.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.allow_external_rcpts = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.from_email = Pickle::unpickle(stream)?; this.from_name = Pickle::unpickle(stream)?; this.min_trigger_interval = Pickle::unpickle(stream)?; this.template = Pickle::unpickle(stream)?; Some(this) } } impl Default for CalendarAlarm { fn default() -> Self { Self { allow_external_rcpts: false, enable: true, from_email: Default::default(), from_name: "INBUXA Calendar".to_string(), min_trigger_interval: Duration::from_millis(3600000), template: Default::default(), } } } impl IntoValue for CalendarAlarm { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked( Property::AllowExternalRcpts, self.allow_external_rcpts.into_value(), ); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::FromEmail, self.from_email.into_value()); map.insert_unchecked(Property::FromName, self.from_name.into_value()); map.insert_unchecked( Property::MinTriggerInterval, self.min_trigger_interval.into_value(), ); map.insert_unchecked(Property::Template, self.template.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for CalendarAlarm { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AllowExternalRcpts) => self.allow_external_rcpts.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::FromEmail) => self .from_email .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::FromName) => self .from_name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MinTriggerInterval) => self.min_trigger_interval.patch(pointer, value), Some(Property::Template) => self.template.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for CalendarScheduling { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::CalendarScheduling; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.http_rsvp_url { if value.is_empty() { errors.push(ValidationError::required(Property::HttpRsvpUrl)); } } let value = &self.itip_max_size; if *value < 100 { errors.push(ValidationError::min_value(Property::ItipMaxSize, 100)); } let value = &self.max_recipients; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxRecipients, 1)); } if let Some(value) = &self.email_template { if value.is_empty() { errors.push(ValidationError::required(Property::EmailTemplate)); } } if let Some(value) = &self.http_rsvp_template { if value.is_empty() { errors.push(ValidationError::required(Property::HttpRsvpTemplate)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for CalendarScheduling { fn pickle(&self, out: &mut Vec) { self.enable.pickle(out); self.http_rsvp_enable.pickle(out); self.http_rsvp_link_expiry.pickle(out); self.http_rsvp_url.pickle(out); self.auto_add_invitations.pickle(out); self.itip_max_size.pickle(out); self.max_recipients.pickle(out); self.email_template.pickle(out); self.http_rsvp_template.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.enable = Pickle::unpickle(stream)?; this.http_rsvp_enable = Pickle::unpickle(stream)?; this.http_rsvp_link_expiry = Pickle::unpickle(stream)?; this.http_rsvp_url = Pickle::unpickle(stream)?; this.auto_add_invitations = Pickle::unpickle(stream)?; this.itip_max_size = Pickle::unpickle(stream)?; this.max_recipients = Pickle::unpickle(stream)?; this.email_template = Pickle::unpickle(stream)?; this.http_rsvp_template = Pickle::unpickle(stream)?; Some(this) } } impl Default for CalendarScheduling { fn default() -> Self { Self { enable: true, http_rsvp_enable: true, http_rsvp_link_expiry: Duration::from_millis(7776000000), http_rsvp_url: Default::default(), auto_add_invitations: false, itip_max_size: 524288, max_recipients: 100u64, email_template: Default::default(), http_rsvp_template: Default::default(), } } } impl IntoValue for CalendarScheduling { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::HttpRsvpEnable, self.http_rsvp_enable.into_value()); map.insert_unchecked( Property::HttpRsvpLinkExpiry, self.http_rsvp_link_expiry.into_value(), ); map.insert_unchecked(Property::HttpRsvpUrl, self.http_rsvp_url.into_value()); map.insert_unchecked( Property::AutoAddInvitations, self.auto_add_invitations.into_value(), ); map.insert_unchecked(Property::ItipMaxSize, self.itip_max_size.into_value()); map.insert_unchecked(Property::MaxRecipients, self.max_recipients.into_value()); map.insert_unchecked(Property::EmailTemplate, self.email_template.into_value()); map.insert_unchecked( Property::HttpRsvpTemplate, self.http_rsvp_template.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for CalendarScheduling { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::HttpRsvpEnable) => self.http_rsvp_enable.patch(pointer, value), Some(Property::HttpRsvpLinkExpiry) => self.http_rsvp_link_expiry.patch(pointer, value), Some(Property::HttpRsvpUrl) => self .http_rsvp_url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AutoAddInvitations) => self.auto_add_invitations.patch(pointer, value), Some(Property::ItipMaxSize) => self.itip_max_size.patch(pointer, value), Some(Property::MaxRecipients) => self.max_recipients.patch(pointer, value), Some(Property::EmailTemplate) => self.email_template.patch(pointer, value), Some(Property::HttpRsvpTemplate) => self.http_rsvp_template.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Certificate { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Certificate; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.certificate; value.validate(errors); let value = &self.private_key; value.validate(errors); let value = &self.subject_alternative_names; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::SubjectAlternativeNames)); } } let value = &self.not_valid_after; if !value.is_valid() { errors.push(ValidationError::invalid(Property::NotValidAfter, value)); } let value = &self.not_valid_before; if !value.is_valid() { errors.push(ValidationError::invalid(Property::NotValidBefore, value)); } let value = &self.issuer; if value.is_empty() { errors.push(ValidationError::required(Property::Issuer)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { for value in self.subject_alternative_names.iter() { i.text(Property::SubjectAlternativeNames, value); } } } impl Pickle for Certificate { fn pickle(&self, out: &mut Vec) { self.certificate.pickle(out); self.private_key.pickle(out); self.subject_alternative_names.pickle(out); self.not_valid_after.pickle(out); self.not_valid_before.pickle(out); self.issuer.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.certificate = Pickle::unpickle(stream)?; this.private_key = Pickle::unpickle(stream)?; this.subject_alternative_names = Pickle::unpickle(stream)?; this.not_valid_after = Pickle::unpickle(stream)?; this.not_valid_before = Pickle::unpickle(stream)?; this.issuer = Pickle::unpickle(stream)?; Some(this) } } impl Default for Certificate { fn default() -> Self { Self { certificate: Default::default(), private_key: Default::default(), subject_alternative_names: Default::default(), not_valid_after: Default::default(), not_valid_before: Default::default(), issuer: Default::default(), } } } impl IntoValue for Certificate { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::Certificate, self.certificate.into_value()); map.insert_unchecked(Property::PrivateKey, self.private_key.into_value()); map.insert_unchecked( Property::SubjectAlternativeNames, self.subject_alternative_names.into_value(), ); map.insert_unchecked(Property::NotValidAfter, self.not_valid_after.into_value()); map.insert_unchecked(Property::NotValidBefore, self.not_valid_before.into_value()); map.insert_unchecked(Property::Issuer, self.issuer.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Certificate { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Certificate) => self.certificate.patch(pointer, value), Some(Property::PrivateKey) => self.private_key.patch(pointer, value), Some(Property::SubjectAlternativeNames) => pointer.assert_server_set(), Some(Property::NotValidAfter) => pointer.assert_server_set(), Some(Property::NotValidBefore) => pointer.assert_server_set(), Some(Property::Issuer) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl CertificateManagement { fn validate(&self, errors: &mut Vec) -> bool { match self { CertificateManagement::Manual => true, CertificateManagement::Automatic(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { CertificateManagement::Manual => {} CertificateManagement::Automatic(object) => { object.index(i); } } } } impl Default for CertificateManagement { fn default() -> Self { CertificateManagement::Manual } } impl Pickle for CertificateManagement { fn pickle(&self, out: &mut Vec) { match self { CertificateManagement::Manual => { 0u16.pickle(out); } CertificateManagement::Automatic(inner) => { 1u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(CertificateManagement::Manual), 1 => Pickle::unpickle(stream).map(CertificateManagement::Automatic), _ => None, } } } impl IntoValue for CertificateManagement { fn into_value(self) -> JmapValue<'static> { match self { CertificateManagement::Manual => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Manual".into())); JmapValue::Object(obj) } CertificateManagement::Automatic(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Automatic".into())); obj } } } } impl RegistryJsonPatch for CertificateManagement { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { CertificateManagementType::Manual => *self = CertificateManagement::Manual, CertificateManagementType::Automatic => { *self = CertificateManagement::Automatic(Default::default()) } } } match self { CertificateManagement::Manual => pointer.assert_eof(), CertificateManagement::Automatic(inner) => inner.patch(pointer, value), } } } impl CertificateManagement { pub fn object_type(&self) -> CertificateManagementType { match self { CertificateManagement::Manual => CertificateManagementType::Manual, CertificateManagement::Automatic(_) => CertificateManagementType::Automatic, } } } impl CertificateManagementProperties { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.acme_provider_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AcmeProviderId)); } let value = &self.subject_alternative_names; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::SubjectAlternativeNames)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::AcmeProvider, self.acme_provider_id.into(), None); } } impl Pickle for CertificateManagementProperties { fn pickle(&self, out: &mut Vec) { self.acme_provider_id.pickle(out); self.subject_alternative_names.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.acme_provider_id = Pickle::unpickle(stream)?; this.subject_alternative_names = Pickle::unpickle(stream)?; Some(this) } } impl Default for CertificateManagementProperties { fn default() -> Self { Self { acme_provider_id: Default::default(), subject_alternative_names: Default::default(), } } } impl IntoValue for CertificateManagementProperties { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::AcmeProviderId, self.acme_provider_id.into_value()); map.insert_unchecked( Property::SubjectAlternativeNames, self.subject_alternative_names.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for CertificateManagementProperties { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AcmeProviderId) => self.acme_provider_id.patch(pointer, value), Some(Property::SubjectAlternativeNames) => self .subject_alternative_names .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ClusterListenerGroup { fn validate(&self, errors: &mut Vec) -> bool { match self { ClusterListenerGroup::EnableAll => true, ClusterListenerGroup::DisableAll => true, ClusterListenerGroup::EnableSome(inner) => inner.validate(errors), ClusterListenerGroup::DisableSome(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { ClusterListenerGroup::EnableAll => {} ClusterListenerGroup::DisableAll => {} ClusterListenerGroup::EnableSome(object) => { object.index(i); } ClusterListenerGroup::DisableSome(object) => { object.index(i); } } } } impl Default for ClusterListenerGroup { fn default() -> Self { ClusterListenerGroup::EnableAll } } impl Pickle for ClusterListenerGroup { fn pickle(&self, out: &mut Vec) { match self { ClusterListenerGroup::EnableAll => { 0u16.pickle(out); } ClusterListenerGroup::DisableAll => { 1u16.pickle(out); } ClusterListenerGroup::EnableSome(inner) => { 2u16.pickle(out); inner.pickle(out); } ClusterListenerGroup::DisableSome(inner) => { 3u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(ClusterListenerGroup::EnableAll), 1 => Some(ClusterListenerGroup::DisableAll), 2 => Pickle::unpickle(stream).map(ClusterListenerGroup::EnableSome), 3 => Pickle::unpickle(stream).map(ClusterListenerGroup::DisableSome), _ => None, } } } impl IntoValue for ClusterListenerGroup { fn into_value(self) -> JmapValue<'static> { match self { ClusterListenerGroup::EnableAll => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("EnableAll".into())); JmapValue::Object(obj) } ClusterListenerGroup::DisableAll => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("DisableAll".into())); JmapValue::Object(obj) } ClusterListenerGroup::EnableSome(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("EnableSome".into())); obj } ClusterListenerGroup::DisableSome(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("DisableSome".into())); obj } } } } impl RegistryJsonPatch for ClusterListenerGroup { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { ClusterListenerGroupType::EnableAll => *self = ClusterListenerGroup::EnableAll, ClusterListenerGroupType::DisableAll => *self = ClusterListenerGroup::DisableAll, ClusterListenerGroupType::EnableSome => { *self = ClusterListenerGroup::EnableSome(Default::default()) } ClusterListenerGroupType::DisableSome => { *self = ClusterListenerGroup::DisableSome(Default::default()) } } } match self { ClusterListenerGroup::EnableAll => pointer.assert_eof(), ClusterListenerGroup::DisableAll => pointer.assert_eof(), ClusterListenerGroup::EnableSome(inner) => inner.patch(pointer, value), ClusterListenerGroup::DisableSome(inner) => inner.patch(pointer, value), } } } impl ClusterListenerGroup { pub fn object_type(&self) -> ClusterListenerGroupType { match self { ClusterListenerGroup::EnableAll => ClusterListenerGroupType::EnableAll, ClusterListenerGroup::DisableAll => ClusterListenerGroupType::DisableAll, ClusterListenerGroup::EnableSome(_) => ClusterListenerGroupType::EnableSome, ClusterListenerGroup::DisableSome(_) => ClusterListenerGroupType::DisableSome, } } } impl ClusterListenerGroupProperties { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.listener_ids; for value in value.iter() { if !value.is_valid() { errors.push(ValidationError::required(Property::ListenerIds)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { for id in self.listener_ids.iter() { i.foreign_key(ObjectType::NetworkListener, Some(*id), None); } } } impl Pickle for ClusterListenerGroupProperties { fn pickle(&self, out: &mut Vec) { self.listener_ids.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.listener_ids = Pickle::unpickle(stream)?; Some(this) } } impl Default for ClusterListenerGroupProperties { fn default() -> Self { Self { listener_ids: Default::default(), } } } impl IntoValue for ClusterListenerGroupProperties { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::ListenerIds, self.listener_ids.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ClusterListenerGroupProperties { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ListenerIds) => self.listener_ids.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for ClusterNode { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::ClusterNode; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.hostname; if value.is_empty() { errors.push(ValidationError::required(Property::Hostname)); } let value = &self.last_renewal; if !value.is_valid() { errors.push(ValidationError::invalid(Property::LastRenewal, value)); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for ClusterNode { fn pickle(&self, out: &mut Vec) { self.node_id.pickle(out); self.hostname.pickle(out); self.last_renewal.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.node_id = Pickle::unpickle(stream)?; this.hostname = Pickle::unpickle(stream)?; this.last_renewal = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for ClusterNode { fn default() -> Self { Self { node_id: 1u64, hostname: Default::default(), last_renewal: Default::default(), status: Default::default(), } } } impl IntoValue for ClusterNode { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::NodeId, self.node_id.into_value()); map.insert_unchecked(Property::Hostname, self.hostname.into_value()); map.insert_unchecked(Property::LastRenewal, self.last_renewal.into_value()); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ClusterNode { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::NodeId) => self.node_id.patch(pointer, value), Some(Property::Hostname) => self.hostname.patch(pointer, value), Some(Property::LastRenewal) => self.last_renewal.patch(pointer, value), Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for ClusterRole { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::ClusterRole; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.tasks; value.validate(errors); let value = &self.listeners; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); self.listeners.index(i); } } impl Pickle for ClusterRole { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.description.pickle(out); self.tasks.pickle(out); self.listeners.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.tasks = Pickle::unpickle(stream)?; this.listeners = Pickle::unpickle(stream)?; Some(this) } } impl Default for ClusterRole { fn default() -> Self { Self { name: Default::default(), description: Default::default(), tasks: Default::default(), listeners: Default::default(), } } } impl IntoValue for ClusterRole { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Tasks, self.tasks.into_value()); map.insert_unchecked(Property::Listeners, self.listeners.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ClusterRole { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self.name.patch(pointer.assert_read_only()?, value), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Tasks) => self.tasks.patch(pointer, value), Some(Property::Listeners) => self.listeners.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ClusterTaskGroup { fn validate(&self, errors: &mut Vec) -> bool { match self { ClusterTaskGroup::EnableAll => true, ClusterTaskGroup::DisableAll => true, ClusterTaskGroup::EnableSome(inner) => inner.validate(errors), ClusterTaskGroup::DisableSome(inner) => inner.validate(errors), } } } impl Default for ClusterTaskGroup { fn default() -> Self { ClusterTaskGroup::EnableAll } } impl Pickle for ClusterTaskGroup { fn pickle(&self, out: &mut Vec) { match self { ClusterTaskGroup::EnableAll => { 0u16.pickle(out); } ClusterTaskGroup::DisableAll => { 1u16.pickle(out); } ClusterTaskGroup::EnableSome(inner) => { 2u16.pickle(out); inner.pickle(out); } ClusterTaskGroup::DisableSome(inner) => { 3u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(ClusterTaskGroup::EnableAll), 1 => Some(ClusterTaskGroup::DisableAll), 2 => Pickle::unpickle(stream).map(ClusterTaskGroup::EnableSome), 3 => Pickle::unpickle(stream).map(ClusterTaskGroup::DisableSome), _ => None, } } } impl IntoValue for ClusterTaskGroup { fn into_value(self) -> JmapValue<'static> { match self { ClusterTaskGroup::EnableAll => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("EnableAll".into())); JmapValue::Object(obj) } ClusterTaskGroup::DisableAll => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("DisableAll".into())); JmapValue::Object(obj) } ClusterTaskGroup::EnableSome(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("EnableSome".into())); obj } ClusterTaskGroup::DisableSome(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("DisableSome".into())); obj } } } } impl RegistryJsonPatch for ClusterTaskGroup { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { ClusterTaskGroupType::EnableAll => *self = ClusterTaskGroup::EnableAll, ClusterTaskGroupType::DisableAll => *self = ClusterTaskGroup::DisableAll, ClusterTaskGroupType::EnableSome => { *self = ClusterTaskGroup::EnableSome(Default::default()) } ClusterTaskGroupType::DisableSome => { *self = ClusterTaskGroup::DisableSome(Default::default()) } } } match self { ClusterTaskGroup::EnableAll => pointer.assert_eof(), ClusterTaskGroup::DisableAll => pointer.assert_eof(), ClusterTaskGroup::EnableSome(inner) => inner.patch(pointer, value), ClusterTaskGroup::DisableSome(inner) => inner.patch(pointer, value), } } } impl ClusterTaskGroup { pub fn object_type(&self) -> ClusterTaskGroupType { match self { ClusterTaskGroup::EnableAll => ClusterTaskGroupType::EnableAll, ClusterTaskGroup::DisableAll => ClusterTaskGroupType::DisableAll, ClusterTaskGroup::EnableSome(_) => ClusterTaskGroupType::EnableSome, ClusterTaskGroup::DisableSome(_) => ClusterTaskGroupType::DisableSome, } } } impl ClusterTaskGroupProperties { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for ClusterTaskGroupProperties { fn pickle(&self, out: &mut Vec) { self.task_types.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.task_types = Pickle::unpickle(stream)?; Some(this) } } impl Default for ClusterTaskGroupProperties { fn default() -> Self { Self { task_types: Default::default(), } } } impl IntoValue for ClusterTaskGroupProperties { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::TaskTypes, self.task_types.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ClusterTaskGroupProperties { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::TaskTypes) => self.task_types.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Coordinator { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Coordinator; fn validate(&self, errors: &mut Vec) -> bool { match self { Coordinator::Disabled => true, Coordinator::Default => true, Coordinator::Kafka(inner) => inner.validate(errors), Coordinator::Nats(inner) => inner.validate(errors), Coordinator::Zenoh(inner) => inner.validate(errors), Coordinator::Redis(inner) => inner.validate(errors), Coordinator::RedisCluster(inner) => inner.validate(errors), Coordinator::RedisSentinel(inner) => inner.validate(errors), } } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Default for Coordinator { fn default() -> Self { Coordinator::Disabled } } impl Pickle for Coordinator { fn pickle(&self, out: &mut Vec) { match self { Coordinator::Disabled => { 0u16.pickle(out); } Coordinator::Default => { 1u16.pickle(out); } Coordinator::Kafka(inner) => { 2u16.pickle(out); inner.pickle(out); } Coordinator::Nats(inner) => { 3u16.pickle(out); inner.pickle(out); } Coordinator::Zenoh(inner) => { 4u16.pickle(out); inner.pickle(out); } Coordinator::Redis(inner) => { 5u16.pickle(out); inner.pickle(out); } Coordinator::RedisCluster(inner) => { 6u16.pickle(out); inner.pickle(out); } Coordinator::RedisSentinel(inner) => { 7u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(Coordinator::Disabled), 1 => Some(Coordinator::Default), 2 => Pickle::unpickle(stream).map(Coordinator::Kafka), 3 => Pickle::unpickle(stream).map(Coordinator::Nats), 4 => Pickle::unpickle(stream).map(Coordinator::Zenoh), 5 => Pickle::unpickle(stream).map(Coordinator::Redis), 6 => Pickle::unpickle(stream).map(Coordinator::RedisCluster), 7 => Pickle::unpickle(stream).map(Coordinator::RedisSentinel), _ => None, } } } impl IntoValue for Coordinator { fn into_value(self) -> JmapValue<'static> { match self { Coordinator::Disabled => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Disabled".into())); JmapValue::Object(obj) } Coordinator::Default => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Default".into())); JmapValue::Object(obj) } Coordinator::Kafka(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Kafka".into())); obj } Coordinator::Nats(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Nats".into())); obj } Coordinator::Zenoh(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Zenoh".into())); obj } Coordinator::Redis(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Redis".into())); obj } Coordinator::RedisCluster(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("RedisCluster".into())); obj } Coordinator::RedisSentinel(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("RedisSentinel".into())); obj } } } } impl RegistryJsonPatch for Coordinator { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { CoordinatorType::Disabled => *self = Coordinator::Disabled, CoordinatorType::Default => *self = Coordinator::Default, CoordinatorType::Kafka => *self = Coordinator::Kafka(Default::default()), CoordinatorType::Nats => *self = Coordinator::Nats(Default::default()), CoordinatorType::Zenoh => *self = Coordinator::Zenoh(Default::default()), CoordinatorType::Redis => *self = Coordinator::Redis(Default::default()), CoordinatorType::RedisCluster => { *self = Coordinator::RedisCluster(Default::default()) } CoordinatorType::RedisSentinel => { *self = Coordinator::RedisSentinel(Default::default()) } } } match self { Coordinator::Disabled => pointer.assert_eof(), Coordinator::Default => pointer.assert_eof(), Coordinator::Kafka(inner) => inner.patch(pointer, value), Coordinator::Nats(inner) => inner.patch(pointer, value), Coordinator::Zenoh(inner) => inner.patch(pointer, value), Coordinator::Redis(inner) => inner.patch(pointer, value), Coordinator::RedisCluster(inner) => inner.patch(pointer, value), Coordinator::RedisSentinel(inner) => inner.patch(pointer, value), } } } impl Coordinator { pub fn object_type(&self) -> CoordinatorType { match self { Coordinator::Disabled => CoordinatorType::Disabled, Coordinator::Default => CoordinatorType::Default, Coordinator::Kafka(_) => CoordinatorType::Kafka, Coordinator::Nats(_) => CoordinatorType::Nats, Coordinator::Zenoh(_) => CoordinatorType::Zenoh, Coordinator::Redis(_) => CoordinatorType::Redis, Coordinator::RedisCluster(_) => CoordinatorType::RedisCluster, Coordinator::RedisSentinel(_) => CoordinatorType::RedisSentinel, } } } impl Credential { fn validate(&self, errors: &mut Vec) -> bool { match self { Credential::Password(inner) => inner.validate(errors), Credential::AppPassword(inner) => inner.validate(errors), Credential::ApiKey(inner) => inner.validate(errors), } } } impl Default for Credential { fn default() -> Self { Credential::Password(Default::default()) } } impl Pickle for Credential { fn pickle(&self, out: &mut Vec) { match self { Credential::Password(inner) => { 0u16.pickle(out); inner.pickle(out); } Credential::AppPassword(inner) => { 1u16.pickle(out); inner.pickle(out); } Credential::ApiKey(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(Credential::Password), 1 => Pickle::unpickle(stream).map(Credential::AppPassword), 2 => Pickle::unpickle(stream).map(Credential::ApiKey), _ => None, } } } impl IntoValue for Credential { fn into_value(self) -> JmapValue<'static> { match self { Credential::Password(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Password".into())); obj } Credential::AppPassword(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("AppPassword".into())); obj } Credential::ApiKey(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("ApiKey".into())); obj } } } } impl RegistryJsonPatch for Credential { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { CredentialType::Password => *self = Credential::Password(Default::default()), CredentialType::AppPassword => *self = Credential::AppPassword(Default::default()), CredentialType::ApiKey => *self = Credential::ApiKey(Default::default()), } } match self { Credential::Password(inner) => inner.patch(pointer, value), Credential::AppPassword(inner) => inner.patch(pointer, value), Credential::ApiKey(inner) => inner.patch(pointer, value), } } } impl Credential { pub fn object_type(&self) -> CredentialType { match self { Credential::Password(_) => CredentialType::Password, Credential::AppPassword(_) => CredentialType::AppPassword, Credential::ApiKey(_) => CredentialType::ApiKey, } } } impl CredentialPermissions { fn validate(&self, errors: &mut Vec) -> bool { match self { CredentialPermissions::Inherit => true, CredentialPermissions::Disable(inner) => inner.validate(errors), CredentialPermissions::Replace(inner) => inner.validate(errors), } } } impl Default for CredentialPermissions { fn default() -> Self { CredentialPermissions::Inherit } } impl Pickle for CredentialPermissions { fn pickle(&self, out: &mut Vec) { match self { CredentialPermissions::Inherit => { 0u16.pickle(out); } CredentialPermissions::Disable(inner) => { 1u16.pickle(out); inner.pickle(out); } CredentialPermissions::Replace(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(CredentialPermissions::Inherit), 1 => Pickle::unpickle(stream).map(CredentialPermissions::Disable), 2 => Pickle::unpickle(stream).map(CredentialPermissions::Replace), _ => None, } } } impl IntoValue for CredentialPermissions { fn into_value(self) -> JmapValue<'static> { match self { CredentialPermissions::Inherit => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Inherit".into())); JmapValue::Object(obj) } CredentialPermissions::Disable(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Disable".into())); obj } CredentialPermissions::Replace(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Replace".into())); obj } } } } impl RegistryJsonPatch for CredentialPermissions { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { CredentialPermissionsType::Inherit => *self = CredentialPermissions::Inherit, CredentialPermissionsType::Disable => { *self = CredentialPermissions::Disable(Default::default()) } CredentialPermissionsType::Replace => { *self = CredentialPermissions::Replace(Default::default()) } } } match self { CredentialPermissions::Inherit => pointer.assert_eof(), CredentialPermissions::Disable(inner) => inner.patch(pointer, value), CredentialPermissions::Replace(inner) => inner.patch(pointer, value), } } } impl CredentialPermissions { pub fn object_type(&self) -> CredentialPermissionsType { match self { CredentialPermissions::Inherit => CredentialPermissionsType::Inherit, CredentialPermissions::Disable(_) => CredentialPermissionsType::Disable, CredentialPermissions::Replace(_) => CredentialPermissionsType::Replace, } } } impl CredentialPermissionsList { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for CredentialPermissionsList { fn pickle(&self, out: &mut Vec) { self.permissions.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.permissions = Pickle::unpickle(stream)?; Some(this) } } impl Default for CredentialPermissionsList { fn default() -> Self { Self { permissions: Default::default(), } } } impl IntoValue for CredentialPermissionsList { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Permissions, self.permissions.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for CredentialPermissionsList { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Permissions) => self.permissions.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl Cron { fn validate(&self, errors: &mut Vec) -> bool { match self { Cron::Daily(inner) => inner.validate(errors), Cron::Weekly(inner) => inner.validate(errors), Cron::Hourly(inner) => inner.validate(errors), } } } impl Default for Cron { fn default() -> Self { Cron::Daily(Default::default()) } } impl Pickle for Cron { fn pickle(&self, out: &mut Vec) { match self { Cron::Daily(inner) => { 0u16.pickle(out); inner.pickle(out); } Cron::Weekly(inner) => { 1u16.pickle(out); inner.pickle(out); } Cron::Hourly(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(Cron::Daily), 1 => Pickle::unpickle(stream).map(Cron::Weekly), 2 => Pickle::unpickle(stream).map(Cron::Hourly), _ => None, } } } impl IntoValue for Cron { fn into_value(self) -> JmapValue<'static> { match self { Cron::Daily(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Daily".into())); obj } Cron::Weekly(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Weekly".into())); obj } Cron::Hourly(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Hourly".into())); obj } } } } impl RegistryJsonPatch for Cron { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { CronType::Daily => *self = Cron::Daily(Default::default()), CronType::Weekly => *self = Cron::Weekly(Default::default()), CronType::Hourly => *self = Cron::Hourly(Default::default()), } } match self { Cron::Daily(inner) => inner.patch(pointer, value), Cron::Weekly(inner) => inner.patch(pointer, value), Cron::Hourly(inner) => inner.patch(pointer, value), } } } impl Cron { pub fn object_type(&self) -> CronType { match self { Cron::Daily(_) => CronType::Daily, Cron::Weekly(_) => CronType::Weekly, Cron::Hourly(_) => CronType::Hourly, } } } impl CronDaily { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.hour; if *value > 23 { errors.push(ValidationError::max_value(Property::Hour, 23)); } let value = &self.minute; if *value > 59 { errors.push(ValidationError::max_value(Property::Minute, 59)); } errors.len() == neb } } impl Pickle for CronDaily { fn pickle(&self, out: &mut Vec) { self.hour.pickle(out); self.minute.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.hour = Pickle::unpickle(stream)?; this.minute = Pickle::unpickle(stream)?; Some(this) } } impl Default for CronDaily { fn default() -> Self { Self { hour: 0u64, minute: 0u64, } } } impl IntoValue for CronDaily { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Hour, self.hour.into_value()); map.insert_unchecked(Property::Minute, self.minute.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for CronDaily { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Hour) => self.hour.patch(pointer, value), Some(Property::Minute) => self.minute.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl CronHourly { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.minute; if *value > 59 { errors.push(ValidationError::max_value(Property::Minute, 59)); } errors.len() == neb } } impl Pickle for CronHourly { fn pickle(&self, out: &mut Vec) { self.minute.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.minute = Pickle::unpickle(stream)?; Some(this) } } impl Default for CronHourly { fn default() -> Self { Self { minute: 0u64 } } } impl IntoValue for CronHourly { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Minute, self.minute.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for CronHourly { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Minute) => self.minute.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl CronWeekly { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.day; if *value > 6 { errors.push(ValidationError::max_value(Property::Day, 6)); } let value = &self.hour; if *value > 23 { errors.push(ValidationError::max_value(Property::Hour, 23)); } let value = &self.minute; if *value > 59 { errors.push(ValidationError::max_value(Property::Minute, 59)); } errors.len() == neb } } impl Pickle for CronWeekly { fn pickle(&self, out: &mut Vec) { self.day.pickle(out); self.hour.pickle(out); self.minute.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.day = Pickle::unpickle(stream)?; this.hour = Pickle::unpickle(stream)?; this.minute = Pickle::unpickle(stream)?; Some(this) } } impl Default for CronWeekly { fn default() -> Self { Self { day: 0u64, hour: 0u64, minute: 0u64, } } } impl IntoValue for CronWeekly { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::Day, self.day.into_value()); map.insert_unchecked(Property::Hour, self.hour.into_value()); map.insert_unchecked(Property::Minute, self.minute.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for CronWeekly { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Day) => self.day.patch(pointer, value), Some(Property::Hour) => self.hour.patch(pointer, value), Some(Property::Minute) => self.minute.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl CustomRoles { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.role_ids; for value in value.iter() { if !value.is_valid() { errors.push(ValidationError::required(Property::RoleIds)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { for id in self.role_ids.iter() { i.foreign_key(ObjectType::Role, Some(*id), None); } } } impl Pickle for CustomRoles { fn pickle(&self, out: &mut Vec) { self.role_ids.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.role_ids = Pickle::unpickle(stream)?; Some(this) } } impl Default for CustomRoles { fn default() -> Self { Self { role_ids: Default::default(), } } } impl IntoValue for CustomRoles { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::RoleIds, self.role_ids.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for CustomRoles { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::RoleIds) => self.role_ids.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for DataRetention { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::DataRetention; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.expunge_schedule; value.validate(errors); let value = &self.data_cleanup_schedule; value.validate(errors); let value = &self.blob_cleanup_schedule; value.validate(errors); let value = &self.metrics_collection_interval; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for DataRetention { fn pickle(&self, out: &mut Vec) { self.expunge_trash_after.pickle(out); self.expunge_submissions_after.pickle(out); self.expunge_share_notify_after.pickle(out); self.expunge_scheduling_inbox_after.pickle(out); self.expunge_schedule.pickle(out); self.data_cleanup_schedule.pickle(out); self.blob_cleanup_schedule.pickle(out); self.max_changes_history.pickle(out); self.archive_deleted_items_for.pickle(out); self.archive_deleted_accounts_for.pickle(out); self.hold_mta_reports_for.pickle(out); self.hold_traces_for.pickle(out); self.hold_metrics_for.pickle(out); self.metrics_collection_interval.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.expunge_trash_after = Pickle::unpickle(stream)?; this.expunge_submissions_after = Pickle::unpickle(stream)?; this.expunge_share_notify_after = Pickle::unpickle(stream)?; this.expunge_scheduling_inbox_after = Pickle::unpickle(stream)?; this.expunge_schedule = Pickle::unpickle(stream)?; this.data_cleanup_schedule = Pickle::unpickle(stream)?; this.blob_cleanup_schedule = Pickle::unpickle(stream)?; this.max_changes_history = Pickle::unpickle(stream)?; this.archive_deleted_items_for = Pickle::unpickle(stream)?; this.archive_deleted_accounts_for = Pickle::unpickle(stream)?; this.hold_mta_reports_for = Pickle::unpickle(stream)?; this.hold_traces_for = Pickle::unpickle(stream)?; this.hold_metrics_for = Pickle::unpickle(stream)?; this.metrics_collection_interval = Pickle::unpickle(stream)?; Some(this) } } impl Default for DataRetention { fn default() -> Self { Self { expunge_trash_after: Some(Duration::from_millis(2592000000)), expunge_submissions_after: Some(Duration::from_millis(259200000)), expunge_share_notify_after: Some(Duration::from_millis(2592000000)), expunge_scheduling_inbox_after: Some(Duration::from_millis(2592000000)), expunge_schedule: Cron::Daily(CronDaily { hour: 0u64, minute: 0u64, }), data_cleanup_schedule: Cron::Daily(CronDaily { hour: 2u64, minute: 0u64, }), blob_cleanup_schedule: Cron::Daily(CronDaily { hour: 4u64, minute: 0u64, }), max_changes_history: Some(10000u64), archive_deleted_items_for: Default::default(), archive_deleted_accounts_for: Default::default(), hold_mta_reports_for: Some(Duration::from_millis(2592000000)), hold_traces_for: Some(Duration::from_millis(2592000000)), hold_metrics_for: Some(Duration::from_millis(7776000000)), metrics_collection_interval: Cron::Hourly(CronHourly { minute: 0u64 }), } } } impl IntoValue for DataRetention { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(16); map.insert_unchecked( Property::ExpungeTrashAfter, self.expunge_trash_after.into_value(), ); map.insert_unchecked( Property::ExpungeSubmissionsAfter, self.expunge_submissions_after.into_value(), ); map.insert_unchecked( Property::ExpungeShareNotifyAfter, self.expunge_share_notify_after.into_value(), ); map.insert_unchecked( Property::ExpungeSchedulingInboxAfter, self.expunge_scheduling_inbox_after.into_value(), ); map.insert_unchecked( Property::ExpungeSchedule, self.expunge_schedule.into_value(), ); map.insert_unchecked( Property::DataCleanupSchedule, self.data_cleanup_schedule.into_value(), ); map.insert_unchecked( Property::BlobCleanupSchedule, self.blob_cleanup_schedule.into_value(), ); map.insert_unchecked( Property::MaxChangesHistory, self.max_changes_history.into_value(), ); map.insert_unchecked( Property::ArchiveDeletedItemsFor, self.archive_deleted_items_for.into_value(), ); map.insert_unchecked( Property::ArchiveDeletedAccountsFor, self.archive_deleted_accounts_for.into_value(), ); map.insert_unchecked( Property::HoldMtaReportsFor, self.hold_mta_reports_for.into_value(), ); map.insert_unchecked(Property::HoldTracesFor, self.hold_traces_for.into_value()); map.insert_unchecked(Property::HoldMetricsFor, self.hold_metrics_for.into_value()); map.insert_unchecked( Property::MetricsCollectionInterval, self.metrics_collection_interval.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DataRetention { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ExpungeTrashAfter) => self.expunge_trash_after.patch(pointer, value), Some(Property::ExpungeSubmissionsAfter) => { self.expunge_submissions_after.patch(pointer, value) } Some(Property::ExpungeShareNotifyAfter) => { self.expunge_share_notify_after.patch(pointer, value) } Some(Property::ExpungeSchedulingInboxAfter) => { self.expunge_scheduling_inbox_after.patch(pointer, value) } Some(Property::ExpungeSchedule) => self.expunge_schedule.patch(pointer, value), Some(Property::DataCleanupSchedule) => self.data_cleanup_schedule.patch(pointer, value), Some(Property::BlobCleanupSchedule) => self.blob_cleanup_schedule.patch(pointer, value), Some(Property::MaxChangesHistory) => self.max_changes_history.patch(pointer, value), Some(Property::ArchiveDeletedItemsFor) => { self.archive_deleted_items_for.patch(pointer, value) } Some(Property::ArchiveDeletedAccountsFor) => { self.archive_deleted_accounts_for.patch(pointer, value) } Some(Property::HoldMtaReportsFor) => self.hold_mta_reports_for.patch(pointer, value), Some(Property::HoldTracesFor) => self.hold_traces_for.patch(pointer, value), Some(Property::HoldMetricsFor) => self.hold_metrics_for.patch(pointer, value), Some(Property::MetricsCollectionInterval) => { self.metrics_collection_interval.patch(pointer, value) } Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for DataStore { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 1; const OBJECT: ObjectType = ObjectType::DataStore; fn validate(&self, errors: &mut Vec) -> bool { match self { DataStore::RocksDb(inner) => inner.validate(errors), DataStore::Sqlite(inner) => inner.validate(errors), DataStore::FoundationDb(inner) => inner.validate(errors), DataStore::PostgreSql(inner) => inner.validate(errors), DataStore::MySql(inner) => inner.validate(errors), } } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Default for DataStore { fn default() -> Self { DataStore::RocksDb(Default::default()) } } impl Pickle for DataStore { fn pickle(&self, out: &mut Vec) { match self { DataStore::RocksDb(inner) => { 0u16.pickle(out); inner.pickle(out); } DataStore::Sqlite(inner) => { 1u16.pickle(out); inner.pickle(out); } DataStore::FoundationDb(inner) => { 2u16.pickle(out); inner.pickle(out); } DataStore::PostgreSql(inner) => { 3u16.pickle(out); inner.pickle(out); } DataStore::MySql(inner) => { 4u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(DataStore::RocksDb), 1 => Pickle::unpickle(stream).map(DataStore::Sqlite), 2 => Pickle::unpickle(stream).map(DataStore::FoundationDb), 3 => Pickle::unpickle(stream).map(DataStore::PostgreSql), 4 => Pickle::unpickle(stream).map(DataStore::MySql), _ => None, } } } impl IntoValue for DataStore { fn into_value(self) -> JmapValue<'static> { match self { DataStore::RocksDb(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("RocksDb".into())); obj } DataStore::Sqlite(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Sqlite".into())); obj } DataStore::FoundationDb(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("FoundationDb".into())); obj } DataStore::PostgreSql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("PostgreSql".into())); obj } DataStore::MySql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("MySql".into())); obj } } } } impl RegistryJsonPatch for DataStore { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { DataStoreType::RocksDb => *self = DataStore::RocksDb(Default::default()), DataStoreType::Sqlite => *self = DataStore::Sqlite(Default::default()), DataStoreType::FoundationDb => *self = DataStore::FoundationDb(Default::default()), DataStoreType::PostgreSql => *self = DataStore::PostgreSql(Default::default()), DataStoreType::MySql => *self = DataStore::MySql(Default::default()), } } match self { DataStore::RocksDb(inner) => inner.patch(pointer, value), DataStore::Sqlite(inner) => inner.patch(pointer, value), DataStore::FoundationDb(inner) => inner.patch(pointer, value), DataStore::PostgreSql(inner) => inner.patch(pointer, value), DataStore::MySql(inner) => inner.patch(pointer, value), } } } impl DataStore { pub fn object_type(&self) -> DataStoreType { match self { DataStore::RocksDb(_) => DataStoreType::RocksDb, DataStore::Sqlite(_) => DataStoreType::Sqlite, DataStore::FoundationDb(_) => DataStoreType::FoundationDb, DataStore::PostgreSql(_) => DataStoreType::PostgreSql, DataStore::MySql(_) => DataStoreType::MySql, } } } impl DeliveryError { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.error_message { if value.is_empty() { errors.push(ValidationError::required(Property::ErrorMessage)); } } if let Some(value) = &self.error_command { if value.is_empty() { errors.push(ValidationError::required(Property::ErrorCommand)); } } if let Some(value) = &self.response_hostname { if value.is_empty() { errors.push(ValidationError::required(Property::ResponseHostname)); } } if let Some(value) = &self.response_code { if *value < 100 { errors.push(ValidationError::min_value(Property::ResponseCode, 100)); } if *value > 599 { errors.push(ValidationError::max_value(Property::ResponseCode, 599)); } } if let Some(value) = &self.response_enhanced { if value.is_empty() { errors.push(ValidationError::required(Property::ResponseEnhanced)); } } if let Some(value) = &self.response_message { if value.is_empty() { errors.push(ValidationError::required(Property::ResponseMessage)); } } errors.len() == neb } } impl Pickle for DeliveryError { fn pickle(&self, out: &mut Vec) { self.error_type.pickle(out); self.error_message.pickle(out); self.error_command.pickle(out); self.response_hostname.pickle(out); self.response_code.pickle(out); self.response_enhanced.pickle(out); self.response_message.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.error_type = Pickle::unpickle(stream)?; this.error_message = Pickle::unpickle(stream)?; this.error_command = Pickle::unpickle(stream)?; this.response_hostname = Pickle::unpickle(stream)?; this.response_code = Pickle::unpickle(stream)?; this.response_enhanced = Pickle::unpickle(stream)?; this.response_message = Pickle::unpickle(stream)?; Some(this) } } impl Default for DeliveryError { fn default() -> Self { Self { error_type: Default::default(), error_message: Default::default(), error_command: Default::default(), response_hostname: Default::default(), response_code: Default::default(), response_enhanced: Default::default(), response_message: Default::default(), } } } impl IntoValue for DeliveryError { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked(Property::ErrorType, self.error_type.into_value()); map.insert_unchecked(Property::ErrorMessage, self.error_message.into_value()); map.insert_unchecked(Property::ErrorCommand, self.error_command.into_value()); map.insert_unchecked( Property::ResponseHostname, self.response_hostname.into_value(), ); map.insert_unchecked(Property::ResponseCode, self.response_code.into_value()); map.insert_unchecked( Property::ResponseEnhanced, self.response_enhanced.into_value(), ); map.insert_unchecked( Property::ResponseMessage, self.response_message.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DeliveryError { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ErrorType) => self.error_type.patch(pointer, value), Some(Property::ErrorMessage) => self.error_message.patch(pointer, value), Some(Property::ErrorCommand) => self.error_command.patch(pointer, value), Some(Property::ResponseHostname) => self.response_hostname.patch(pointer, value), Some(Property::ResponseCode) => self.response_code.patch(pointer, value), Some(Property::ResponseEnhanced) => self.response_enhanced.patch(pointer, value), Some(Property::ResponseMessage) => self.response_message.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Directory { const FLAGS: u64 = OBJ_FILTER_TENANT; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Directory; fn validate(&self, errors: &mut Vec) -> bool { match self { Directory::Ldap(inner) => inner.validate(errors), Directory::Sql(inner) => inner.validate(errors), Directory::Oidc(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { Directory::Ldap(object) => { object.index(i); } Directory::Sql(object) => { object.index(i); } Directory::Oidc(object) => { object.index(i); } } } } impl Default for Directory { fn default() -> Self { Directory::Ldap(Default::default()) } } impl Pickle for Directory { fn pickle(&self, out: &mut Vec) { match self { Directory::Ldap(inner) => { 0u16.pickle(out); inner.pickle(out); } Directory::Sql(inner) => { 1u16.pickle(out); inner.pickle(out); } Directory::Oidc(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(Directory::Ldap), 1 => Pickle::unpickle(stream).map(Directory::Sql), 2 => Pickle::unpickle(stream).map(Directory::Oidc), _ => None, } } } impl IntoValue for Directory { fn into_value(self) -> JmapValue<'static> { match self { Directory::Ldap(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ldap".into())); obj } Directory::Sql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Sql".into())); obj } Directory::Oidc(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Oidc".into())); obj } } } } impl RegistryJsonPatch for Directory { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { DirectoryType::Ldap => *self = Directory::Ldap(Default::default()), DirectoryType::Sql => *self = Directory::Sql(Default::default()), DirectoryType::Oidc => *self = Directory::Oidc(Default::default()), } } match self { Directory::Ldap(inner) => inner.patch(pointer, value), Directory::Sql(inner) => inner.patch(pointer, value), Directory::Oidc(inner) => inner.patch(pointer, value), } } } impl Directory { pub fn object_type(&self) -> DirectoryType { match self { Directory::Ldap(_) => DirectoryType::Ldap, Directory::Sql(_) => DirectoryType::Sql, Directory::Oidc(_) => DirectoryType::Oidc, } } } impl DirectoryBootstrap { fn validate(&self, errors: &mut Vec) -> bool { match self { DirectoryBootstrap::Internal => true, DirectoryBootstrap::Ldap(inner) => inner.validate(errors), DirectoryBootstrap::Sql(inner) => inner.validate(errors), DirectoryBootstrap::Oidc(inner) => inner.validate(errors), } } } impl Default for DirectoryBootstrap { fn default() -> Self { DirectoryBootstrap::Internal } } impl Pickle for DirectoryBootstrap { fn pickle(&self, out: &mut Vec) { match self { DirectoryBootstrap::Internal => { 0u16.pickle(out); } DirectoryBootstrap::Ldap(inner) => { 1u16.pickle(out); inner.pickle(out); } DirectoryBootstrap::Sql(inner) => { 2u16.pickle(out); inner.pickle(out); } DirectoryBootstrap::Oidc(inner) => { 3u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(DirectoryBootstrap::Internal), 1 => Pickle::unpickle(stream).map(DirectoryBootstrap::Ldap), 2 => Pickle::unpickle(stream).map(DirectoryBootstrap::Sql), 3 => Pickle::unpickle(stream).map(DirectoryBootstrap::Oidc), _ => None, } } } impl IntoValue for DirectoryBootstrap { fn into_value(self) -> JmapValue<'static> { match self { DirectoryBootstrap::Internal => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Internal".into())); JmapValue::Object(obj) } DirectoryBootstrap::Ldap(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ldap".into())); obj } DirectoryBootstrap::Sql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Sql".into())); obj } DirectoryBootstrap::Oidc(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Oidc".into())); obj } } } } impl RegistryJsonPatch for DirectoryBootstrap { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { DirectoryBootstrapType::Internal => *self = DirectoryBootstrap::Internal, DirectoryBootstrapType::Ldap => { *self = DirectoryBootstrap::Ldap(Default::default()) } DirectoryBootstrapType::Sql => *self = DirectoryBootstrap::Sql(Default::default()), DirectoryBootstrapType::Oidc => { *self = DirectoryBootstrap::Oidc(Default::default()) } } } match self { DirectoryBootstrap::Internal => pointer.assert_eof(), DirectoryBootstrap::Ldap(inner) => inner.patch(pointer, value), DirectoryBootstrap::Sql(inner) => inner.patch(pointer, value), DirectoryBootstrap::Oidc(inner) => inner.patch(pointer, value), } } } impl DirectoryBootstrap { pub fn object_type(&self) -> DirectoryBootstrapType { match self { DirectoryBootstrap::Internal => DirectoryBootstrapType::Internal, DirectoryBootstrap::Ldap(_) => DirectoryBootstrapType::Ldap, DirectoryBootstrap::Sql(_) => DirectoryBootstrapType::Sql, DirectoryBootstrap::Oidc(_) => DirectoryBootstrapType::Oidc, } } } impl Dkim1Signature { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.auid { if value.is_empty() { errors.push(ValidationError::required(Property::Auid)); } } let value = &self.headers; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::Headers)); } } let value = &self.private_key; value.validate(errors); if let Some(value) = &self.third_party { if value.is_empty() { errors.push(ValidationError::required(Property::ThirdParty)); } } let value = &self.domain_id; if !value.is_valid() { errors.push(ValidationError::required(Property::DomainId)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } let value = &self.selector; if value.is_empty() { errors.push(ValidationError::required(Property::Selector)); } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } if let Some(value) = &self.next_transition_at { if !value.is_valid() { errors.push(ValidationError::invalid(Property::NextTransitionAt, value)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Domain, self.domain_id.into(), None); i.search(Property::DomainId, &self.domain_id); i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for Dkim1Signature { fn pickle(&self, out: &mut Vec) { self.auid.pickle(out); self.canonicalization.pickle(out); self.expire.pickle(out); self.headers.pickle(out); self.private_key.pickle(out); self.report.pickle(out); self.third_party.pickle(out); self.third_party_hash.pickle(out); self.domain_id.pickle(out); self.member_tenant_id.pickle(out); self.selector.pickle(out); self.created_at.pickle(out); self.next_transition_at.pickle(out); self.stage.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.auid = Pickle::unpickle(stream)?; this.canonicalization = Pickle::unpickle(stream)?; this.expire = Pickle::unpickle(stream)?; this.headers = Pickle::unpickle(stream)?; this.private_key = Pickle::unpickle(stream)?; this.report = Pickle::unpickle(stream)?; this.third_party = Pickle::unpickle(stream)?; this.third_party_hash = Pickle::unpickle(stream)?; this.domain_id = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.selector = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.next_transition_at = Pickle::unpickle(stream)?; this.stage = Pickle::unpickle(stream)?; Some(this) } } impl Default for Dkim1Signature { fn default() -> Self { Self { auid: Default::default(), canonicalization: DkimCanonicalization::RelaxedRelaxed, expire: Default::default(), headers: Map::new(vec![ "From".to_string(), "To".to_string(), "Date".to_string(), "Subject".to_string(), "Message-ID".to_string(), ]), private_key: Default::default(), report: true, third_party: Default::default(), third_party_hash: Default::default(), domain_id: Default::default(), member_tenant_id: Default::default(), selector: Default::default(), created_at: Default::default(), next_transition_at: Default::default(), stage: DkimRotationStage::Active, } } } impl IntoValue for Dkim1Signature { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(16); map.insert_unchecked(Property::Auid, self.auid.into_value()); map.insert_unchecked( Property::Canonicalization, self.canonicalization.into_value(), ); map.insert_unchecked(Property::Expire, self.expire.into_value()); map.insert_unchecked(Property::Headers, self.headers.into_value()); map.insert_unchecked(Property::PrivateKey, self.private_key.into_value()); map.insert_unchecked(Property::Report, self.report.into_value()); map.insert_unchecked(Property::ThirdParty, self.third_party.into_value()); map.insert_unchecked(Property::ThirdPartyHash, self.third_party_hash.into_value()); map.insert_unchecked(Property::DomainId, self.domain_id.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Selector, self.selector.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked( Property::NextTransitionAt, self.next_transition_at.into_value(), ); map.insert_unchecked(Property::Stage, self.stage.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Dkim1Signature { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Auid) => self .auid .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Canonicalization) => self.canonicalization.patch(pointer, value), Some(Property::Expire) => self.expire.patch(pointer, value), Some(Property::Headers) => self .headers .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::PrivateKey) => self.private_key.patch(pointer, value), Some(Property::PublicKey) => pointer.assert_server_set(), Some(Property::Report) => self.report.patch(pointer, value), Some(Property::ThirdParty) => self .third_party .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ThirdPartyHash) => self.third_party_hash.patch(pointer, value), Some(Property::DomainId) => self.domain_id.patch(pointer, value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Selector) => self .selector .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::NextTransitionAt) => self.next_transition_at.patch(pointer, value), Some(Property::Stage) => self.stage.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl Dkim2Signature { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.private_key; value.validate(errors); let value = &self.domain_id; if !value.is_valid() { errors.push(ValidationError::required(Property::DomainId)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } let value = &self.selector; if value.is_empty() { errors.push(ValidationError::required(Property::Selector)); } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } if let Some(value) = &self.next_transition_at { if !value.is_valid() { errors.push(ValidationError::invalid(Property::NextTransitionAt, value)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Domain, self.domain_id.into(), None); i.search(Property::DomainId, &self.domain_id); i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for Dkim2Signature { fn pickle(&self, out: &mut Vec) { self.flags.pickle(out); self.private_key.pickle(out); self.domain_id.pickle(out); self.member_tenant_id.pickle(out); self.selector.pickle(out); self.created_at.pickle(out); self.next_transition_at.pickle(out); self.stage.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.flags = Pickle::unpickle(stream)?; this.private_key = Pickle::unpickle(stream)?; this.domain_id = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.selector = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.next_transition_at = Pickle::unpickle(stream)?; this.stage = Pickle::unpickle(stream)?; Some(this) } } impl Default for Dkim2Signature { fn default() -> Self { Self { flags: Default::default(), private_key: Default::default(), domain_id: Default::default(), member_tenant_id: Default::default(), selector: Default::default(), created_at: Default::default(), next_transition_at: Default::default(), stage: DkimRotationStage::Active, } } } impl IntoValue for Dkim2Signature { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(10); map.insert_unchecked(Property::Flags, self.flags.into_value()); map.insert_unchecked(Property::PrivateKey, self.private_key.into_value()); map.insert_unchecked(Property::DomainId, self.domain_id.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Selector, self.selector.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked( Property::NextTransitionAt, self.next_transition_at.into_value(), ); map.insert_unchecked(Property::Stage, self.stage.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Dkim2Signature { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Flags) => self.flags.patch(pointer, value), Some(Property::PrivateKey) => self.private_key.patch(pointer, value), Some(Property::PublicKey) => pointer.assert_server_set(), Some(Property::DomainId) => self.domain_id.patch(pointer, value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Selector) => self .selector .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::NextTransitionAt) => self.next_transition_at.patch(pointer, value), Some(Property::Stage) => self.stage.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DkimManagement { fn validate(&self, errors: &mut Vec) -> bool { match self { DkimManagement::Automatic(inner) => inner.validate(errors), DkimManagement::Manual => true, } } } impl Default for DkimManagement { fn default() -> Self { DkimManagement::Automatic(Default::default()) } } impl Pickle for DkimManagement { fn pickle(&self, out: &mut Vec) { match self { DkimManagement::Automatic(inner) => { 0u16.pickle(out); inner.pickle(out); } DkimManagement::Manual => { 1u16.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(DkimManagement::Automatic), 1 => Some(DkimManagement::Manual), _ => None, } } } impl IntoValue for DkimManagement { fn into_value(self) -> JmapValue<'static> { match self { DkimManagement::Automatic(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Automatic".into())); obj } DkimManagement::Manual => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Manual".into())); JmapValue::Object(obj) } } } } impl RegistryJsonPatch for DkimManagement { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { DkimManagementType::Automatic => { *self = DkimManagement::Automatic(Default::default()) } DkimManagementType::Manual => *self = DkimManagement::Manual, } } match self { DkimManagement::Automatic(inner) => inner.patch(pointer, value), DkimManagement::Manual => pointer.assert_eof(), } } } impl DkimManagement { pub fn object_type(&self) -> DkimManagementType { match self { DkimManagement::Automatic(_) => DkimManagementType::Automatic, DkimManagement::Manual => DkimManagementType::Manual, } } } impl DkimManagementProperties { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.selector_template; if value.is_empty() { errors.push(ValidationError::required(Property::SelectorTemplate)); } errors.len() == neb } } impl Pickle for DkimManagementProperties { fn pickle(&self, out: &mut Vec) { self.algorithms.pickle(out); self.selector_template.pickle(out); self.rotate_after.pickle(out); self.retire_after.pickle(out); self.delete_after.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.algorithms = Pickle::unpickle(stream)?; this.selector_template = Pickle::unpickle(stream)?; this.rotate_after = Pickle::unpickle(stream)?; this.retire_after = Pickle::unpickle(stream)?; this.delete_after = Pickle::unpickle(stream)?; Some(this) } } impl Default for DkimManagementProperties { fn default() -> Self { Self { algorithms: Map::new(vec![ DkimSignatureType::Dkim1Ed25519Sha256, DkimSignatureType::Dkim1RsaSha256, ]), selector_template: "v{version}-{algorithm}-{date-%Y%m%d}".to_string(), rotate_after: Duration::from_millis(7776000000), retire_after: Duration::from_millis(604800000), delete_after: Duration::from_millis(2592000000), } } } impl IntoValue for DkimManagementProperties { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Algorithms, self.algorithms.into_value()); map.insert_unchecked( Property::SelectorTemplate, self.selector_template.into_value(), ); map.insert_unchecked(Property::RotateAfter, self.rotate_after.into_value()); map.insert_unchecked(Property::RetireAfter, self.retire_after.into_value()); map.insert_unchecked(Property::DeleteAfter, self.delete_after.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DkimManagementProperties { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Algorithms) => self.algorithms.patch(pointer, value), Some(Property::SelectorTemplate) => self .selector_template .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::RotateAfter) => self.rotate_after.patch(pointer, value), Some(Property::RetireAfter) => self.retire_after.patch(pointer, value), Some(Property::DeleteAfter) => self.delete_after.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for DkimReportSettings { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::DkimReportSettings; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.from_address; value.validate(errors); let value = &self.from_name; value.validate(errors); let value = &self.send_frequency; value.validate(errors); let value = &self.dkim_sign_domain; value.validate(errors); let value = &self.subject; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl DkimReportSettings { pub fn ctx_from_address(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.from_address, default: Some(Expression { else_: "'noreply-dkim@' + system('domain')".to_string(), ..Default::default() }), property: Property::FromAddress, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_from_name(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.from_name, default: Some(Expression { else_: "'Report Subsystem'".to_string(), ..Default::default() }), property: Property::FromName, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_send_frequency(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.send_frequency, default: Some(Expression { else_: "[1, 1d]".to_string(), ..Default::default() }), property: Property::SendFrequency, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_dkim_sign_domain(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.dkim_sign_domain, default: Some(Expression { else_: "system('domain')".to_string(), ..Default::default() }), property: Property::DkimSignDomain, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_subject(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.subject, default: Some(Expression { else_: "'DKIM Authentication Failure Report'".to_string(), ..Default::default() }), property: Property::Subject, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_from_address(), self.ctx_from_name(), self.ctx_send_frequency(), self.ctx_dkim_sign_domain(), self.ctx_subject(), ] } } impl Pickle for DkimReportSettings { fn pickle(&self, out: &mut Vec) { self.from_address.pickle(out); self.from_name.pickle(out); self.send_frequency.pickle(out); self.dkim_sign_domain.pickle(out); self.subject.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.from_address = Pickle::unpickle(stream)?; this.from_name = Pickle::unpickle(stream)?; this.send_frequency = Pickle::unpickle(stream)?; this.dkim_sign_domain = Pickle::unpickle(stream)?; this.subject = Pickle::unpickle(stream)?; Some(this) } } impl Default for DkimReportSettings { fn default() -> Self { Self { from_address: Expression { else_: "'noreply-dkim@' + system('domain')".to_string(), ..Default::default() }, from_name: Expression { else_: "'Report Subsystem'".to_string(), ..Default::default() }, send_frequency: Expression { else_: "[1, 1d]".to_string(), ..Default::default() }, dkim_sign_domain: Expression { else_: "system('domain')".to_string(), ..Default::default() }, subject: Expression { else_: "'DKIM Authentication Failure Report'".to_string(), ..Default::default() }, } } } impl IntoValue for DkimReportSettings { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::FromAddress, self.from_address.into_value()); map.insert_unchecked(Property::FromName, self.from_name.into_value()); map.insert_unchecked(Property::SendFrequency, self.send_frequency.into_value()); map.insert_unchecked(Property::DkimSignDomain, self.dkim_sign_domain.into_value()); map.insert_unchecked(Property::Subject, self.subject.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DkimReportSettings { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::FromAddress) => self.from_address.patch(pointer, value), Some(Property::FromName) => self.from_name.patch(pointer, value), Some(Property::SendFrequency) => self.send_frequency.patch(pointer, value), Some(Property::DkimSignDomain) => self.dkim_sign_domain.patch(pointer, value), Some(Property::Subject) => self.subject.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for DkimSignature { const FLAGS: u64 = OBJ_FILTER_TENANT; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::DkimSignature; fn validate(&self, errors: &mut Vec) -> bool { match self { DkimSignature::Dkim1Ed25519Sha256(inner) => inner.validate(errors), DkimSignature::Dkim1RsaSha256(inner) => inner.validate(errors), DkimSignature::Dkim2Ed25519Sha256(inner) => inner.validate(errors), DkimSignature::Dkim2RsaSha256(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { DkimSignature::Dkim1Ed25519Sha256(object) => { object.index(i); } DkimSignature::Dkim1RsaSha256(object) => { object.index(i); } DkimSignature::Dkim2Ed25519Sha256(object) => { object.index(i); } DkimSignature::Dkim2RsaSha256(object) => { object.index(i); } } } } impl Default for DkimSignature { fn default() -> Self { DkimSignature::Dkim1Ed25519Sha256(Default::default()) } } impl Pickle for DkimSignature { fn pickle(&self, out: &mut Vec) { match self { DkimSignature::Dkim1Ed25519Sha256(inner) => { 0u16.pickle(out); inner.pickle(out); } DkimSignature::Dkim1RsaSha256(inner) => { 1u16.pickle(out); inner.pickle(out); } DkimSignature::Dkim2Ed25519Sha256(inner) => { 2u16.pickle(out); inner.pickle(out); } DkimSignature::Dkim2RsaSha256(inner) => { 3u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(DkimSignature::Dkim1Ed25519Sha256), 1 => Pickle::unpickle(stream).map(DkimSignature::Dkim1RsaSha256), 2 => Pickle::unpickle(stream).map(DkimSignature::Dkim2Ed25519Sha256), 3 => Pickle::unpickle(stream).map(DkimSignature::Dkim2RsaSha256), _ => None, } } } impl IntoValue for DkimSignature { fn into_value(self) -> JmapValue<'static> { match self { DkimSignature::Dkim1Ed25519Sha256(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Dkim1Ed25519Sha256".into())); obj } DkimSignature::Dkim1RsaSha256(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Dkim1RsaSha256".into())); obj } DkimSignature::Dkim2Ed25519Sha256(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Dkim2Ed25519Sha256".into())); obj } DkimSignature::Dkim2RsaSha256(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Dkim2RsaSha256".into())); obj } } } } impl RegistryJsonPatch for DkimSignature { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { DkimSignatureType::Dkim1Ed25519Sha256 => { *self = DkimSignature::Dkim1Ed25519Sha256(Default::default()) } DkimSignatureType::Dkim1RsaSha256 => { *self = DkimSignature::Dkim1RsaSha256(Default::default()) } DkimSignatureType::Dkim2Ed25519Sha256 => { *self = DkimSignature::Dkim2Ed25519Sha256(Default::default()) } DkimSignatureType::Dkim2RsaSha256 => { *self = DkimSignature::Dkim2RsaSha256(Default::default()) } } } match self { DkimSignature::Dkim1Ed25519Sha256(inner) => inner.patch(pointer, value), DkimSignature::Dkim1RsaSha256(inner) => inner.patch(pointer, value), DkimSignature::Dkim2Ed25519Sha256(inner) => inner.patch(pointer, value), DkimSignature::Dkim2RsaSha256(inner) => inner.patch(pointer, value), } } } impl DkimSignature { pub fn object_type(&self) -> DkimSignatureType { match self { DkimSignature::Dkim1Ed25519Sha256(_) => DkimSignatureType::Dkim1Ed25519Sha256, DkimSignature::Dkim1RsaSha256(_) => DkimSignatureType::Dkim1RsaSha256, DkimSignature::Dkim2Ed25519Sha256(_) => DkimSignatureType::Dkim2Ed25519Sha256, DkimSignature::Dkim2RsaSha256(_) => DkimSignatureType::Dkim2RsaSha256, } } } impl DmarcDkimResult { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.domain; if value.is_empty() { errors.push(ValidationError::required(Property::Domain)); } let value = &self.selector; if value.is_empty() { errors.push(ValidationError::required(Property::Selector)); } if let Some(value) = &self.human_result { if value.is_empty() { errors.push(ValidationError::required(Property::HumanResult)); } } errors.len() == neb } } impl Pickle for DmarcDkimResult { fn pickle(&self, out: &mut Vec) { self.domain.pickle(out); self.selector.pickle(out); self.result.pickle(out); self.human_result.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.domain = Pickle::unpickle(stream)?; this.selector = Pickle::unpickle(stream)?; this.result = Pickle::unpickle(stream)?; this.human_result = Pickle::unpickle(stream)?; Some(this) } } impl Default for DmarcDkimResult { fn default() -> Self { Self { domain: Default::default(), selector: Default::default(), result: Default::default(), human_result: Default::default(), } } } impl IntoValue for DmarcDkimResult { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Domain, self.domain.into_value()); map.insert_unchecked(Property::Selector, self.selector.into_value()); map.insert_unchecked(Property::Result, self.result.into_value()); map.insert_unchecked(Property::HumanResult, self.human_result.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DmarcDkimResult { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Domain) => self .domain .patch(pointer.with_validators(&[StringValidator::Domain]), value), Some(Property::Selector) => self.selector.patch(pointer, value), Some(Property::Result) => self.result.patch(pointer, value), Some(Property::HumanResult) => self.human_result.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DmarcExtension { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } let value = &self.definition; if value.is_empty() { errors.push(ValidationError::required(Property::Definition)); } errors.len() == neb } } impl Pickle for DmarcExtension { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.definition.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.definition = Pickle::unpickle(stream)?; Some(this) } } impl Default for DmarcExtension { fn default() -> Self { Self { name: Default::default(), definition: Default::default(), } } } impl IntoValue for DmarcExtension { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Definition, self.definition.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DmarcExtension { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self.name.patch(pointer, value), Some(Property::Definition) => self.definition.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for DmarcExternalReport { const FLAGS: u64 = OBJ_FILTER_TENANT; const VERSION: u8 = 1; const OBJECT: ObjectType = ObjectType::DmarcExternalReport; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.report; value.validate(errors); let value = &self.from; if value.is_empty() { errors.push(ValidationError::required(Property::From)); } let value = &self.subject; if value.is_empty() { errors.push(ValidationError::required(Property::Subject)); } let value = &self.to; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::To)); } } let value = &self.received_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ReceivedAt, value)); } let value = &self.expires_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ExpiresAt, value)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); } } impl Pickle for DmarcExternalReport { fn pickle(&self, out: &mut Vec) { self.report.pickle(out); self.from.pickle(out); self.subject.pickle(out); self.to.pickle(out); self.received_at.pickle(out); self.expires_at.pickle(out); self.member_tenant_id.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.report = Pickle::unpickle(stream)?; this.from = Pickle::unpickle(stream)?; this.subject = Pickle::unpickle(stream)?; this.to = Pickle::unpickle(stream)?; this.received_at = Pickle::unpickle(stream)?; this.expires_at = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; Some(this) } } impl Default for DmarcExternalReport { fn default() -> Self { Self { report: Default::default(), from: Default::default(), subject: Default::default(), to: Default::default(), received_at: Default::default(), expires_at: Default::default(), member_tenant_id: Default::default(), } } } impl IntoValue for DmarcExternalReport { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked(Property::Report, self.report.into_value()); map.insert_unchecked(Property::From, self.from.into_value()); map.insert_unchecked(Property::Subject, self.subject.into_value()); map.insert_unchecked(Property::To, self.to.into_value()); map.insert_unchecked(Property::ReceivedAt, self.received_at.into_value()); map.insert_unchecked(Property::ExpiresAt, self.expires_at.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DmarcExternalReport { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Report) => self.report.patch(pointer, value), Some(Property::From) => self .from .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::Subject) => self.subject.patch(pointer, value), Some(Property::To) => self .to .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::ReceivedAt) => self.received_at.patch(pointer, value), Some(Property::ExpiresAt) => self.expires_at.patch(pointer, value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for DmarcInternalReport { const FLAGS: u64 = 0; const VERSION: u8 = 1; const OBJECT: ObjectType = ObjectType::DmarcInternalReport; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.rua; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::Rua)); } } let value = &self.report; value.validate(errors); let value = &self.domain; if value.is_empty() { errors.push(ValidationError::required(Property::Domain)); } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } let value = &self.deliver_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::DeliverAt, value)); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for DmarcInternalReport { fn pickle(&self, out: &mut Vec) { self.rua.pickle(out); self.policy_identifier.pickle(out); self.report.pickle(out); self.domain.pickle(out); self.created_at.pickle(out); self.deliver_at.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.rua = Pickle::unpickle(stream)?; this.policy_identifier = Pickle::unpickle(stream)?; this.report = Pickle::unpickle(stream)?; this.domain = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.deliver_at = Pickle::unpickle(stream)?; Some(this) } } impl Default for DmarcInternalReport { fn default() -> Self { Self { rua: Default::default(), policy_identifier: 0u64, report: Default::default(), domain: Default::default(), created_at: Default::default(), deliver_at: Default::default(), } } } impl IntoValue for DmarcInternalReport { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::Rua, self.rua.into_value()); map.insert_unchecked( Property::PolicyIdentifier, self.policy_identifier.into_value(), ); map.insert_unchecked(Property::Report, self.report.into_value()); map.insert_unchecked(Property::Domain, self.domain.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::DeliverAt, self.deliver_at.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DmarcInternalReport { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Rua) => self .rua .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::PolicyIdentifier) => self.policy_identifier.patch(pointer, value), Some(Property::Report) => self.report.patch(pointer, value), Some(Property::Domain) => self .domain .patch(pointer.with_validators(&[StringValidator::Domain]), value), Some(Property::CreatedAt) => self.created_at.patch(pointer, value), Some(Property::DeliverAt) => self.deliver_at.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DmarcPolicyOverrideReason { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.comment { if value.is_empty() { errors.push(ValidationError::required(Property::Comment)); } } errors.len() == neb } } impl Pickle for DmarcPolicyOverrideReason { fn pickle(&self, out: &mut Vec) { self.override_type.pickle(out); self.comment.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.override_type = Pickle::unpickle(stream)?; this.comment = Pickle::unpickle(stream)?; Some(this) } } impl Default for DmarcPolicyOverrideReason { fn default() -> Self { Self { override_type: Default::default(), comment: Default::default(), } } } impl IntoValue for DmarcPolicyOverrideReason { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::OverrideType, self.override_type.into_value()); map.insert_unchecked(Property::Comment, self.comment.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DmarcPolicyOverrideReason { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::OverrideType) => self.override_type.patch(pointer, value), Some(Property::Comment) => self.comment.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DmarcReport { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.org_name; if value.is_empty() { errors.push(ValidationError::required(Property::OrgName)); } let value = &self.email; if value.is_empty() { errors.push(ValidationError::required(Property::Email)); } if let Some(value) = &self.extra_contact_info { if value.is_empty() { errors.push(ValidationError::required(Property::ExtraContactInfo)); } } let value = &self.report_id; if value.is_empty() { errors.push(ValidationError::required(Property::ReportId)); } let value = &self.date_range_begin; if !value.is_valid() { errors.push(ValidationError::invalid(Property::DateRangeBegin, value)); } let value = &self.date_range_end; if !value.is_valid() { errors.push(ValidationError::invalid(Property::DateRangeEnd, value)); } let value = &self.errors; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::Errors)); } } let value = &self.policy_domain; if value.is_empty() { errors.push(ValidationError::required(Property::PolicyDomain)); } if let Some(value) = &self.policy_version { if value.is_empty() { errors.push(ValidationError::required(Property::PolicyVersion)); } } let value = &self.records; for value in value.values() { value.validate(errors); } let value = &self.extensions; for value in value.values() { value.validate(errors); } if let Some(value) = &self.generator { if value.is_empty() { errors.push(ValidationError::required(Property::Generator)); } } errors.len() == neb } } impl Pickle for DmarcReport { fn pickle(&self, out: &mut Vec) { self.version.pickle(out); self.org_name.pickle(out); self.email.pickle(out); self.extra_contact_info.pickle(out); self.report_id.pickle(out); self.date_range_begin.pickle(out); self.date_range_end.pickle(out); self.errors.pickle(out); self.policy_domain.pickle(out); self.policy_version.pickle(out); self.policy_adkim.pickle(out); self.policy_aspf.pickle(out); self.policy_disposition.pickle(out); self.policy_subdomain_disposition.pickle(out); self.policy_testing_mode.pickle(out); self.policy_failure_reporting_options.pickle(out); self.records.pickle(out); self.extensions.pickle(out); self.generator.pickle(out); self.policy_np.pickle(out); self.policy_discovery_method.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.version = Pickle::unpickle(stream)?; this.org_name = Pickle::unpickle(stream)?; this.email = Pickle::unpickle(stream)?; this.extra_contact_info = Pickle::unpickle(stream)?; this.report_id = Pickle::unpickle(stream)?; this.date_range_begin = Pickle::unpickle(stream)?; this.date_range_end = Pickle::unpickle(stream)?; this.errors = Pickle::unpickle(stream)?; this.policy_domain = Pickle::unpickle(stream)?; this.policy_version = Pickle::unpickle(stream)?; this.policy_adkim = Pickle::unpickle(stream)?; this.policy_aspf = Pickle::unpickle(stream)?; this.policy_disposition = Pickle::unpickle(stream)?; this.policy_subdomain_disposition = Pickle::unpickle(stream)?; this.policy_testing_mode = Pickle::unpickle(stream)?; this.policy_failure_reporting_options = Pickle::unpickle(stream)?; this.records = Pickle::unpickle(stream)?; this.extensions = Pickle::unpickle(stream)?; if stream.version() >= 1 { this.generator = Pickle::unpickle(stream)?; } if stream.version() >= 1 { this.policy_np = Pickle::unpickle(stream)?; } if stream.version() >= 1 { this.policy_discovery_method = Pickle::unpickle(stream)?; } Some(this) } } impl Default for DmarcReport { fn default() -> Self { Self { version: Float::new(1.0f64), org_name: Default::default(), email: Default::default(), extra_contact_info: Default::default(), report_id: Default::default(), date_range_begin: Default::default(), date_range_end: Default::default(), errors: Default::default(), policy_domain: Default::default(), policy_version: Default::default(), policy_adkim: Default::default(), policy_aspf: Default::default(), policy_disposition: Default::default(), policy_subdomain_disposition: Default::default(), policy_testing_mode: false, policy_failure_reporting_options: Default::default(), records: Default::default(), extensions: Default::default(), generator: Default::default(), policy_np: DmarcDisposition::Unspecified, policy_discovery_method: DmarcDiscovery::Unspecified, } } } impl IntoValue for DmarcReport { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(23); map.insert_unchecked(Property::Version, self.version.into_value()); map.insert_unchecked(Property::OrgName, self.org_name.into_value()); map.insert_unchecked(Property::Email, self.email.into_value()); map.insert_unchecked( Property::ExtraContactInfo, self.extra_contact_info.into_value(), ); map.insert_unchecked(Property::ReportId, self.report_id.into_value()); map.insert_unchecked(Property::DateRangeBegin, self.date_range_begin.into_value()); map.insert_unchecked(Property::DateRangeEnd, self.date_range_end.into_value()); map.insert_unchecked(Property::Errors, self.errors.into_value()); map.insert_unchecked(Property::PolicyDomain, self.policy_domain.into_value()); map.insert_unchecked(Property::PolicyVersion, self.policy_version.into_value()); map.insert_unchecked(Property::PolicyAdkim, self.policy_adkim.into_value()); map.insert_unchecked(Property::PolicyAspf, self.policy_aspf.into_value()); map.insert_unchecked( Property::PolicyDisposition, self.policy_disposition.into_value(), ); map.insert_unchecked( Property::PolicySubdomainDisposition, self.policy_subdomain_disposition.into_value(), ); map.insert_unchecked( Property::PolicyTestingMode, self.policy_testing_mode.into_value(), ); map.insert_unchecked( Property::PolicyFailureReportingOptions, self.policy_failure_reporting_options.into_value(), ); map.insert_unchecked(Property::Records, self.records.into_value()); map.insert_unchecked(Property::Extensions, self.extensions.into_value()); map.insert_unchecked(Property::Generator, self.generator.into_value()); map.insert_unchecked(Property::PolicyNp, self.policy_np.into_value()); map.insert_unchecked( Property::PolicyDiscoveryMethod, self.policy_discovery_method.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DmarcReport { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Version) => self.version.patch(pointer, value), Some(Property::OrgName) => self.org_name.patch(pointer, value), Some(Property::Email) => self .email .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::ExtraContactInfo) => self.extra_contact_info.patch(pointer, value), Some(Property::ReportId) => self.report_id.patch(pointer, value), Some(Property::DateRangeBegin) => self.date_range_begin.patch(pointer, value), Some(Property::DateRangeEnd) => self.date_range_end.patch(pointer, value), Some(Property::Errors) => self.errors.patch(pointer, value), Some(Property::PolicyDomain) => self.policy_domain.patch(pointer, value), Some(Property::PolicyVersion) => self.policy_version.patch(pointer, value), Some(Property::PolicyAdkim) => self.policy_adkim.patch(pointer, value), Some(Property::PolicyAspf) => self.policy_aspf.patch(pointer, value), Some(Property::PolicyDisposition) => self.policy_disposition.patch(pointer, value), Some(Property::PolicySubdomainDisposition) => { self.policy_subdomain_disposition.patch(pointer, value) } Some(Property::PolicyTestingMode) => self.policy_testing_mode.patch(pointer, value), Some(Property::PolicyFailureReportingOptions) => { self.policy_failure_reporting_options.patch(pointer, value) } Some(Property::Records) => self.records.patch(pointer, value), Some(Property::Extensions) => self.extensions.patch(pointer, value), Some(Property::Generator) => self.generator.patch(pointer, value), Some(Property::PolicyNp) => self.policy_np.patch(pointer, value), Some(Property::PolicyDiscoveryMethod) => { self.policy_discovery_method.patch(pointer, value) } Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DmarcReportRecord { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.source_ip { if !value.is_valid() { errors.push(ValidationError::invalid(Property::SourceIp, value)); } } let value = &self.policy_override_reasons; for value in value.values() { value.validate(errors); } if let Some(value) = &self.envelope_to { if value.is_empty() { errors.push(ValidationError::required(Property::EnvelopeTo)); } } let value = &self.envelope_from; if value.is_empty() { errors.push(ValidationError::required(Property::EnvelopeFrom)); } let value = &self.header_from; if value.is_empty() { errors.push(ValidationError::required(Property::HeaderFrom)); } let value = &self.dkim_results; for value in value.values() { value.validate(errors); } let value = &self.spf_results; for value in value.values() { value.validate(errors); } let value = &self.extensions; for value in value.values() { value.validate(errors); } errors.len() == neb } } impl Pickle for DmarcReportRecord { fn pickle(&self, out: &mut Vec) { self.source_ip.pickle(out); self.count.pickle(out); self.evaluated_disposition.pickle(out); self.evaluated_dkim.pickle(out); self.evaluated_spf.pickle(out); self.policy_override_reasons.pickle(out); self.envelope_to.pickle(out); self.envelope_from.pickle(out); self.header_from.pickle(out); self.dkim_results.pickle(out); self.spf_results.pickle(out); self.extensions.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.source_ip = Pickle::unpickle(stream)?; this.count = Pickle::unpickle(stream)?; this.evaluated_disposition = Pickle::unpickle(stream)?; this.evaluated_dkim = Pickle::unpickle(stream)?; this.evaluated_spf = Pickle::unpickle(stream)?; this.policy_override_reasons = Pickle::unpickle(stream)?; this.envelope_to = Pickle::unpickle(stream)?; this.envelope_from = Pickle::unpickle(stream)?; this.header_from = Pickle::unpickle(stream)?; this.dkim_results = Pickle::unpickle(stream)?; this.spf_results = Pickle::unpickle(stream)?; this.extensions = Pickle::unpickle(stream)?; Some(this) } } impl Default for DmarcReportRecord { fn default() -> Self { Self { source_ip: Default::default(), count: 0u64, evaluated_disposition: Default::default(), evaluated_dkim: Default::default(), evaluated_spf: Default::default(), policy_override_reasons: Default::default(), envelope_to: Default::default(), envelope_from: Default::default(), header_from: Default::default(), dkim_results: Default::default(), spf_results: Default::default(), extensions: Default::default(), } } } impl IntoValue for DmarcReportRecord { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked(Property::SourceIp, self.source_ip.into_value()); map.insert_unchecked(Property::Count, self.count.into_value()); map.insert_unchecked( Property::EvaluatedDisposition, self.evaluated_disposition.into_value(), ); map.insert_unchecked(Property::EvaluatedDkim, self.evaluated_dkim.into_value()); map.insert_unchecked(Property::EvaluatedSpf, self.evaluated_spf.into_value()); map.insert_unchecked( Property::PolicyOverrideReasons, self.policy_override_reasons.into_value(), ); map.insert_unchecked(Property::EnvelopeTo, self.envelope_to.into_value()); map.insert_unchecked(Property::EnvelopeFrom, self.envelope_from.into_value()); map.insert_unchecked(Property::HeaderFrom, self.header_from.into_value()); map.insert_unchecked(Property::DkimResults, self.dkim_results.into_value()); map.insert_unchecked(Property::SpfResults, self.spf_results.into_value()); map.insert_unchecked(Property::Extensions, self.extensions.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DmarcReportRecord { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::SourceIp) => self.source_ip.patch(pointer, value), Some(Property::Count) => self.count.patch(pointer, value), Some(Property::EvaluatedDisposition) => { self.evaluated_disposition.patch(pointer, value) } Some(Property::EvaluatedDkim) => self.evaluated_dkim.patch(pointer, value), Some(Property::EvaluatedSpf) => self.evaluated_spf.patch(pointer, value), Some(Property::PolicyOverrideReasons) => { self.policy_override_reasons.patch(pointer, value) } Some(Property::EnvelopeTo) => self.envelope_to.patch(pointer, value), Some(Property::EnvelopeFrom) => self.envelope_from.patch(pointer, value), Some(Property::HeaderFrom) => self.header_from.patch(pointer, value), Some(Property::DkimResults) => self.dkim_results.patch(pointer, value), Some(Property::SpfResults) => self.spf_results.patch(pointer, value), Some(Property::Extensions) => self.extensions.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for DmarcReportSettings { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::DmarcReportSettings; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.aggregate_contact_info; value.validate(errors); let value = &self.aggregate_from_address; value.validate(errors); let value = &self.aggregate_from_name; value.validate(errors); let value = &self.aggregate_max_report_size; value.validate(errors); let value = &self.aggregate_org_name; value.validate(errors); let value = &self.aggregate_send_frequency; value.validate(errors); let value = &self.aggregate_dkim_sign_domain; value.validate(errors); let value = &self.aggregate_subject; value.validate(errors); let value = &self.failure_from_address; value.validate(errors); let value = &self.failure_from_name; value.validate(errors); let value = &self.failure_send_frequency; value.validate(errors); let value = &self.failure_dkim_sign_domain; value.validate(errors); let value = &self.failure_subject; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl DmarcReportSettings { pub fn ctx_aggregate_contact_info(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.aggregate_contact_info, default: Some(Expression { else_: "false".to_string(), ..Default::default() }), property: Property::AggregateContactInfo, allowed_variables: MTA_RCPT_DOMAIN_VARIABLE, allowed_constants: &[], } } pub fn ctx_aggregate_from_address(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.aggregate_from_address, default: Some(Expression { else_: "'noreply-dmarc@' + system('domain')".to_string(), ..Default::default() }), property: Property::AggregateFromAddress, allowed_variables: MTA_RCPT_DOMAIN_VARIABLE, allowed_constants: &[], } } pub fn ctx_aggregate_from_name(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.aggregate_from_name, default: Some(Expression { else_: "'Report Subsystem'".to_string(), ..Default::default() }), property: Property::AggregateFromName, allowed_variables: MTA_RCPT_DOMAIN_VARIABLE, allowed_constants: &[], } } pub fn ctx_aggregate_max_report_size(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.aggregate_max_report_size, default: Some(Expression { else_: "5242880".to_string(), ..Default::default() }), property: Property::AggregateMaxReportSize, allowed_variables: MTA_RCPT_DOMAIN_VARIABLE, allowed_constants: &[], } } pub fn ctx_aggregate_org_name(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.aggregate_org_name, default: Some(Expression { else_: "system('domain')".to_string(), ..Default::default() }), property: Property::AggregateOrgName, allowed_variables: MTA_RCPT_DOMAIN_VARIABLE, allowed_constants: &[], } } pub fn ctx_aggregate_send_frequency(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.aggregate_send_frequency, default: Some(Expression { else_: "daily".to_string(), ..Default::default() }), property: Property::AggregateSendFrequency, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: MTA_AGGREGATE_CONSTANT, } } pub fn ctx_aggregate_dkim_sign_domain(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.aggregate_dkim_sign_domain, default: Some(Expression { else_: "system('domain')".to_string(), ..Default::default() }), property: Property::AggregateDkimSignDomain, allowed_variables: MTA_RCPT_DOMAIN_VARIABLE, allowed_constants: &[], } } pub fn ctx_aggregate_subject(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.aggregate_subject, default: Some(Expression { else_: "'DMARC Aggregate Report'".to_string(), ..Default::default() }), property: Property::AggregateSubject, allowed_variables: MTA_RCPT_DOMAIN_VARIABLE, allowed_constants: &[], } } pub fn ctx_failure_from_address(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.failure_from_address, default: Some(Expression { else_: "'noreply-dmarc@' + system('domain')".to_string(), ..Default::default() }), property: Property::FailureFromAddress, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_failure_from_name(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.failure_from_name, default: Some(Expression { else_: "'Report Subsystem'".to_string(), ..Default::default() }), property: Property::FailureFromName, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_failure_send_frequency(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.failure_send_frequency, default: Some(Expression { else_: "[1, 1d]".to_string(), ..Default::default() }), property: Property::FailureSendFrequency, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_failure_dkim_sign_domain(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.failure_dkim_sign_domain, default: Some(Expression { else_: "system('domain')".to_string(), ..Default::default() }), property: Property::FailureDkimSignDomain, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_failure_subject(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.failure_subject, default: Some(Expression { else_: "'DMARC Authentication Failure Report'".to_string(), ..Default::default() }), property: Property::FailureSubject, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_aggregate_contact_info(), self.ctx_aggregate_from_address(), self.ctx_aggregate_from_name(), self.ctx_aggregate_max_report_size(), self.ctx_aggregate_org_name(), self.ctx_aggregate_send_frequency(), self.ctx_aggregate_dkim_sign_domain(), self.ctx_aggregate_subject(), self.ctx_failure_from_address(), self.ctx_failure_from_name(), self.ctx_failure_send_frequency(), self.ctx_failure_dkim_sign_domain(), self.ctx_failure_subject(), ] } } impl Pickle for DmarcReportSettings { fn pickle(&self, out: &mut Vec) { self.aggregate_contact_info.pickle(out); self.aggregate_from_address.pickle(out); self.aggregate_from_name.pickle(out); self.aggregate_max_report_size.pickle(out); self.aggregate_org_name.pickle(out); self.aggregate_send_frequency.pickle(out); self.aggregate_dkim_sign_domain.pickle(out); self.aggregate_subject.pickle(out); self.failure_from_address.pickle(out); self.failure_from_name.pickle(out); self.failure_send_frequency.pickle(out); self.failure_dkim_sign_domain.pickle(out); self.failure_subject.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.aggregate_contact_info = Pickle::unpickle(stream)?; this.aggregate_from_address = Pickle::unpickle(stream)?; this.aggregate_from_name = Pickle::unpickle(stream)?; this.aggregate_max_report_size = Pickle::unpickle(stream)?; this.aggregate_org_name = Pickle::unpickle(stream)?; this.aggregate_send_frequency = Pickle::unpickle(stream)?; this.aggregate_dkim_sign_domain = Pickle::unpickle(stream)?; this.aggregate_subject = Pickle::unpickle(stream)?; this.failure_from_address = Pickle::unpickle(stream)?; this.failure_from_name = Pickle::unpickle(stream)?; this.failure_send_frequency = Pickle::unpickle(stream)?; this.failure_dkim_sign_domain = Pickle::unpickle(stream)?; this.failure_subject = Pickle::unpickle(stream)?; Some(this) } } impl Default for DmarcReportSettings { fn default() -> Self { Self { aggregate_contact_info: Expression { else_: "false".to_string(), ..Default::default() }, aggregate_from_address: Expression { else_: "'noreply-dmarc@' + system('domain')".to_string(), ..Default::default() }, aggregate_from_name: Expression { else_: "'Report Subsystem'".to_string(), ..Default::default() }, aggregate_max_report_size: Expression { else_: "5242880".to_string(), ..Default::default() }, aggregate_org_name: Expression { else_: "system('domain')".to_string(), ..Default::default() }, aggregate_send_frequency: Expression { else_: "daily".to_string(), ..Default::default() }, aggregate_dkim_sign_domain: Expression { else_: "system('domain')".to_string(), ..Default::default() }, aggregate_subject: Expression { else_: "'DMARC Aggregate Report'".to_string(), ..Default::default() }, failure_from_address: Expression { else_: "'noreply-dmarc@' + system('domain')".to_string(), ..Default::default() }, failure_from_name: Expression { else_: "'Report Subsystem'".to_string(), ..Default::default() }, failure_send_frequency: Expression { else_: "[1, 1d]".to_string(), ..Default::default() }, failure_dkim_sign_domain: Expression { else_: "system('domain')".to_string(), ..Default::default() }, failure_subject: Expression { else_: "'DMARC Authentication Failure Report'".to_string(), ..Default::default() }, } } } impl IntoValue for DmarcReportSettings { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(15); map.insert_unchecked( Property::AggregateContactInfo, self.aggregate_contact_info.into_value(), ); map.insert_unchecked( Property::AggregateFromAddress, self.aggregate_from_address.into_value(), ); map.insert_unchecked( Property::AggregateFromName, self.aggregate_from_name.into_value(), ); map.insert_unchecked( Property::AggregateMaxReportSize, self.aggregate_max_report_size.into_value(), ); map.insert_unchecked( Property::AggregateOrgName, self.aggregate_org_name.into_value(), ); map.insert_unchecked( Property::AggregateSendFrequency, self.aggregate_send_frequency.into_value(), ); map.insert_unchecked( Property::AggregateDkimSignDomain, self.aggregate_dkim_sign_domain.into_value(), ); map.insert_unchecked( Property::AggregateSubject, self.aggregate_subject.into_value(), ); map.insert_unchecked( Property::FailureFromAddress, self.failure_from_address.into_value(), ); map.insert_unchecked( Property::FailureFromName, self.failure_from_name.into_value(), ); map.insert_unchecked( Property::FailureSendFrequency, self.failure_send_frequency.into_value(), ); map.insert_unchecked( Property::FailureDkimSignDomain, self.failure_dkim_sign_domain.into_value(), ); map.insert_unchecked(Property::FailureSubject, self.failure_subject.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DmarcReportSettings { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AggregateContactInfo) => { self.aggregate_contact_info.patch(pointer, value) } Some(Property::AggregateFromAddress) => { self.aggregate_from_address.patch(pointer, value) } Some(Property::AggregateFromName) => self.aggregate_from_name.patch(pointer, value), Some(Property::AggregateMaxReportSize) => { self.aggregate_max_report_size.patch(pointer, value) } Some(Property::AggregateOrgName) => self.aggregate_org_name.patch(pointer, value), Some(Property::AggregateSendFrequency) => { self.aggregate_send_frequency.patch(pointer, value) } Some(Property::AggregateDkimSignDomain) => { self.aggregate_dkim_sign_domain.patch(pointer, value) } Some(Property::AggregateSubject) => self.aggregate_subject.patch(pointer, value), Some(Property::FailureFromAddress) => self.failure_from_address.patch(pointer, value), Some(Property::FailureFromName) => self.failure_from_name.patch(pointer, value), Some(Property::FailureSendFrequency) => { self.failure_send_frequency.patch(pointer, value) } Some(Property::FailureDkimSignDomain) => { self.failure_dkim_sign_domain.patch(pointer, value) } Some(Property::FailureSubject) => self.failure_subject.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DmarcSpfResult { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.domain; if value.is_empty() { errors.push(ValidationError::required(Property::Domain)); } if let Some(value) = &self.human_result { if value.is_empty() { errors.push(ValidationError::required(Property::HumanResult)); } } errors.len() == neb } } impl Pickle for DmarcSpfResult { fn pickle(&self, out: &mut Vec) { self.domain.pickle(out); self.scope.pickle(out); self.result.pickle(out); self.human_result.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.domain = Pickle::unpickle(stream)?; this.scope = Pickle::unpickle(stream)?; this.result = Pickle::unpickle(stream)?; this.human_result = Pickle::unpickle(stream)?; Some(this) } } impl Default for DmarcSpfResult { fn default() -> Self { Self { domain: Default::default(), scope: Default::default(), result: Default::default(), human_result: Default::default(), } } } impl IntoValue for DmarcSpfResult { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Domain, self.domain.into_value()); map.insert_unchecked(Property::Scope, self.scope.into_value()); map.insert_unchecked(Property::Result, self.result.into_value()); map.insert_unchecked(Property::HumanResult, self.human_result.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DmarcSpfResult { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Domain) => self .domain .patch(pointer.with_validators(&[StringValidator::Domain]), value), Some(Property::Scope) => self.scope.patch(pointer, value), Some(Property::Result) => self.result.patch(pointer, value), Some(Property::HumanResult) => self.human_result.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DmarcTroubleshoot { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.remote_ip; if !value.is_valid() { errors.push(ValidationError::invalid(Property::RemoteIp, value)); } let value = &self.ehlo_domain; if value.is_empty() { errors.push(ValidationError::required(Property::EhloDomain)); } let value = &self.mail_from; if value.is_empty() { errors.push(ValidationError::required(Property::MailFrom)); } let value = &self.to; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::To)); } } if let Some(value) = &self.message { if value.is_empty() { errors.push(ValidationError::required(Property::Message)); } } let value = &self.spf_ehlo_domain; if value.is_empty() { errors.push(ValidationError::required(Property::SpfEhloDomain)); } let value = &self.spf_ehlo_result; value.validate(errors); let value = &self.spf_mail_from_domain; if value.is_empty() { errors.push(ValidationError::required(Property::SpfMailFromDomain)); } let value = &self.spf_mail_from_result; value.validate(errors); let value = &self.ip_rev_result; value.validate(errors); let value = &self.ip_rev_ptr; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::IpRevPtr)); } } let value = &self.dkim_results; for value in value.values() { value.validate(errors); } let value = &self.dkim2_result; value.validate(errors); let value = &self.arc_result; value.validate(errors); let value = &self.dmarc_result; value.validate(errors); errors.len() == neb } } impl Pickle for DmarcTroubleshoot { fn pickle(&self, out: &mut Vec) { self.remote_ip.pickle(out); self.ehlo_domain.pickle(out); self.mail_from.pickle(out); self.to.pickle(out); self.message.pickle(out); self.spf_ehlo_domain.pickle(out); self.spf_ehlo_result.pickle(out); self.spf_mail_from_domain.pickle(out); self.spf_mail_from_result.pickle(out); self.ip_rev_result.pickle(out); self.ip_rev_ptr.pickle(out); self.dkim_results.pickle(out); self.dkim_pass.pickle(out); self.dkim2_result.pickle(out); self.dkim2_pass.pickle(out); self.arc_result.pickle(out); self.dmarc_result.pickle(out); self.dmarc_pass.pickle(out); self.dmarc_policy.pickle(out); self.elapsed.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.remote_ip = Pickle::unpickle(stream)?; this.ehlo_domain = Pickle::unpickle(stream)?; this.mail_from = Pickle::unpickle(stream)?; this.to = Pickle::unpickle(stream)?; this.message = Pickle::unpickle(stream)?; this.spf_ehlo_domain = Pickle::unpickle(stream)?; this.spf_ehlo_result = Pickle::unpickle(stream)?; this.spf_mail_from_domain = Pickle::unpickle(stream)?; this.spf_mail_from_result = Pickle::unpickle(stream)?; this.ip_rev_result = Pickle::unpickle(stream)?; this.ip_rev_ptr = Pickle::unpickle(stream)?; this.dkim_results = Pickle::unpickle(stream)?; this.dkim_pass = Pickle::unpickle(stream)?; this.dkim2_result = Pickle::unpickle(stream)?; this.dkim2_pass = Pickle::unpickle(stream)?; this.arc_result = Pickle::unpickle(stream)?; this.dmarc_result = Pickle::unpickle(stream)?; this.dmarc_pass = Pickle::unpickle(stream)?; this.dmarc_policy = Pickle::unpickle(stream)?; this.elapsed = Pickle::unpickle(stream)?; Some(this) } } impl Default for DmarcTroubleshoot { fn default() -> Self { Self { remote_ip: Default::default(), ehlo_domain: Default::default(), mail_from: Default::default(), to: Default::default(), message: Default::default(), spf_ehlo_domain: Default::default(), spf_ehlo_result: Default::default(), spf_mail_from_domain: Default::default(), spf_mail_from_result: Default::default(), ip_rev_result: Default::default(), ip_rev_ptr: Default::default(), dkim_results: Default::default(), dkim_pass: false, dkim2_result: Default::default(), dkim2_pass: false, arc_result: Default::default(), dmarc_result: Default::default(), dmarc_pass: false, dmarc_policy: Default::default(), elapsed: Duration::from_millis(0), } } } impl IntoValue for DmarcTroubleshoot { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(22); map.insert_unchecked(Property::RemoteIp, self.remote_ip.into_value()); map.insert_unchecked(Property::EhloDomain, self.ehlo_domain.into_value()); map.insert_unchecked(Property::MailFrom, self.mail_from.into_value()); map.insert_unchecked(Property::To, self.to.into_value()); map.insert_unchecked(Property::Message, self.message.into_value()); map.insert_unchecked(Property::SpfEhloDomain, self.spf_ehlo_domain.into_value()); map.insert_unchecked(Property::SpfEhloResult, self.spf_ehlo_result.into_value()); map.insert_unchecked( Property::SpfMailFromDomain, self.spf_mail_from_domain.into_value(), ); map.insert_unchecked( Property::SpfMailFromResult, self.spf_mail_from_result.into_value(), ); map.insert_unchecked(Property::IpRevResult, self.ip_rev_result.into_value()); map.insert_unchecked(Property::IpRevPtr, self.ip_rev_ptr.into_value()); map.insert_unchecked(Property::DkimResults, self.dkim_results.into_value()); map.insert_unchecked(Property::DkimPass, self.dkim_pass.into_value()); map.insert_unchecked(Property::Dkim2Result, self.dkim2_result.into_value()); map.insert_unchecked(Property::Dkim2Pass, self.dkim2_pass.into_value()); map.insert_unchecked(Property::ArcResult, self.arc_result.into_value()); map.insert_unchecked(Property::DmarcResult, self.dmarc_result.into_value()); map.insert_unchecked(Property::DmarcPass, self.dmarc_pass.into_value()); map.insert_unchecked(Property::DmarcPolicy, self.dmarc_policy.into_value()); map.insert_unchecked(Property::Elapsed, self.elapsed.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DmarcTroubleshoot { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::RemoteIp) => self.remote_ip.patch(pointer, value), Some(Property::EhloDomain) => self.ehlo_domain.patch(pointer, value), Some(Property::MailFrom) => self .mail_from .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::To) => self .to .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::Message) => self.message.patch(pointer, value), Some(Property::SpfEhloDomain) => self.spf_ehlo_domain.patch(pointer, value), Some(Property::SpfEhloResult) => pointer.assert_server_set(), Some(Property::SpfMailFromDomain) => self.spf_mail_from_domain.patch(pointer, value), Some(Property::SpfMailFromResult) => pointer.assert_server_set(), Some(Property::IpRevResult) => pointer.assert_server_set(), Some(Property::IpRevPtr) => pointer.assert_server_set(), Some(Property::DkimResults) => pointer.assert_server_set(), Some(Property::DkimPass) => pointer.assert_server_set(), Some(Property::Dkim2Result) => pointer.assert_server_set(), Some(Property::Dkim2Pass) => pointer.assert_server_set(), Some(Property::ArcResult) => pointer.assert_server_set(), Some(Property::DmarcResult) => pointer.assert_server_set(), Some(Property::DmarcPass) => pointer.assert_server_set(), Some(Property::DmarcPolicy) => pointer.assert_server_set(), Some(Property::Elapsed) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DmarcTroubleshootAuthResult { fn validate(&self, errors: &mut Vec) -> bool { match self { DmarcTroubleshootAuthResult::Pass => true, DmarcTroubleshootAuthResult::Fail(inner) => inner.validate(errors), DmarcTroubleshootAuthResult::SoftFail(inner) => inner.validate(errors), DmarcTroubleshootAuthResult::TempError(inner) => inner.validate(errors), DmarcTroubleshootAuthResult::PermError(inner) => inner.validate(errors), DmarcTroubleshootAuthResult::Neutral(inner) => inner.validate(errors), DmarcTroubleshootAuthResult::None => true, } } } impl Default for DmarcTroubleshootAuthResult { fn default() -> Self { DmarcTroubleshootAuthResult::Pass } } impl Pickle for DmarcTroubleshootAuthResult { fn pickle(&self, out: &mut Vec) { match self { DmarcTroubleshootAuthResult::Pass => { 0u16.pickle(out); } DmarcTroubleshootAuthResult::Fail(inner) => { 1u16.pickle(out); inner.pickle(out); } DmarcTroubleshootAuthResult::SoftFail(inner) => { 2u16.pickle(out); inner.pickle(out); } DmarcTroubleshootAuthResult::TempError(inner) => { 3u16.pickle(out); inner.pickle(out); } DmarcTroubleshootAuthResult::PermError(inner) => { 4u16.pickle(out); inner.pickle(out); } DmarcTroubleshootAuthResult::Neutral(inner) => { 5u16.pickle(out); inner.pickle(out); } DmarcTroubleshootAuthResult::None => { 6u16.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(DmarcTroubleshootAuthResult::Pass), 1 => Pickle::unpickle(stream).map(DmarcTroubleshootAuthResult::Fail), 2 => Pickle::unpickle(stream).map(DmarcTroubleshootAuthResult::SoftFail), 3 => Pickle::unpickle(stream).map(DmarcTroubleshootAuthResult::TempError), 4 => Pickle::unpickle(stream).map(DmarcTroubleshootAuthResult::PermError), 5 => Pickle::unpickle(stream).map(DmarcTroubleshootAuthResult::Neutral), 6 => Some(DmarcTroubleshootAuthResult::None), _ => None, } } } impl IntoValue for DmarcTroubleshootAuthResult { fn into_value(self) -> JmapValue<'static> { match self { DmarcTroubleshootAuthResult::Pass => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Pass".into())); JmapValue::Object(obj) } DmarcTroubleshootAuthResult::Fail(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Fail".into())); obj } DmarcTroubleshootAuthResult::SoftFail(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("SoftFail".into())); obj } DmarcTroubleshootAuthResult::TempError(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("TempError".into())); obj } DmarcTroubleshootAuthResult::PermError(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("PermError".into())); obj } DmarcTroubleshootAuthResult::Neutral(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Neutral".into())); obj } DmarcTroubleshootAuthResult::None => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("None".into())); JmapValue::Object(obj) } } } } impl RegistryJsonPatch for DmarcTroubleshootAuthResult { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { DmarcTroubleshootAuthResultType::Pass => *self = DmarcTroubleshootAuthResult::Pass, DmarcTroubleshootAuthResultType::Fail => { *self = DmarcTroubleshootAuthResult::Fail(Default::default()) } DmarcTroubleshootAuthResultType::SoftFail => { *self = DmarcTroubleshootAuthResult::SoftFail(Default::default()) } DmarcTroubleshootAuthResultType::TempError => { *self = DmarcTroubleshootAuthResult::TempError(Default::default()) } DmarcTroubleshootAuthResultType::PermError => { *self = DmarcTroubleshootAuthResult::PermError(Default::default()) } DmarcTroubleshootAuthResultType::Neutral => { *self = DmarcTroubleshootAuthResult::Neutral(Default::default()) } DmarcTroubleshootAuthResultType::None => *self = DmarcTroubleshootAuthResult::None, } } match self { DmarcTroubleshootAuthResult::Pass => pointer.assert_eof(), DmarcTroubleshootAuthResult::Fail(inner) => inner.patch(pointer, value), DmarcTroubleshootAuthResult::SoftFail(inner) => inner.patch(pointer, value), DmarcTroubleshootAuthResult::TempError(inner) => inner.patch(pointer, value), DmarcTroubleshootAuthResult::PermError(inner) => inner.patch(pointer, value), DmarcTroubleshootAuthResult::Neutral(inner) => inner.patch(pointer, value), DmarcTroubleshootAuthResult::None => pointer.assert_eof(), } } } impl DmarcTroubleshootAuthResult { pub fn object_type(&self) -> DmarcTroubleshootAuthResultType { match self { DmarcTroubleshootAuthResult::Pass => DmarcTroubleshootAuthResultType::Pass, DmarcTroubleshootAuthResult::Fail(_) => DmarcTroubleshootAuthResultType::Fail, DmarcTroubleshootAuthResult::SoftFail(_) => DmarcTroubleshootAuthResultType::SoftFail, DmarcTroubleshootAuthResult::TempError(_) => DmarcTroubleshootAuthResultType::TempError, DmarcTroubleshootAuthResult::PermError(_) => DmarcTroubleshootAuthResultType::PermError, DmarcTroubleshootAuthResult::Neutral(_) => DmarcTroubleshootAuthResultType::Neutral, DmarcTroubleshootAuthResult::None => DmarcTroubleshootAuthResultType::None, } } } impl DmarcTroubleshootDetails { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.details { if value.is_empty() { errors.push(ValidationError::required(Property::Details)); } } errors.len() == neb } } impl Pickle for DmarcTroubleshootDetails { fn pickle(&self, out: &mut Vec) { self.details.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.details = Pickle::unpickle(stream)?; Some(this) } } impl Default for DmarcTroubleshootDetails { fn default() -> Self { Self { details: Default::default(), } } } impl IntoValue for DmarcTroubleshootDetails { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Details, self.details.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DmarcTroubleshootDetails { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Details) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsCustomResolver { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.address; if !value.is_valid() { errors.push(ValidationError::invalid(Property::Address, value)); } let value = &self.port; if *value < 1 { errors.push(ValidationError::min_value(Property::Port, 1)); } if *value > 65535 { errors.push(ValidationError::max_value(Property::Port, 65535)); } errors.len() == neb } } impl Pickle for DnsCustomResolver { fn pickle(&self, out: &mut Vec) { self.protocol.pickle(out); self.address.pickle(out); self.port.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.protocol = Pickle::unpickle(stream)?; this.address = Pickle::unpickle(stream)?; this.port = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsCustomResolver { fn default() -> Self { Self { protocol: DnsResolverProtocol::Udp, address: IpAddr::from_str("127.0.0.1").unwrap(), port: 53u64, } } } impl IntoValue for DnsCustomResolver { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::Protocol, self.protocol.into_value()); map.insert_unchecked(Property::Address, self.address.into_value()); map.insert_unchecked(Property::Port, self.port.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsCustomResolver { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Protocol) => self.protocol.patch(pointer, value), Some(Property::Address) => self .address .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Port) => self.port.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsManagement { fn validate(&self, errors: &mut Vec) -> bool { match self { DnsManagement::Manual => true, DnsManagement::Automatic(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { DnsManagement::Manual => {} DnsManagement::Automatic(object) => { object.index(i); } } } } impl Default for DnsManagement { fn default() -> Self { DnsManagement::Manual } } impl Pickle for DnsManagement { fn pickle(&self, out: &mut Vec) { match self { DnsManagement::Manual => { 0u16.pickle(out); } DnsManagement::Automatic(inner) => { 1u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(DnsManagement::Manual), 1 => Pickle::unpickle(stream).map(DnsManagement::Automatic), _ => None, } } } impl IntoValue for DnsManagement { fn into_value(self) -> JmapValue<'static> { match self { DnsManagement::Manual => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Manual".into())); JmapValue::Object(obj) } DnsManagement::Automatic(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Automatic".into())); obj } } } } impl RegistryJsonPatch for DnsManagement { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { DnsManagementType::Manual => *self = DnsManagement::Manual, DnsManagementType::Automatic => { *self = DnsManagement::Automatic(Default::default()) } } } match self { DnsManagement::Manual => pointer.assert_eof(), DnsManagement::Automatic(inner) => inner.patch(pointer, value), } } } impl DnsManagement { pub fn object_type(&self) -> DnsManagementType { match self { DnsManagement::Manual => DnsManagementType::Manual, DnsManagement::Automatic(_) => DnsManagementType::Automatic, } } } impl DnsManagementProperties { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.dns_server_id; if !value.is_valid() { errors.push(ValidationError::required(Property::DnsServerId)); } if let Some(value) = &self.origin { if value.is_empty() { errors.push(ValidationError::required(Property::Origin)); } } let value = &self.publish_records; if value.len() < 1 { errors.push(ValidationError::min_items(Property::PublishRecords, 1)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::DnsServer, self.dns_server_id.into(), None); } } impl Pickle for DnsManagementProperties { fn pickle(&self, out: &mut Vec) { self.dns_server_id.pickle(out); self.origin.pickle(out); self.publish_records.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.dns_server_id = Pickle::unpickle(stream)?; this.origin = Pickle::unpickle(stream)?; this.publish_records = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsManagementProperties { fn default() -> Self { Self { dns_server_id: Default::default(), origin: Default::default(), publish_records: Map::new(vec![ DnsRecordType::Dkim, DnsRecordType::Spf, DnsRecordType::Mx, DnsRecordType::Dmarc, DnsRecordType::Srv, DnsRecordType::MtaSts, DnsRecordType::TlsRpt, DnsRecordType::Caa, DnsRecordType::AutoConfig, DnsRecordType::AutoConfigLegacy, DnsRecordType::AutoDiscover, ]), } } } impl IntoValue for DnsManagementProperties { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::DnsServerId, self.dns_server_id.into_value()); map.insert_unchecked(Property::Origin, self.origin.into_value()); map.insert_unchecked(Property::PublishRecords, self.publish_records.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsManagementProperties { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::DnsServerId) => self.dns_server_id.patch(pointer, value), Some(Property::Origin) => self .origin .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::PublishRecords) => self.publish_records.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for DnsResolver { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::DnsResolver; fn validate(&self, errors: &mut Vec) -> bool { match self { DnsResolver::System(inner) => inner.validate(errors), DnsResolver::Custom(inner) => inner.validate(errors), DnsResolver::Cloudflare(inner) => inner.validate(errors), DnsResolver::Quad9(inner) => inner.validate(errors), DnsResolver::Google(inner) => inner.validate(errors), } } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Default for DnsResolver { fn default() -> Self { DnsResolver::System(Default::default()) } } impl Pickle for DnsResolver { fn pickle(&self, out: &mut Vec) { match self { DnsResolver::System(inner) => { 0u16.pickle(out); inner.pickle(out); } DnsResolver::Custom(inner) => { 1u16.pickle(out); inner.pickle(out); } DnsResolver::Cloudflare(inner) => { 2u16.pickle(out); inner.pickle(out); } DnsResolver::Quad9(inner) => { 3u16.pickle(out); inner.pickle(out); } DnsResolver::Google(inner) => { 4u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(DnsResolver::System), 1 => Pickle::unpickle(stream).map(DnsResolver::Custom), 2 => Pickle::unpickle(stream).map(DnsResolver::Cloudflare), 3 => Pickle::unpickle(stream).map(DnsResolver::Quad9), 4 => Pickle::unpickle(stream).map(DnsResolver::Google), _ => None, } } } impl IntoValue for DnsResolver { fn into_value(self) -> JmapValue<'static> { match self { DnsResolver::System(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("System".into())); obj } DnsResolver::Custom(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Custom".into())); obj } DnsResolver::Cloudflare(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Cloudflare".into())); obj } DnsResolver::Quad9(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Quad9".into())); obj } DnsResolver::Google(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Google".into())); obj } } } } impl RegistryJsonPatch for DnsResolver { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { DnsResolverType::System => *self = DnsResolver::System(Default::default()), DnsResolverType::Custom => *self = DnsResolver::Custom(Default::default()), DnsResolverType::Cloudflare => *self = DnsResolver::Cloudflare(Default::default()), DnsResolverType::Quad9 => *self = DnsResolver::Quad9(Default::default()), DnsResolverType::Google => *self = DnsResolver::Google(Default::default()), } } match self { DnsResolver::System(inner) => inner.patch(pointer, value), DnsResolver::Custom(inner) => inner.patch(pointer, value), DnsResolver::Cloudflare(inner) => inner.patch(pointer, value), DnsResolver::Quad9(inner) => inner.patch(pointer, value), DnsResolver::Google(inner) => inner.patch(pointer, value), } } } impl DnsResolver { pub fn object_type(&self) -> DnsResolverType { match self { DnsResolver::System(_) => DnsResolverType::System, DnsResolver::Custom(_) => DnsResolverType::Custom, DnsResolver::Cloudflare(_) => DnsResolverType::Cloudflare, DnsResolver::Quad9(_) => DnsResolverType::Quad9, DnsResolver::Google(_) => DnsResolverType::Google, } } } impl DnsResolverCommon { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for DnsResolverCommon { fn pickle(&self, out: &mut Vec) { self.attempts.pickle(out); self.concurrency.pickle(out); self.enable_edns.pickle(out); self.preserve_intermediates.pickle(out); self.timeout.pickle(out); self.tcp_on_error.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.attempts = Pickle::unpickle(stream)?; this.concurrency = Pickle::unpickle(stream)?; this.enable_edns = Pickle::unpickle(stream)?; this.preserve_intermediates = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.tcp_on_error = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsResolverCommon { fn default() -> Self { Self { attempts: 2u64, concurrency: 2u64, enable_edns: true, preserve_intermediates: true, timeout: Duration::from_millis(5000), tcp_on_error: true, } } } impl IntoValue for DnsResolverCommon { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::Attempts, self.attempts.into_value()); map.insert_unchecked(Property::Concurrency, self.concurrency.into_value()); map.insert_unchecked(Property::EnableEdns, self.enable_edns.into_value()); map.insert_unchecked( Property::PreserveIntermediates, self.preserve_intermediates.into_value(), ); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::TcpOnError, self.tcp_on_error.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsResolverCommon { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Attempts) => self.attempts.patch(pointer, value), Some(Property::Concurrency) => self.concurrency.patch(pointer, value), Some(Property::EnableEdns) => self.enable_edns.patch(pointer, value), Some(Property::PreserveIntermediates) => { self.preserve_intermediates.patch(pointer, value) } Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::TcpOnError) => self.tcp_on_error.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsResolverCustom { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.servers; for value in value.values() { value.validate(errors); } if value.len() < 1 { errors.push(ValidationError::min_items(Property::Servers, 1)); } errors.len() == neb } } impl Pickle for DnsResolverCustom { fn pickle(&self, out: &mut Vec) { self.servers.pickle(out); self.attempts.pickle(out); self.concurrency.pickle(out); self.enable_edns.pickle(out); self.preserve_intermediates.pickle(out); self.timeout.pickle(out); self.tcp_on_error.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.servers = Pickle::unpickle(stream)?; this.attempts = Pickle::unpickle(stream)?; this.concurrency = Pickle::unpickle(stream)?; this.enable_edns = Pickle::unpickle(stream)?; this.preserve_intermediates = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.tcp_on_error = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsResolverCustom { fn default() -> Self { Self { servers: Default::default(), attempts: 2u64, concurrency: 2u64, enable_edns: true, preserve_intermediates: true, timeout: Duration::from_millis(5000), tcp_on_error: true, } } } impl IntoValue for DnsResolverCustom { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked(Property::Servers, self.servers.into_value()); map.insert_unchecked(Property::Attempts, self.attempts.into_value()); map.insert_unchecked(Property::Concurrency, self.concurrency.into_value()); map.insert_unchecked(Property::EnableEdns, self.enable_edns.into_value()); map.insert_unchecked( Property::PreserveIntermediates, self.preserve_intermediates.into_value(), ); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::TcpOnError, self.tcp_on_error.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsResolverCustom { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Servers) => self.servers.patch(pointer, value), Some(Property::Attempts) => self.attempts.patch(pointer, value), Some(Property::Concurrency) => self.concurrency.patch(pointer, value), Some(Property::EnableEdns) => self.enable_edns.patch(pointer, value), Some(Property::PreserveIntermediates) => { self.preserve_intermediates.patch(pointer, value) } Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::TcpOnError) => self.tcp_on_error.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsResolverTls { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for DnsResolverTls { fn pickle(&self, out: &mut Vec) { self.use_tls.pickle(out); self.attempts.pickle(out); self.concurrency.pickle(out); self.enable_edns.pickle(out); self.preserve_intermediates.pickle(out); self.timeout.pickle(out); self.tcp_on_error.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.use_tls = Pickle::unpickle(stream)?; this.attempts = Pickle::unpickle(stream)?; this.concurrency = Pickle::unpickle(stream)?; this.enable_edns = Pickle::unpickle(stream)?; this.preserve_intermediates = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.tcp_on_error = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsResolverTls { fn default() -> Self { Self { use_tls: true, attempts: 2u64, concurrency: 2u64, enable_edns: true, preserve_intermediates: true, timeout: Duration::from_millis(5000), tcp_on_error: true, } } } impl IntoValue for DnsResolverTls { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked(Property::UseTls, self.use_tls.into_value()); map.insert_unchecked(Property::Attempts, self.attempts.into_value()); map.insert_unchecked(Property::Concurrency, self.concurrency.into_value()); map.insert_unchecked(Property::EnableEdns, self.enable_edns.into_value()); map.insert_unchecked( Property::PreserveIntermediates, self.preserve_intermediates.into_value(), ); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::TcpOnError, self.tcp_on_error.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsResolverTls { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::UseTls) => self.use_tls.patch(pointer, value), Some(Property::Attempts) => self.attempts.patch(pointer, value), Some(Property::Concurrency) => self.concurrency.patch(pointer, value), Some(Property::EnableEdns) => self.enable_edns.patch(pointer, value), Some(Property::PreserveIntermediates) => { self.preserve_intermediates.patch(pointer, value) } Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::TcpOnError) => self.tcp_on_error.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for DnsServer { const FLAGS: u64 = OBJ_FILTER_TENANT; const VERSION: u8 = 1; const OBJECT: ObjectType = ObjectType::DnsServer; fn validate(&self, errors: &mut Vec) -> bool { match self { DnsServer::Tsig(inner) => inner.validate(errors), DnsServer::Deprecated1 => true, DnsServer::Cloudflare(inner) => inner.validate(errors), DnsServer::DigitalOcean(inner) => inner.validate(errors), DnsServer::DeSEC(inner) => inner.validate(errors), DnsServer::Ovh(inner) => inner.validate(errors), DnsServer::Bunny(inner) => inner.validate(errors), DnsServer::Porkbun(inner) => inner.validate(errors), DnsServer::Dnsimple(inner) => inner.validate(errors), DnsServer::Spaceship(inner) => inner.validate(errors), DnsServer::Route53(inner) => inner.validate(errors), DnsServer::GoogleCloudDns(inner) => inner.validate(errors), DnsServer::Alidns(inner) => inner.validate(errors), DnsServer::ArvanCloud(inner) => inner.validate(errors), DnsServer::Autodns(inner) => inner.validate(errors), DnsServer::AzureDns(inner) => inner.validate(errors), DnsServer::BaiduCloud(inner) => inner.validate(errors), DnsServer::BluecatV2(inner) => inner.validate(errors), DnsServer::ClouDns(inner) => inner.validate(errors), DnsServer::Constellix(inner) => inner.validate(errors), DnsServer::Cpanel(inner) => inner.validate(errors), DnsServer::Ddnss(inner) => inner.validate(errors), DnsServer::DnsMadeEasy(inner) => inner.validate(errors), DnsServer::Domeneshop(inner) => inner.validate(errors), DnsServer::Dreamhost(inner) => inner.validate(errors), DnsServer::DuckDns(inner) => inner.validate(errors), DnsServer::Dynu(inner) => inner.validate(errors), DnsServer::EasyDns(inner) => inner.validate(errors), DnsServer::EdgeDns(inner) => inner.validate(errors), DnsServer::Exoscale(inner) => inner.validate(errors), DnsServer::FreeMyIp(inner) => inner.validate(errors), DnsServer::GandiV5(inner) => inner.validate(errors), DnsServer::Gcore(inner) => inner.validate(errors), DnsServer::Glesys(inner) => inner.validate(errors), DnsServer::Godaddy(inner) => inner.validate(errors), DnsServer::Hetzner(inner) => inner.validate(errors), DnsServer::HostingDe(inner) => inner.validate(errors), DnsServer::Hostinger(inner) => inner.validate(errors), DnsServer::HuaweiCloud(inner) => inner.validate(errors), DnsServer::Hurricane(inner) => inner.validate(errors), DnsServer::IbmCloud(inner) => inner.validate(errors), DnsServer::Infoblox(inner) => inner.validate(errors), DnsServer::Infomaniak(inner) => inner.validate(errors), DnsServer::Inwx(inner) => inner.validate(errors), DnsServer::Ionos(inner) => inner.validate(errors), DnsServer::Ipv64(inner) => inner.validate(errors), DnsServer::Joker(inner) => inner.validate(errors), DnsServer::Lightsail(inner) => inner.validate(errors), DnsServer::Linode(inner) => inner.validate(errors), DnsServer::LuaDns(inner) => inner.validate(errors), DnsServer::MythicBeasts(inner) => inner.validate(errors), DnsServer::Namecheap(inner) => inner.validate(errors), DnsServer::NameDotCom(inner) => inner.validate(errors), DnsServer::NameSilo(inner) => inner.validate(errors), DnsServer::Netcup(inner) => inner.validate(errors), DnsServer::Netlify(inner) => inner.validate(errors), DnsServer::Nifcloud(inner) => inner.validate(errors), DnsServer::Ns1(inner) => inner.validate(errors), DnsServer::OracleCloud(inner) => inner.validate(errors), DnsServer::Plesk(inner) => inner.validate(errors), DnsServer::Safedns(inner) => inner.validate(errors), DnsServer::Scaleway(inner) => inner.validate(errors), DnsServer::TencentCloud(inner) => inner.validate(errors), DnsServer::Transip(inner) => inner.validate(errors), DnsServer::UltraDns(inner) => inner.validate(errors), DnsServer::Vercel(inner) => inner.validate(errors), DnsServer::Volcengine(inner) => inner.validate(errors), DnsServer::Vultr(inner) => inner.validate(errors), DnsServer::WebSupport(inner) => inner.validate(errors), DnsServer::YandexCloud(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { DnsServer::Tsig(object) => { object.index(i); } DnsServer::Deprecated1 => {} DnsServer::Cloudflare(object) => { object.index(i); } DnsServer::DigitalOcean(object) => { object.index(i); } DnsServer::DeSEC(object) => { object.index(i); } DnsServer::Ovh(object) => { object.index(i); } DnsServer::Bunny(object) => { object.index(i); } DnsServer::Porkbun(object) => { object.index(i); } DnsServer::Dnsimple(object) => { object.index(i); } DnsServer::Spaceship(object) => { object.index(i); } DnsServer::Route53(object) => { object.index(i); } DnsServer::GoogleCloudDns(object) => { object.index(i); } DnsServer::Alidns(object) => { object.index(i); } DnsServer::ArvanCloud(object) => { object.index(i); } DnsServer::Autodns(object) => { object.index(i); } DnsServer::AzureDns(object) => { object.index(i); } DnsServer::BaiduCloud(object) => { object.index(i); } DnsServer::BluecatV2(object) => { object.index(i); } DnsServer::ClouDns(object) => { object.index(i); } DnsServer::Constellix(object) => { object.index(i); } DnsServer::Cpanel(object) => { object.index(i); } DnsServer::Ddnss(object) => { object.index(i); } DnsServer::DnsMadeEasy(object) => { object.index(i); } DnsServer::Domeneshop(object) => { object.index(i); } DnsServer::Dreamhost(object) => { object.index(i); } DnsServer::DuckDns(object) => { object.index(i); } DnsServer::Dynu(object) => { object.index(i); } DnsServer::EasyDns(object) => { object.index(i); } DnsServer::EdgeDns(object) => { object.index(i); } DnsServer::Exoscale(object) => { object.index(i); } DnsServer::FreeMyIp(object) => { object.index(i); } DnsServer::GandiV5(object) => { object.index(i); } DnsServer::Gcore(object) => { object.index(i); } DnsServer::Glesys(object) => { object.index(i); } DnsServer::Godaddy(object) => { object.index(i); } DnsServer::Hetzner(object) => { object.index(i); } DnsServer::HostingDe(object) => { object.index(i); } DnsServer::Hostinger(object) => { object.index(i); } DnsServer::HuaweiCloud(object) => { object.index(i); } DnsServer::Hurricane(object) => { object.index(i); } DnsServer::IbmCloud(object) => { object.index(i); } DnsServer::Infoblox(object) => { object.index(i); } DnsServer::Infomaniak(object) => { object.index(i); } DnsServer::Inwx(object) => { object.index(i); } DnsServer::Ionos(object) => { object.index(i); } DnsServer::Ipv64(object) => { object.index(i); } DnsServer::Joker(object) => { object.index(i); } DnsServer::Lightsail(object) => { object.index(i); } DnsServer::Linode(object) => { object.index(i); } DnsServer::LuaDns(object) => { object.index(i); } DnsServer::MythicBeasts(object) => { object.index(i); } DnsServer::Namecheap(object) => { object.index(i); } DnsServer::NameDotCom(object) => { object.index(i); } DnsServer::NameSilo(object) => { object.index(i); } DnsServer::Netcup(object) => { object.index(i); } DnsServer::Netlify(object) => { object.index(i); } DnsServer::Nifcloud(object) => { object.index(i); } DnsServer::Ns1(object) => { object.index(i); } DnsServer::OracleCloud(object) => { object.index(i); } DnsServer::Plesk(object) => { object.index(i); } DnsServer::Safedns(object) => { object.index(i); } DnsServer::Scaleway(object) => { object.index(i); } DnsServer::TencentCloud(object) => { object.index(i); } DnsServer::Transip(object) => { object.index(i); } DnsServer::UltraDns(object) => { object.index(i); } DnsServer::Vercel(object) => { object.index(i); } DnsServer::Volcengine(object) => { object.index(i); } DnsServer::Vultr(object) => { object.index(i); } DnsServer::WebSupport(object) => { object.index(i); } DnsServer::YandexCloud(object) => { object.index(i); } } } } impl Default for DnsServer { fn default() -> Self { DnsServer::Tsig(Default::default()) } } impl Pickle for DnsServer { fn pickle(&self, out: &mut Vec) { match self { DnsServer::Tsig(inner) => { 0u16.pickle(out); inner.pickle(out); } DnsServer::Deprecated1 => { 1u16.pickle(out); } DnsServer::Cloudflare(inner) => { 2u16.pickle(out); inner.pickle(out); } DnsServer::DigitalOcean(inner) => { 3u16.pickle(out); inner.pickle(out); } DnsServer::DeSEC(inner) => { 4u16.pickle(out); inner.pickle(out); } DnsServer::Ovh(inner) => { 5u16.pickle(out); inner.pickle(out); } DnsServer::Bunny(inner) => { 6u16.pickle(out); inner.pickle(out); } DnsServer::Porkbun(inner) => { 7u16.pickle(out); inner.pickle(out); } DnsServer::Dnsimple(inner) => { 8u16.pickle(out); inner.pickle(out); } DnsServer::Spaceship(inner) => { 9u16.pickle(out); inner.pickle(out); } DnsServer::Route53(inner) => { 10u16.pickle(out); inner.pickle(out); } DnsServer::GoogleCloudDns(inner) => { 11u16.pickle(out); inner.pickle(out); } DnsServer::Alidns(inner) => { 12u16.pickle(out); inner.pickle(out); } DnsServer::ArvanCloud(inner) => { 13u16.pickle(out); inner.pickle(out); } DnsServer::Autodns(inner) => { 14u16.pickle(out); inner.pickle(out); } DnsServer::AzureDns(inner) => { 15u16.pickle(out); inner.pickle(out); } DnsServer::BaiduCloud(inner) => { 16u16.pickle(out); inner.pickle(out); } DnsServer::BluecatV2(inner) => { 17u16.pickle(out); inner.pickle(out); } DnsServer::ClouDns(inner) => { 18u16.pickle(out); inner.pickle(out); } DnsServer::Constellix(inner) => { 19u16.pickle(out); inner.pickle(out); } DnsServer::Cpanel(inner) => { 20u16.pickle(out); inner.pickle(out); } DnsServer::Ddnss(inner) => { 21u16.pickle(out); inner.pickle(out); } DnsServer::DnsMadeEasy(inner) => { 22u16.pickle(out); inner.pickle(out); } DnsServer::Domeneshop(inner) => { 23u16.pickle(out); inner.pickle(out); } DnsServer::Dreamhost(inner) => { 24u16.pickle(out); inner.pickle(out); } DnsServer::DuckDns(inner) => { 25u16.pickle(out); inner.pickle(out); } DnsServer::Dynu(inner) => { 26u16.pickle(out); inner.pickle(out); } DnsServer::EasyDns(inner) => { 27u16.pickle(out); inner.pickle(out); } DnsServer::EdgeDns(inner) => { 28u16.pickle(out); inner.pickle(out); } DnsServer::Exoscale(inner) => { 29u16.pickle(out); inner.pickle(out); } DnsServer::FreeMyIp(inner) => { 30u16.pickle(out); inner.pickle(out); } DnsServer::GandiV5(inner) => { 31u16.pickle(out); inner.pickle(out); } DnsServer::Gcore(inner) => { 32u16.pickle(out); inner.pickle(out); } DnsServer::Glesys(inner) => { 33u16.pickle(out); inner.pickle(out); } DnsServer::Godaddy(inner) => { 34u16.pickle(out); inner.pickle(out); } DnsServer::Hetzner(inner) => { 35u16.pickle(out); inner.pickle(out); } DnsServer::HostingDe(inner) => { 36u16.pickle(out); inner.pickle(out); } DnsServer::Hostinger(inner) => { 37u16.pickle(out); inner.pickle(out); } DnsServer::HuaweiCloud(inner) => { 38u16.pickle(out); inner.pickle(out); } DnsServer::Hurricane(inner) => { 39u16.pickle(out); inner.pickle(out); } DnsServer::IbmCloud(inner) => { 40u16.pickle(out); inner.pickle(out); } DnsServer::Infoblox(inner) => { 41u16.pickle(out); inner.pickle(out); } DnsServer::Infomaniak(inner) => { 42u16.pickle(out); inner.pickle(out); } DnsServer::Inwx(inner) => { 43u16.pickle(out); inner.pickle(out); } DnsServer::Ionos(inner) => { 44u16.pickle(out); inner.pickle(out); } DnsServer::Ipv64(inner) => { 45u16.pickle(out); inner.pickle(out); } DnsServer::Joker(inner) => { 46u16.pickle(out); inner.pickle(out); } DnsServer::Lightsail(inner) => { 47u16.pickle(out); inner.pickle(out); } DnsServer::Linode(inner) => { 48u16.pickle(out); inner.pickle(out); } DnsServer::LuaDns(inner) => { 49u16.pickle(out); inner.pickle(out); } DnsServer::MythicBeasts(inner) => { 50u16.pickle(out); inner.pickle(out); } DnsServer::Namecheap(inner) => { 51u16.pickle(out); inner.pickle(out); } DnsServer::NameDotCom(inner) => { 52u16.pickle(out); inner.pickle(out); } DnsServer::NameSilo(inner) => { 53u16.pickle(out); inner.pickle(out); } DnsServer::Netcup(inner) => { 54u16.pickle(out); inner.pickle(out); } DnsServer::Netlify(inner) => { 55u16.pickle(out); inner.pickle(out); } DnsServer::Nifcloud(inner) => { 56u16.pickle(out); inner.pickle(out); } DnsServer::Ns1(inner) => { 57u16.pickle(out); inner.pickle(out); } DnsServer::OracleCloud(inner) => { 58u16.pickle(out); inner.pickle(out); } DnsServer::Plesk(inner) => { 59u16.pickle(out); inner.pickle(out); } DnsServer::Safedns(inner) => { 60u16.pickle(out); inner.pickle(out); } DnsServer::Scaleway(inner) => { 61u16.pickle(out); inner.pickle(out); } DnsServer::TencentCloud(inner) => { 62u16.pickle(out); inner.pickle(out); } DnsServer::Transip(inner) => { 63u16.pickle(out); inner.pickle(out); } DnsServer::UltraDns(inner) => { 64u16.pickle(out); inner.pickle(out); } DnsServer::Vercel(inner) => { 65u16.pickle(out); inner.pickle(out); } DnsServer::Volcengine(inner) => { 66u16.pickle(out); inner.pickle(out); } DnsServer::Vultr(inner) => { 67u16.pickle(out); inner.pickle(out); } DnsServer::WebSupport(inner) => { 68u16.pickle(out); inner.pickle(out); } DnsServer::YandexCloud(inner) => { 69u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(DnsServer::Tsig), 1 => Some(DnsServer::Deprecated1), 2 => Pickle::unpickle(stream).map(DnsServer::Cloudflare), 3 => Pickle::unpickle(stream).map(DnsServer::DigitalOcean), 4 => Pickle::unpickle(stream).map(DnsServer::DeSEC), 5 => Pickle::unpickle(stream).map(DnsServer::Ovh), 6 => Pickle::unpickle(stream).map(DnsServer::Bunny), 7 => Pickle::unpickle(stream).map(DnsServer::Porkbun), 8 => Pickle::unpickle(stream).map(DnsServer::Dnsimple), 9 => Pickle::unpickle(stream).map(DnsServer::Spaceship), 10 => Pickle::unpickle(stream).map(DnsServer::Route53), 11 => Pickle::unpickle(stream).map(DnsServer::GoogleCloudDns), 12 => Pickle::unpickle(stream).map(DnsServer::Alidns), 13 => Pickle::unpickle(stream).map(DnsServer::ArvanCloud), 14 => Pickle::unpickle(stream).map(DnsServer::Autodns), 15 => Pickle::unpickle(stream).map(DnsServer::AzureDns), 16 => Pickle::unpickle(stream).map(DnsServer::BaiduCloud), 17 => Pickle::unpickle(stream).map(DnsServer::BluecatV2), 18 => Pickle::unpickle(stream).map(DnsServer::ClouDns), 19 => Pickle::unpickle(stream).map(DnsServer::Constellix), 20 => Pickle::unpickle(stream).map(DnsServer::Cpanel), 21 => Pickle::unpickle(stream).map(DnsServer::Ddnss), 22 => Pickle::unpickle(stream).map(DnsServer::DnsMadeEasy), 23 => Pickle::unpickle(stream).map(DnsServer::Domeneshop), 24 => Pickle::unpickle(stream).map(DnsServer::Dreamhost), 25 => Pickle::unpickle(stream).map(DnsServer::DuckDns), 26 => Pickle::unpickle(stream).map(DnsServer::Dynu), 27 => Pickle::unpickle(stream).map(DnsServer::EasyDns), 28 => Pickle::unpickle(stream).map(DnsServer::EdgeDns), 29 => Pickle::unpickle(stream).map(DnsServer::Exoscale), 30 => Pickle::unpickle(stream).map(DnsServer::FreeMyIp), 31 => Pickle::unpickle(stream).map(DnsServer::GandiV5), 32 => Pickle::unpickle(stream).map(DnsServer::Gcore), 33 => Pickle::unpickle(stream).map(DnsServer::Glesys), 34 => Pickle::unpickle(stream).map(DnsServer::Godaddy), 35 => Pickle::unpickle(stream).map(DnsServer::Hetzner), 36 => Pickle::unpickle(stream).map(DnsServer::HostingDe), 37 => Pickle::unpickle(stream).map(DnsServer::Hostinger), 38 => Pickle::unpickle(stream).map(DnsServer::HuaweiCloud), 39 => Pickle::unpickle(stream).map(DnsServer::Hurricane), 40 => Pickle::unpickle(stream).map(DnsServer::IbmCloud), 41 => Pickle::unpickle(stream).map(DnsServer::Infoblox), 42 => Pickle::unpickle(stream).map(DnsServer::Infomaniak), 43 => Pickle::unpickle(stream).map(DnsServer::Inwx), 44 => Pickle::unpickle(stream).map(DnsServer::Ionos), 45 => Pickle::unpickle(stream).map(DnsServer::Ipv64), 46 => Pickle::unpickle(stream).map(DnsServer::Joker), 47 => Pickle::unpickle(stream).map(DnsServer::Lightsail), 48 => Pickle::unpickle(stream).map(DnsServer::Linode), 49 => Pickle::unpickle(stream).map(DnsServer::LuaDns), 50 => Pickle::unpickle(stream).map(DnsServer::MythicBeasts), 51 => Pickle::unpickle(stream).map(DnsServer::Namecheap), 52 => Pickle::unpickle(stream).map(DnsServer::NameDotCom), 53 => Pickle::unpickle(stream).map(DnsServer::NameSilo), 54 => Pickle::unpickle(stream).map(DnsServer::Netcup), 55 => Pickle::unpickle(stream).map(DnsServer::Netlify), 56 => Pickle::unpickle(stream).map(DnsServer::Nifcloud), 57 => Pickle::unpickle(stream).map(DnsServer::Ns1), 58 => Pickle::unpickle(stream).map(DnsServer::OracleCloud), 59 => Pickle::unpickle(stream).map(DnsServer::Plesk), 60 => Pickle::unpickle(stream).map(DnsServer::Safedns), 61 => Pickle::unpickle(stream).map(DnsServer::Scaleway), 62 => Pickle::unpickle(stream).map(DnsServer::TencentCloud), 63 => Pickle::unpickle(stream).map(DnsServer::Transip), 64 => Pickle::unpickle(stream).map(DnsServer::UltraDns), 65 => Pickle::unpickle(stream).map(DnsServer::Vercel), 66 => Pickle::unpickle(stream).map(DnsServer::Volcengine), 67 => Pickle::unpickle(stream).map(DnsServer::Vultr), 68 => Pickle::unpickle(stream).map(DnsServer::WebSupport), 69 => Pickle::unpickle(stream).map(DnsServer::YandexCloud), _ => None, } } } impl IntoValue for DnsServer { fn into_value(self) -> JmapValue<'static> { match self { DnsServer::Tsig(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Tsig".into())); obj } DnsServer::Deprecated1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Deprecated1".into())); JmapValue::Object(obj) } DnsServer::Cloudflare(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Cloudflare".into())); obj } DnsServer::DigitalOcean(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("DigitalOcean".into())); obj } DnsServer::DeSEC(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("DeSEC".into())); obj } DnsServer::Ovh(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ovh".into())); obj } DnsServer::Bunny(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Bunny".into())); obj } DnsServer::Porkbun(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Porkbun".into())); obj } DnsServer::Dnsimple(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Dnsimple".into())); obj } DnsServer::Spaceship(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Spaceship".into())); obj } DnsServer::Route53(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Route53".into())); obj } DnsServer::GoogleCloudDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("GoogleCloudDns".into())); obj } DnsServer::Alidns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Alidns".into())); obj } DnsServer::ArvanCloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("ArvanCloud".into())); obj } DnsServer::Autodns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Autodns".into())); obj } DnsServer::AzureDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("AzureDns".into())); obj } DnsServer::BaiduCloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("BaiduCloud".into())); obj } DnsServer::BluecatV2(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("BluecatV2".into())); obj } DnsServer::ClouDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("ClouDns".into())); obj } DnsServer::Constellix(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Constellix".into())); obj } DnsServer::Cpanel(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Cpanel".into())); obj } DnsServer::Ddnss(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ddnss".into())); obj } DnsServer::DnsMadeEasy(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("DnsMadeEasy".into())); obj } DnsServer::Domeneshop(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Domeneshop".into())); obj } DnsServer::Dreamhost(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Dreamhost".into())); obj } DnsServer::DuckDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("DuckDns".into())); obj } DnsServer::Dynu(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Dynu".into())); obj } DnsServer::EasyDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("EasyDns".into())); obj } DnsServer::EdgeDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("EdgeDns".into())); obj } DnsServer::Exoscale(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Exoscale".into())); obj } DnsServer::FreeMyIp(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("FreeMyIp".into())); obj } DnsServer::GandiV5(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("GandiV5".into())); obj } DnsServer::Gcore(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Gcore".into())); obj } DnsServer::Glesys(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Glesys".into())); obj } DnsServer::Godaddy(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Godaddy".into())); obj } DnsServer::Hetzner(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Hetzner".into())); obj } DnsServer::HostingDe(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("HostingDe".into())); obj } DnsServer::Hostinger(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Hostinger".into())); obj } DnsServer::HuaweiCloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("HuaweiCloud".into())); obj } DnsServer::Hurricane(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Hurricane".into())); obj } DnsServer::IbmCloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("IbmCloud".into())); obj } DnsServer::Infoblox(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Infoblox".into())); obj } DnsServer::Infomaniak(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Infomaniak".into())); obj } DnsServer::Inwx(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Inwx".into())); obj } DnsServer::Ionos(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ionos".into())); obj } DnsServer::Ipv64(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ipv64".into())); obj } DnsServer::Joker(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Joker".into())); obj } DnsServer::Lightsail(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Lightsail".into())); obj } DnsServer::Linode(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Linode".into())); obj } DnsServer::LuaDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("LuaDns".into())); obj } DnsServer::MythicBeasts(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("MythicBeasts".into())); obj } DnsServer::Namecheap(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Namecheap".into())); obj } DnsServer::NameDotCom(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("NameDotCom".into())); obj } DnsServer::NameSilo(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("NameSilo".into())); obj } DnsServer::Netcup(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Netcup".into())); obj } DnsServer::Netlify(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Netlify".into())); obj } DnsServer::Nifcloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Nifcloud".into())); obj } DnsServer::Ns1(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ns1".into())); obj } DnsServer::OracleCloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("OracleCloud".into())); obj } DnsServer::Plesk(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Plesk".into())); obj } DnsServer::Safedns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Safedns".into())); obj } DnsServer::Scaleway(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Scaleway".into())); obj } DnsServer::TencentCloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("TencentCloud".into())); obj } DnsServer::Transip(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Transip".into())); obj } DnsServer::UltraDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("UltraDns".into())); obj } DnsServer::Vercel(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Vercel".into())); obj } DnsServer::Volcengine(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Volcengine".into())); obj } DnsServer::Vultr(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Vultr".into())); obj } DnsServer::WebSupport(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("WebSupport".into())); obj } DnsServer::YandexCloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("YandexCloud".into())); obj } } } } impl RegistryJsonPatch for DnsServer { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { DnsServerType::Tsig => *self = DnsServer::Tsig(Default::default()), DnsServerType::Deprecated1 => *self = DnsServer::Deprecated1, DnsServerType::Cloudflare => *self = DnsServer::Cloudflare(Default::default()), DnsServerType::DigitalOcean => *self = DnsServer::DigitalOcean(Default::default()), DnsServerType::DeSEC => *self = DnsServer::DeSEC(Default::default()), DnsServerType::Ovh => *self = DnsServer::Ovh(Default::default()), DnsServerType::Bunny => *self = DnsServer::Bunny(Default::default()), DnsServerType::Porkbun => *self = DnsServer::Porkbun(Default::default()), DnsServerType::Dnsimple => *self = DnsServer::Dnsimple(Default::default()), DnsServerType::Spaceship => *self = DnsServer::Spaceship(Default::default()), DnsServerType::Route53 => *self = DnsServer::Route53(Default::default()), DnsServerType::GoogleCloudDns => { *self = DnsServer::GoogleCloudDns(Default::default()) } DnsServerType::Alidns => *self = DnsServer::Alidns(Default::default()), DnsServerType::ArvanCloud => *self = DnsServer::ArvanCloud(Default::default()), DnsServerType::Autodns => *self = DnsServer::Autodns(Default::default()), DnsServerType::AzureDns => *self = DnsServer::AzureDns(Default::default()), DnsServerType::BaiduCloud => *self = DnsServer::BaiduCloud(Default::default()), DnsServerType::BluecatV2 => *self = DnsServer::BluecatV2(Default::default()), DnsServerType::ClouDns => *self = DnsServer::ClouDns(Default::default()), DnsServerType::Constellix => *self = DnsServer::Constellix(Default::default()), DnsServerType::Cpanel => *self = DnsServer::Cpanel(Default::default()), DnsServerType::Ddnss => *self = DnsServer::Ddnss(Default::default()), DnsServerType::DnsMadeEasy => *self = DnsServer::DnsMadeEasy(Default::default()), DnsServerType::Domeneshop => *self = DnsServer::Domeneshop(Default::default()), DnsServerType::Dreamhost => *self = DnsServer::Dreamhost(Default::default()), DnsServerType::DuckDns => *self = DnsServer::DuckDns(Default::default()), DnsServerType::Dynu => *self = DnsServer::Dynu(Default::default()), DnsServerType::EasyDns => *self = DnsServer::EasyDns(Default::default()), DnsServerType::EdgeDns => *self = DnsServer::EdgeDns(Default::default()), DnsServerType::Exoscale => *self = DnsServer::Exoscale(Default::default()), DnsServerType::FreeMyIp => *self = DnsServer::FreeMyIp(Default::default()), DnsServerType::GandiV5 => *self = DnsServer::GandiV5(Default::default()), DnsServerType::Gcore => *self = DnsServer::Gcore(Default::default()), DnsServerType::Glesys => *self = DnsServer::Glesys(Default::default()), DnsServerType::Godaddy => *self = DnsServer::Godaddy(Default::default()), DnsServerType::Hetzner => *self = DnsServer::Hetzner(Default::default()), DnsServerType::HostingDe => *self = DnsServer::HostingDe(Default::default()), DnsServerType::Hostinger => *self = DnsServer::Hostinger(Default::default()), DnsServerType::HuaweiCloud => *self = DnsServer::HuaweiCloud(Default::default()), DnsServerType::Hurricane => *self = DnsServer::Hurricane(Default::default()), DnsServerType::IbmCloud => *self = DnsServer::IbmCloud(Default::default()), DnsServerType::Infoblox => *self = DnsServer::Infoblox(Default::default()), DnsServerType::Infomaniak => *self = DnsServer::Infomaniak(Default::default()), DnsServerType::Inwx => *self = DnsServer::Inwx(Default::default()), DnsServerType::Ionos => *self = DnsServer::Ionos(Default::default()), DnsServerType::Ipv64 => *self = DnsServer::Ipv64(Default::default()), DnsServerType::Joker => *self = DnsServer::Joker(Default::default()), DnsServerType::Lightsail => *self = DnsServer::Lightsail(Default::default()), DnsServerType::Linode => *self = DnsServer::Linode(Default::default()), DnsServerType::LuaDns => *self = DnsServer::LuaDns(Default::default()), DnsServerType::MythicBeasts => *self = DnsServer::MythicBeasts(Default::default()), DnsServerType::Namecheap => *self = DnsServer::Namecheap(Default::default()), DnsServerType::NameDotCom => *self = DnsServer::NameDotCom(Default::default()), DnsServerType::NameSilo => *self = DnsServer::NameSilo(Default::default()), DnsServerType::Netcup => *self = DnsServer::Netcup(Default::default()), DnsServerType::Netlify => *self = DnsServer::Netlify(Default::default()), DnsServerType::Nifcloud => *self = DnsServer::Nifcloud(Default::default()), DnsServerType::Ns1 => *self = DnsServer::Ns1(Default::default()), DnsServerType::OracleCloud => *self = DnsServer::OracleCloud(Default::default()), DnsServerType::Plesk => *self = DnsServer::Plesk(Default::default()), DnsServerType::Safedns => *self = DnsServer::Safedns(Default::default()), DnsServerType::Scaleway => *self = DnsServer::Scaleway(Default::default()), DnsServerType::TencentCloud => *self = DnsServer::TencentCloud(Default::default()), DnsServerType::Transip => *self = DnsServer::Transip(Default::default()), DnsServerType::UltraDns => *self = DnsServer::UltraDns(Default::default()), DnsServerType::Vercel => *self = DnsServer::Vercel(Default::default()), DnsServerType::Volcengine => *self = DnsServer::Volcengine(Default::default()), DnsServerType::Vultr => *self = DnsServer::Vultr(Default::default()), DnsServerType::WebSupport => *self = DnsServer::WebSupport(Default::default()), DnsServerType::YandexCloud => *self = DnsServer::YandexCloud(Default::default()), } } match self { DnsServer::Tsig(inner) => inner.patch(pointer, value), DnsServer::Deprecated1 => pointer.assert_eof(), DnsServer::Cloudflare(inner) => inner.patch(pointer, value), DnsServer::DigitalOcean(inner) => inner.patch(pointer, value), DnsServer::DeSEC(inner) => inner.patch(pointer, value), DnsServer::Ovh(inner) => inner.patch(pointer, value), DnsServer::Bunny(inner) => inner.patch(pointer, value), DnsServer::Porkbun(inner) => inner.patch(pointer, value), DnsServer::Dnsimple(inner) => inner.patch(pointer, value), DnsServer::Spaceship(inner) => inner.patch(pointer, value), DnsServer::Route53(inner) => inner.patch(pointer, value), DnsServer::GoogleCloudDns(inner) => inner.patch(pointer, value), DnsServer::Alidns(inner) => inner.patch(pointer, value), DnsServer::ArvanCloud(inner) => inner.patch(pointer, value), DnsServer::Autodns(inner) => inner.patch(pointer, value), DnsServer::AzureDns(inner) => inner.patch(pointer, value), DnsServer::BaiduCloud(inner) => inner.patch(pointer, value), DnsServer::BluecatV2(inner) => inner.patch(pointer, value), DnsServer::ClouDns(inner) => inner.patch(pointer, value), DnsServer::Constellix(inner) => inner.patch(pointer, value), DnsServer::Cpanel(inner) => inner.patch(pointer, value), DnsServer::Ddnss(inner) => inner.patch(pointer, value), DnsServer::DnsMadeEasy(inner) => inner.patch(pointer, value), DnsServer::Domeneshop(inner) => inner.patch(pointer, value), DnsServer::Dreamhost(inner) => inner.patch(pointer, value), DnsServer::DuckDns(inner) => inner.patch(pointer, value), DnsServer::Dynu(inner) => inner.patch(pointer, value), DnsServer::EasyDns(inner) => inner.patch(pointer, value), DnsServer::EdgeDns(inner) => inner.patch(pointer, value), DnsServer::Exoscale(inner) => inner.patch(pointer, value), DnsServer::FreeMyIp(inner) => inner.patch(pointer, value), DnsServer::GandiV5(inner) => inner.patch(pointer, value), DnsServer::Gcore(inner) => inner.patch(pointer, value), DnsServer::Glesys(inner) => inner.patch(pointer, value), DnsServer::Godaddy(inner) => inner.patch(pointer, value), DnsServer::Hetzner(inner) => inner.patch(pointer, value), DnsServer::HostingDe(inner) => inner.patch(pointer, value), DnsServer::Hostinger(inner) => inner.patch(pointer, value), DnsServer::HuaweiCloud(inner) => inner.patch(pointer, value), DnsServer::Hurricane(inner) => inner.patch(pointer, value), DnsServer::IbmCloud(inner) => inner.patch(pointer, value), DnsServer::Infoblox(inner) => inner.patch(pointer, value), DnsServer::Infomaniak(inner) => inner.patch(pointer, value), DnsServer::Inwx(inner) => inner.patch(pointer, value), DnsServer::Ionos(inner) => inner.patch(pointer, value), DnsServer::Ipv64(inner) => inner.patch(pointer, value), DnsServer::Joker(inner) => inner.patch(pointer, value), DnsServer::Lightsail(inner) => inner.patch(pointer, value), DnsServer::Linode(inner) => inner.patch(pointer, value), DnsServer::LuaDns(inner) => inner.patch(pointer, value), DnsServer::MythicBeasts(inner) => inner.patch(pointer, value), DnsServer::Namecheap(inner) => inner.patch(pointer, value), DnsServer::NameDotCom(inner) => inner.patch(pointer, value), DnsServer::NameSilo(inner) => inner.patch(pointer, value), DnsServer::Netcup(inner) => inner.patch(pointer, value), DnsServer::Netlify(inner) => inner.patch(pointer, value), DnsServer::Nifcloud(inner) => inner.patch(pointer, value), DnsServer::Ns1(inner) => inner.patch(pointer, value), DnsServer::OracleCloud(inner) => inner.patch(pointer, value), DnsServer::Plesk(inner) => inner.patch(pointer, value), DnsServer::Safedns(inner) => inner.patch(pointer, value), DnsServer::Scaleway(inner) => inner.patch(pointer, value), DnsServer::TencentCloud(inner) => inner.patch(pointer, value), DnsServer::Transip(inner) => inner.patch(pointer, value), DnsServer::UltraDns(inner) => inner.patch(pointer, value), DnsServer::Vercel(inner) => inner.patch(pointer, value), DnsServer::Volcengine(inner) => inner.patch(pointer, value), DnsServer::Vultr(inner) => inner.patch(pointer, value), DnsServer::WebSupport(inner) => inner.patch(pointer, value), DnsServer::YandexCloud(inner) => inner.patch(pointer, value), } } } impl DnsServer { pub fn object_type(&self) -> DnsServerType { match self { DnsServer::Tsig(_) => DnsServerType::Tsig, DnsServer::Deprecated1 => DnsServerType::Deprecated1, DnsServer::Cloudflare(_) => DnsServerType::Cloudflare, DnsServer::DigitalOcean(_) => DnsServerType::DigitalOcean, DnsServer::DeSEC(_) => DnsServerType::DeSEC, DnsServer::Ovh(_) => DnsServerType::Ovh, DnsServer::Bunny(_) => DnsServerType::Bunny, DnsServer::Porkbun(_) => DnsServerType::Porkbun, DnsServer::Dnsimple(_) => DnsServerType::Dnsimple, DnsServer::Spaceship(_) => DnsServerType::Spaceship, DnsServer::Route53(_) => DnsServerType::Route53, DnsServer::GoogleCloudDns(_) => DnsServerType::GoogleCloudDns, DnsServer::Alidns(_) => DnsServerType::Alidns, DnsServer::ArvanCloud(_) => DnsServerType::ArvanCloud, DnsServer::Autodns(_) => DnsServerType::Autodns, DnsServer::AzureDns(_) => DnsServerType::AzureDns, DnsServer::BaiduCloud(_) => DnsServerType::BaiduCloud, DnsServer::BluecatV2(_) => DnsServerType::BluecatV2, DnsServer::ClouDns(_) => DnsServerType::ClouDns, DnsServer::Constellix(_) => DnsServerType::Constellix, DnsServer::Cpanel(_) => DnsServerType::Cpanel, DnsServer::Ddnss(_) => DnsServerType::Ddnss, DnsServer::DnsMadeEasy(_) => DnsServerType::DnsMadeEasy, DnsServer::Domeneshop(_) => DnsServerType::Domeneshop, DnsServer::Dreamhost(_) => DnsServerType::Dreamhost, DnsServer::DuckDns(_) => DnsServerType::DuckDns, DnsServer::Dynu(_) => DnsServerType::Dynu, DnsServer::EasyDns(_) => DnsServerType::EasyDns, DnsServer::EdgeDns(_) => DnsServerType::EdgeDns, DnsServer::Exoscale(_) => DnsServerType::Exoscale, DnsServer::FreeMyIp(_) => DnsServerType::FreeMyIp, DnsServer::GandiV5(_) => DnsServerType::GandiV5, DnsServer::Gcore(_) => DnsServerType::Gcore, DnsServer::Glesys(_) => DnsServerType::Glesys, DnsServer::Godaddy(_) => DnsServerType::Godaddy, DnsServer::Hetzner(_) => DnsServerType::Hetzner, DnsServer::HostingDe(_) => DnsServerType::HostingDe, DnsServer::Hostinger(_) => DnsServerType::Hostinger, DnsServer::HuaweiCloud(_) => DnsServerType::HuaweiCloud, DnsServer::Hurricane(_) => DnsServerType::Hurricane, DnsServer::IbmCloud(_) => DnsServerType::IbmCloud, DnsServer::Infoblox(_) => DnsServerType::Infoblox, DnsServer::Infomaniak(_) => DnsServerType::Infomaniak, DnsServer::Inwx(_) => DnsServerType::Inwx, DnsServer::Ionos(_) => DnsServerType::Ionos, DnsServer::Ipv64(_) => DnsServerType::Ipv64, DnsServer::Joker(_) => DnsServerType::Joker, DnsServer::Lightsail(_) => DnsServerType::Lightsail, DnsServer::Linode(_) => DnsServerType::Linode, DnsServer::LuaDns(_) => DnsServerType::LuaDns, DnsServer::MythicBeasts(_) => DnsServerType::MythicBeasts, DnsServer::Namecheap(_) => DnsServerType::Namecheap, DnsServer::NameDotCom(_) => DnsServerType::NameDotCom, DnsServer::NameSilo(_) => DnsServerType::NameSilo, DnsServer::Netcup(_) => DnsServerType::Netcup, DnsServer::Netlify(_) => DnsServerType::Netlify, DnsServer::Nifcloud(_) => DnsServerType::Nifcloud, DnsServer::Ns1(_) => DnsServerType::Ns1, DnsServer::OracleCloud(_) => DnsServerType::OracleCloud, DnsServer::Plesk(_) => DnsServerType::Plesk, DnsServer::Safedns(_) => DnsServerType::Safedns, DnsServer::Scaleway(_) => DnsServerType::Scaleway, DnsServer::TencentCloud(_) => DnsServerType::TencentCloud, DnsServer::Transip(_) => DnsServerType::Transip, DnsServer::UltraDns(_) => DnsServerType::UltraDns, DnsServer::Vercel(_) => DnsServerType::Vercel, DnsServer::Volcengine(_) => DnsServerType::Volcengine, DnsServer::Vultr(_) => DnsServerType::Vultr, DnsServer::WebSupport(_) => DnsServerType::WebSupport, DnsServer::YandexCloud(_) => DnsServerType::YandexCloud, } } } impl DnsServerAlidns { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.access_key; if value.is_empty() { errors.push(ValidationError::required(Property::AccessKey)); } let value = &self.secret_key; value.validate(errors); if let Some(value) = &self.region { if value.is_empty() { errors.push(ValidationError::required(Property::Region)); } } let value = &self.security_token; value.validate(errors); if let Some(value) = &self.line { if value.is_empty() { errors.push(ValidationError::required(Property::Line)); } } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerAlidns { fn pickle(&self, out: &mut Vec) { self.access_key.pickle(out); self.secret_key.pickle(out); self.region.pickle(out); self.security_token.pickle(out); self.line.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.access_key = Pickle::unpickle(stream)?; this.secret_key = Pickle::unpickle(stream)?; this.region = Pickle::unpickle(stream)?; this.security_token = Pickle::unpickle(stream)?; this.line = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerAlidns { fn default() -> Self { Self { access_key: Default::default(), secret_key: Default::default(), region: Default::default(), security_token: Default::default(), line: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerAlidns { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked(Property::AccessKey, self.access_key.into_value()); map.insert_unchecked(Property::SecretKey, self.secret_key.into_value()); map.insert_unchecked(Property::Region, self.region.into_value()); map.insert_unchecked(Property::SecurityToken, self.security_token.into_value()); map.insert_unchecked(Property::Line, self.line.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerAlidns { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AccessKey) => self .access_key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SecretKey) => self.secret_key.patch(pointer, value), Some(Property::Region) => self .region .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SecurityToken) => self.security_token.patch(pointer, value), Some(Property::Line) => self .line .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerAutodns { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.username; if value.is_empty() { errors.push(ValidationError::required(Property::Username)); } let value = &self.password; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerAutodns { fn pickle(&self, out: &mut Vec) { self.username.pickle(out); self.password.pickle(out); self.context.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.username = Pickle::unpickle(stream)?; this.password = Pickle::unpickle(stream)?; this.context = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerAutodns { fn default() -> Self { Self { username: Default::default(), password: Default::default(), context: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerAutodns { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(12); map.insert_unchecked(Property::Username, self.username.into_value()); map.insert_unchecked(Property::Password, self.password.into_value()); map.insert_unchecked(Property::Context, self.context.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerAutodns { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Username) => self .username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Password) => self.password.patch(pointer, value), Some(Property::Context) => self.context.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerAzureDns { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.tenant_id; if value.is_empty() { errors.push(ValidationError::required(Property::TenantId)); } let value = &self.client_id; if value.is_empty() { errors.push(ValidationError::required(Property::ClientId)); } let value = &self.client_secret; value.validate(errors); let value = &self.subscription_id; if value.is_empty() { errors.push(ValidationError::required(Property::SubscriptionId)); } let value = &self.resource_group; if value.is_empty() { errors.push(ValidationError::required(Property::ResourceGroup)); } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerAzureDns { fn pickle(&self, out: &mut Vec) { self.tenant_id.pickle(out); self.client_id.pickle(out); self.client_secret.pickle(out); self.subscription_id.pickle(out); self.resource_group.pickle(out); self.environment.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.tenant_id = Pickle::unpickle(stream)?; this.client_id = Pickle::unpickle(stream)?; this.client_secret = Pickle::unpickle(stream)?; this.subscription_id = Pickle::unpickle(stream)?; this.resource_group = Pickle::unpickle(stream)?; this.environment = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerAzureDns { fn default() -> Self { Self { tenant_id: Default::default(), client_id: Default::default(), client_secret: Default::default(), subscription_id: Default::default(), resource_group: Default::default(), environment: AzureEnvironment::Public, description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerAzureDns { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(15); map.insert_unchecked(Property::TenantId, self.tenant_id.into_value()); map.insert_unchecked(Property::ClientId, self.client_id.into_value()); map.insert_unchecked(Property::ClientSecret, self.client_secret.into_value()); map.insert_unchecked(Property::SubscriptionId, self.subscription_id.into_value()); map.insert_unchecked(Property::ResourceGroup, self.resource_group.into_value()); map.insert_unchecked(Property::Environment, self.environment.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerAzureDns { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::TenantId) => self .tenant_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ClientId) => self .client_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ClientSecret) => self.client_secret.patch(pointer, value), Some(Property::SubscriptionId) => self .subscription_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ResourceGroup) => self .resource_group .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Environment) => self.environment.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerBaiduCloud { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.access_key; if value.is_empty() { errors.push(ValidationError::required(Property::AccessKey)); } let value = &self.secret_key; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerBaiduCloud { fn pickle(&self, out: &mut Vec) { self.access_key.pickle(out); self.secret_key.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.access_key = Pickle::unpickle(stream)?; this.secret_key = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerBaiduCloud { fn default() -> Self { Self { access_key: Default::default(), secret_key: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerBaiduCloud { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::AccessKey, self.access_key.into_value()); map.insert_unchecked(Property::SecretKey, self.secret_key.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerBaiduCloud { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AccessKey) => self .access_key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SecretKey) => self.secret_key.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerBluecatV2 { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.base_url; if value.is_empty() { errors.push(ValidationError::required(Property::BaseUrl)); } let value = &self.username; if value.is_empty() { errors.push(ValidationError::required(Property::Username)); } let value = &self.password; value.validate(errors); let value = &self.config_name; if value.is_empty() { errors.push(ValidationError::required(Property::ConfigName)); } let value = &self.view_name; if value.is_empty() { errors.push(ValidationError::required(Property::ViewName)); } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerBluecatV2 { fn pickle(&self, out: &mut Vec) { self.base_url.pickle(out); self.username.pickle(out); self.password.pickle(out); self.config_name.pickle(out); self.view_name.pickle(out); self.skip_deploy.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.base_url = Pickle::unpickle(stream)?; this.username = Pickle::unpickle(stream)?; this.password = Pickle::unpickle(stream)?; this.config_name = Pickle::unpickle(stream)?; this.view_name = Pickle::unpickle(stream)?; this.skip_deploy = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerBluecatV2 { fn default() -> Self { Self { base_url: Default::default(), username: Default::default(), password: Default::default(), config_name: Default::default(), view_name: Default::default(), skip_deploy: false, description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerBluecatV2 { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(15); map.insert_unchecked(Property::BaseUrl, self.base_url.into_value()); map.insert_unchecked(Property::Username, self.username.into_value()); map.insert_unchecked(Property::Password, self.password.into_value()); map.insert_unchecked(Property::ConfigName, self.config_name.into_value()); map.insert_unchecked(Property::ViewName, self.view_name.into_value()); map.insert_unchecked(Property::SkipDeploy, self.skip_deploy.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerBluecatV2 { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::BaseUrl) => self .base_url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Username) => self .username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Password) => self.password.patch(pointer, value), Some(Property::ConfigName) => self .config_name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ViewName) => self .view_name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SkipDeploy) => self.skip_deploy.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerBootstrap { fn validate(&self, errors: &mut Vec) -> bool { match self { DnsServerBootstrap::Manual => true, DnsServerBootstrap::Tsig(inner) => inner.validate(errors), DnsServerBootstrap::Deprecated1 => true, DnsServerBootstrap::Cloudflare(inner) => inner.validate(errors), DnsServerBootstrap::DigitalOcean(inner) => inner.validate(errors), DnsServerBootstrap::DeSEC(inner) => inner.validate(errors), DnsServerBootstrap::Ovh(inner) => inner.validate(errors), DnsServerBootstrap::Bunny(inner) => inner.validate(errors), DnsServerBootstrap::Porkbun(inner) => inner.validate(errors), DnsServerBootstrap::Dnsimple(inner) => inner.validate(errors), DnsServerBootstrap::Spaceship(inner) => inner.validate(errors), DnsServerBootstrap::Route53(inner) => inner.validate(errors), DnsServerBootstrap::GoogleCloudDns(inner) => inner.validate(errors), DnsServerBootstrap::Alidns(inner) => inner.validate(errors), DnsServerBootstrap::ArvanCloud(inner) => inner.validate(errors), DnsServerBootstrap::Autodns(inner) => inner.validate(errors), DnsServerBootstrap::AzureDns(inner) => inner.validate(errors), DnsServerBootstrap::BaiduCloud(inner) => inner.validate(errors), DnsServerBootstrap::BluecatV2(inner) => inner.validate(errors), DnsServerBootstrap::ClouDns(inner) => inner.validate(errors), DnsServerBootstrap::Constellix(inner) => inner.validate(errors), DnsServerBootstrap::Cpanel(inner) => inner.validate(errors), DnsServerBootstrap::Ddnss(inner) => inner.validate(errors), DnsServerBootstrap::DnsMadeEasy(inner) => inner.validate(errors), DnsServerBootstrap::Domeneshop(inner) => inner.validate(errors), DnsServerBootstrap::Dreamhost(inner) => inner.validate(errors), DnsServerBootstrap::DuckDns(inner) => inner.validate(errors), DnsServerBootstrap::Dynu(inner) => inner.validate(errors), DnsServerBootstrap::EasyDns(inner) => inner.validate(errors), DnsServerBootstrap::EdgeDns(inner) => inner.validate(errors), DnsServerBootstrap::Exoscale(inner) => inner.validate(errors), DnsServerBootstrap::FreeMyIp(inner) => inner.validate(errors), DnsServerBootstrap::GandiV5(inner) => inner.validate(errors), DnsServerBootstrap::Gcore(inner) => inner.validate(errors), DnsServerBootstrap::Glesys(inner) => inner.validate(errors), DnsServerBootstrap::Godaddy(inner) => inner.validate(errors), DnsServerBootstrap::Hetzner(inner) => inner.validate(errors), DnsServerBootstrap::HostingDe(inner) => inner.validate(errors), DnsServerBootstrap::Hostinger(inner) => inner.validate(errors), DnsServerBootstrap::HuaweiCloud(inner) => inner.validate(errors), DnsServerBootstrap::Hurricane(inner) => inner.validate(errors), DnsServerBootstrap::IbmCloud(inner) => inner.validate(errors), DnsServerBootstrap::Infoblox(inner) => inner.validate(errors), DnsServerBootstrap::Infomaniak(inner) => inner.validate(errors), DnsServerBootstrap::Inwx(inner) => inner.validate(errors), DnsServerBootstrap::Ionos(inner) => inner.validate(errors), DnsServerBootstrap::Ipv64(inner) => inner.validate(errors), DnsServerBootstrap::Joker(inner) => inner.validate(errors), DnsServerBootstrap::Lightsail(inner) => inner.validate(errors), DnsServerBootstrap::Linode(inner) => inner.validate(errors), DnsServerBootstrap::LuaDns(inner) => inner.validate(errors), DnsServerBootstrap::MythicBeasts(inner) => inner.validate(errors), DnsServerBootstrap::Namecheap(inner) => inner.validate(errors), DnsServerBootstrap::NameDotCom(inner) => inner.validate(errors), DnsServerBootstrap::NameSilo(inner) => inner.validate(errors), DnsServerBootstrap::Netcup(inner) => inner.validate(errors), DnsServerBootstrap::Netlify(inner) => inner.validate(errors), DnsServerBootstrap::Nifcloud(inner) => inner.validate(errors), DnsServerBootstrap::Ns1(inner) => inner.validate(errors), DnsServerBootstrap::OracleCloud(inner) => inner.validate(errors), DnsServerBootstrap::Plesk(inner) => inner.validate(errors), DnsServerBootstrap::Safedns(inner) => inner.validate(errors), DnsServerBootstrap::Scaleway(inner) => inner.validate(errors), DnsServerBootstrap::TencentCloud(inner) => inner.validate(errors), DnsServerBootstrap::Transip(inner) => inner.validate(errors), DnsServerBootstrap::UltraDns(inner) => inner.validate(errors), DnsServerBootstrap::Vercel(inner) => inner.validate(errors), DnsServerBootstrap::Volcengine(inner) => inner.validate(errors), DnsServerBootstrap::Vultr(inner) => inner.validate(errors), DnsServerBootstrap::WebSupport(inner) => inner.validate(errors), DnsServerBootstrap::YandexCloud(inner) => inner.validate(errors), } } } impl Default for DnsServerBootstrap { fn default() -> Self { DnsServerBootstrap::Manual } } impl Pickle for DnsServerBootstrap { fn pickle(&self, out: &mut Vec) { match self { DnsServerBootstrap::Manual => { 0u16.pickle(out); } DnsServerBootstrap::Tsig(inner) => { 1u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Deprecated1 => { 2u16.pickle(out); } DnsServerBootstrap::Cloudflare(inner) => { 3u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::DigitalOcean(inner) => { 4u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::DeSEC(inner) => { 5u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Ovh(inner) => { 6u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Bunny(inner) => { 7u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Porkbun(inner) => { 8u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Dnsimple(inner) => { 9u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Spaceship(inner) => { 10u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Route53(inner) => { 11u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::GoogleCloudDns(inner) => { 12u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Alidns(inner) => { 13u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::ArvanCloud(inner) => { 14u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Autodns(inner) => { 15u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::AzureDns(inner) => { 16u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::BaiduCloud(inner) => { 17u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::BluecatV2(inner) => { 18u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::ClouDns(inner) => { 19u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Constellix(inner) => { 20u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Cpanel(inner) => { 21u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Ddnss(inner) => { 22u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::DnsMadeEasy(inner) => { 23u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Domeneshop(inner) => { 24u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Dreamhost(inner) => { 25u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::DuckDns(inner) => { 26u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Dynu(inner) => { 27u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::EasyDns(inner) => { 28u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::EdgeDns(inner) => { 29u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Exoscale(inner) => { 30u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::FreeMyIp(inner) => { 31u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::GandiV5(inner) => { 32u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Gcore(inner) => { 33u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Glesys(inner) => { 34u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Godaddy(inner) => { 35u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Hetzner(inner) => { 36u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::HostingDe(inner) => { 37u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Hostinger(inner) => { 38u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::HuaweiCloud(inner) => { 39u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Hurricane(inner) => { 40u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::IbmCloud(inner) => { 41u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Infoblox(inner) => { 42u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Infomaniak(inner) => { 43u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Inwx(inner) => { 44u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Ionos(inner) => { 45u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Ipv64(inner) => { 46u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Joker(inner) => { 47u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Lightsail(inner) => { 48u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Linode(inner) => { 49u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::LuaDns(inner) => { 50u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::MythicBeasts(inner) => { 51u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Namecheap(inner) => { 52u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::NameDotCom(inner) => { 53u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::NameSilo(inner) => { 54u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Netcup(inner) => { 55u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Netlify(inner) => { 56u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Nifcloud(inner) => { 57u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Ns1(inner) => { 58u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::OracleCloud(inner) => { 59u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Plesk(inner) => { 60u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Safedns(inner) => { 61u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Scaleway(inner) => { 62u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::TencentCloud(inner) => { 63u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Transip(inner) => { 64u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::UltraDns(inner) => { 65u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Vercel(inner) => { 66u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Volcengine(inner) => { 67u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::Vultr(inner) => { 68u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::WebSupport(inner) => { 69u16.pickle(out); inner.pickle(out); } DnsServerBootstrap::YandexCloud(inner) => { 70u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(DnsServerBootstrap::Manual), 1 => Pickle::unpickle(stream).map(DnsServerBootstrap::Tsig), 2 => Some(DnsServerBootstrap::Deprecated1), 3 => Pickle::unpickle(stream).map(DnsServerBootstrap::Cloudflare), 4 => Pickle::unpickle(stream).map(DnsServerBootstrap::DigitalOcean), 5 => Pickle::unpickle(stream).map(DnsServerBootstrap::DeSEC), 6 => Pickle::unpickle(stream).map(DnsServerBootstrap::Ovh), 7 => Pickle::unpickle(stream).map(DnsServerBootstrap::Bunny), 8 => Pickle::unpickle(stream).map(DnsServerBootstrap::Porkbun), 9 => Pickle::unpickle(stream).map(DnsServerBootstrap::Dnsimple), 10 => Pickle::unpickle(stream).map(DnsServerBootstrap::Spaceship), 11 => Pickle::unpickle(stream).map(DnsServerBootstrap::Route53), 12 => Pickle::unpickle(stream).map(DnsServerBootstrap::GoogleCloudDns), 13 => Pickle::unpickle(stream).map(DnsServerBootstrap::Alidns), 14 => Pickle::unpickle(stream).map(DnsServerBootstrap::ArvanCloud), 15 => Pickle::unpickle(stream).map(DnsServerBootstrap::Autodns), 16 => Pickle::unpickle(stream).map(DnsServerBootstrap::AzureDns), 17 => Pickle::unpickle(stream).map(DnsServerBootstrap::BaiduCloud), 18 => Pickle::unpickle(stream).map(DnsServerBootstrap::BluecatV2), 19 => Pickle::unpickle(stream).map(DnsServerBootstrap::ClouDns), 20 => Pickle::unpickle(stream).map(DnsServerBootstrap::Constellix), 21 => Pickle::unpickle(stream).map(DnsServerBootstrap::Cpanel), 22 => Pickle::unpickle(stream).map(DnsServerBootstrap::Ddnss), 23 => Pickle::unpickle(stream).map(DnsServerBootstrap::DnsMadeEasy), 24 => Pickle::unpickle(stream).map(DnsServerBootstrap::Domeneshop), 25 => Pickle::unpickle(stream).map(DnsServerBootstrap::Dreamhost), 26 => Pickle::unpickle(stream).map(DnsServerBootstrap::DuckDns), 27 => Pickle::unpickle(stream).map(DnsServerBootstrap::Dynu), 28 => Pickle::unpickle(stream).map(DnsServerBootstrap::EasyDns), 29 => Pickle::unpickle(stream).map(DnsServerBootstrap::EdgeDns), 30 => Pickle::unpickle(stream).map(DnsServerBootstrap::Exoscale), 31 => Pickle::unpickle(stream).map(DnsServerBootstrap::FreeMyIp), 32 => Pickle::unpickle(stream).map(DnsServerBootstrap::GandiV5), 33 => Pickle::unpickle(stream).map(DnsServerBootstrap::Gcore), 34 => Pickle::unpickle(stream).map(DnsServerBootstrap::Glesys), 35 => Pickle::unpickle(stream).map(DnsServerBootstrap::Godaddy), 36 => Pickle::unpickle(stream).map(DnsServerBootstrap::Hetzner), 37 => Pickle::unpickle(stream).map(DnsServerBootstrap::HostingDe), 38 => Pickle::unpickle(stream).map(DnsServerBootstrap::Hostinger), 39 => Pickle::unpickle(stream).map(DnsServerBootstrap::HuaweiCloud), 40 => Pickle::unpickle(stream).map(DnsServerBootstrap::Hurricane), 41 => Pickle::unpickle(stream).map(DnsServerBootstrap::IbmCloud), 42 => Pickle::unpickle(stream).map(DnsServerBootstrap::Infoblox), 43 => Pickle::unpickle(stream).map(DnsServerBootstrap::Infomaniak), 44 => Pickle::unpickle(stream).map(DnsServerBootstrap::Inwx), 45 => Pickle::unpickle(stream).map(DnsServerBootstrap::Ionos), 46 => Pickle::unpickle(stream).map(DnsServerBootstrap::Ipv64), 47 => Pickle::unpickle(stream).map(DnsServerBootstrap::Joker), 48 => Pickle::unpickle(stream).map(DnsServerBootstrap::Lightsail), 49 => Pickle::unpickle(stream).map(DnsServerBootstrap::Linode), 50 => Pickle::unpickle(stream).map(DnsServerBootstrap::LuaDns), 51 => Pickle::unpickle(stream).map(DnsServerBootstrap::MythicBeasts), 52 => Pickle::unpickle(stream).map(DnsServerBootstrap::Namecheap), 53 => Pickle::unpickle(stream).map(DnsServerBootstrap::NameDotCom), 54 => Pickle::unpickle(stream).map(DnsServerBootstrap::NameSilo), 55 => Pickle::unpickle(stream).map(DnsServerBootstrap::Netcup), 56 => Pickle::unpickle(stream).map(DnsServerBootstrap::Netlify), 57 => Pickle::unpickle(stream).map(DnsServerBootstrap::Nifcloud), 58 => Pickle::unpickle(stream).map(DnsServerBootstrap::Ns1), 59 => Pickle::unpickle(stream).map(DnsServerBootstrap::OracleCloud), 60 => Pickle::unpickle(stream).map(DnsServerBootstrap::Plesk), 61 => Pickle::unpickle(stream).map(DnsServerBootstrap::Safedns), 62 => Pickle::unpickle(stream).map(DnsServerBootstrap::Scaleway), 63 => Pickle::unpickle(stream).map(DnsServerBootstrap::TencentCloud), 64 => Pickle::unpickle(stream).map(DnsServerBootstrap::Transip), 65 => Pickle::unpickle(stream).map(DnsServerBootstrap::UltraDns), 66 => Pickle::unpickle(stream).map(DnsServerBootstrap::Vercel), 67 => Pickle::unpickle(stream).map(DnsServerBootstrap::Volcengine), 68 => Pickle::unpickle(stream).map(DnsServerBootstrap::Vultr), 69 => Pickle::unpickle(stream).map(DnsServerBootstrap::WebSupport), 70 => Pickle::unpickle(stream).map(DnsServerBootstrap::YandexCloud), _ => None, } } } impl IntoValue for DnsServerBootstrap { fn into_value(self) -> JmapValue<'static> { match self { DnsServerBootstrap::Manual => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Manual".into())); JmapValue::Object(obj) } DnsServerBootstrap::Tsig(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Tsig".into())); obj } DnsServerBootstrap::Deprecated1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Deprecated1".into())); JmapValue::Object(obj) } DnsServerBootstrap::Cloudflare(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Cloudflare".into())); obj } DnsServerBootstrap::DigitalOcean(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("DigitalOcean".into())); obj } DnsServerBootstrap::DeSEC(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("DeSEC".into())); obj } DnsServerBootstrap::Ovh(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ovh".into())); obj } DnsServerBootstrap::Bunny(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Bunny".into())); obj } DnsServerBootstrap::Porkbun(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Porkbun".into())); obj } DnsServerBootstrap::Dnsimple(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Dnsimple".into())); obj } DnsServerBootstrap::Spaceship(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Spaceship".into())); obj } DnsServerBootstrap::Route53(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Route53".into())); obj } DnsServerBootstrap::GoogleCloudDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("GoogleCloudDns".into())); obj } DnsServerBootstrap::Alidns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Alidns".into())); obj } DnsServerBootstrap::ArvanCloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("ArvanCloud".into())); obj } DnsServerBootstrap::Autodns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Autodns".into())); obj } DnsServerBootstrap::AzureDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("AzureDns".into())); obj } DnsServerBootstrap::BaiduCloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("BaiduCloud".into())); obj } DnsServerBootstrap::BluecatV2(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("BluecatV2".into())); obj } DnsServerBootstrap::ClouDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("ClouDns".into())); obj } DnsServerBootstrap::Constellix(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Constellix".into())); obj } DnsServerBootstrap::Cpanel(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Cpanel".into())); obj } DnsServerBootstrap::Ddnss(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ddnss".into())); obj } DnsServerBootstrap::DnsMadeEasy(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("DnsMadeEasy".into())); obj } DnsServerBootstrap::Domeneshop(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Domeneshop".into())); obj } DnsServerBootstrap::Dreamhost(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Dreamhost".into())); obj } DnsServerBootstrap::DuckDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("DuckDns".into())); obj } DnsServerBootstrap::Dynu(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Dynu".into())); obj } DnsServerBootstrap::EasyDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("EasyDns".into())); obj } DnsServerBootstrap::EdgeDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("EdgeDns".into())); obj } DnsServerBootstrap::Exoscale(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Exoscale".into())); obj } DnsServerBootstrap::FreeMyIp(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("FreeMyIp".into())); obj } DnsServerBootstrap::GandiV5(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("GandiV5".into())); obj } DnsServerBootstrap::Gcore(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Gcore".into())); obj } DnsServerBootstrap::Glesys(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Glesys".into())); obj } DnsServerBootstrap::Godaddy(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Godaddy".into())); obj } DnsServerBootstrap::Hetzner(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Hetzner".into())); obj } DnsServerBootstrap::HostingDe(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("HostingDe".into())); obj } DnsServerBootstrap::Hostinger(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Hostinger".into())); obj } DnsServerBootstrap::HuaweiCloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("HuaweiCloud".into())); obj } DnsServerBootstrap::Hurricane(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Hurricane".into())); obj } DnsServerBootstrap::IbmCloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("IbmCloud".into())); obj } DnsServerBootstrap::Infoblox(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Infoblox".into())); obj } DnsServerBootstrap::Infomaniak(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Infomaniak".into())); obj } DnsServerBootstrap::Inwx(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Inwx".into())); obj } DnsServerBootstrap::Ionos(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ionos".into())); obj } DnsServerBootstrap::Ipv64(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ipv64".into())); obj } DnsServerBootstrap::Joker(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Joker".into())); obj } DnsServerBootstrap::Lightsail(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Lightsail".into())); obj } DnsServerBootstrap::Linode(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Linode".into())); obj } DnsServerBootstrap::LuaDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("LuaDns".into())); obj } DnsServerBootstrap::MythicBeasts(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("MythicBeasts".into())); obj } DnsServerBootstrap::Namecheap(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Namecheap".into())); obj } DnsServerBootstrap::NameDotCom(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("NameDotCom".into())); obj } DnsServerBootstrap::NameSilo(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("NameSilo".into())); obj } DnsServerBootstrap::Netcup(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Netcup".into())); obj } DnsServerBootstrap::Netlify(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Netlify".into())); obj } DnsServerBootstrap::Nifcloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Nifcloud".into())); obj } DnsServerBootstrap::Ns1(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ns1".into())); obj } DnsServerBootstrap::OracleCloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("OracleCloud".into())); obj } DnsServerBootstrap::Plesk(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Plesk".into())); obj } DnsServerBootstrap::Safedns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Safedns".into())); obj } DnsServerBootstrap::Scaleway(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Scaleway".into())); obj } DnsServerBootstrap::TencentCloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("TencentCloud".into())); obj } DnsServerBootstrap::Transip(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Transip".into())); obj } DnsServerBootstrap::UltraDns(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("UltraDns".into())); obj } DnsServerBootstrap::Vercel(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Vercel".into())); obj } DnsServerBootstrap::Volcengine(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Volcengine".into())); obj } DnsServerBootstrap::Vultr(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Vultr".into())); obj } DnsServerBootstrap::WebSupport(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("WebSupport".into())); obj } DnsServerBootstrap::YandexCloud(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("YandexCloud".into())); obj } } } } impl RegistryJsonPatch for DnsServerBootstrap { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { DnsServerBootstrapType::Manual => *self = DnsServerBootstrap::Manual, DnsServerBootstrapType::Tsig => { *self = DnsServerBootstrap::Tsig(Default::default()) } DnsServerBootstrapType::Deprecated1 => *self = DnsServerBootstrap::Deprecated1, DnsServerBootstrapType::Cloudflare => { *self = DnsServerBootstrap::Cloudflare(Default::default()) } DnsServerBootstrapType::DigitalOcean => { *self = DnsServerBootstrap::DigitalOcean(Default::default()) } DnsServerBootstrapType::DeSEC => { *self = DnsServerBootstrap::DeSEC(Default::default()) } DnsServerBootstrapType::Ovh => *self = DnsServerBootstrap::Ovh(Default::default()), DnsServerBootstrapType::Bunny => { *self = DnsServerBootstrap::Bunny(Default::default()) } DnsServerBootstrapType::Porkbun => { *self = DnsServerBootstrap::Porkbun(Default::default()) } DnsServerBootstrapType::Dnsimple => { *self = DnsServerBootstrap::Dnsimple(Default::default()) } DnsServerBootstrapType::Spaceship => { *self = DnsServerBootstrap::Spaceship(Default::default()) } DnsServerBootstrapType::Route53 => { *self = DnsServerBootstrap::Route53(Default::default()) } DnsServerBootstrapType::GoogleCloudDns => { *self = DnsServerBootstrap::GoogleCloudDns(Default::default()) } DnsServerBootstrapType::Alidns => { *self = DnsServerBootstrap::Alidns(Default::default()) } DnsServerBootstrapType::ArvanCloud => { *self = DnsServerBootstrap::ArvanCloud(Default::default()) } DnsServerBootstrapType::Autodns => { *self = DnsServerBootstrap::Autodns(Default::default()) } DnsServerBootstrapType::AzureDns => { *self = DnsServerBootstrap::AzureDns(Default::default()) } DnsServerBootstrapType::BaiduCloud => { *self = DnsServerBootstrap::BaiduCloud(Default::default()) } DnsServerBootstrapType::BluecatV2 => { *self = DnsServerBootstrap::BluecatV2(Default::default()) } DnsServerBootstrapType::ClouDns => { *self = DnsServerBootstrap::ClouDns(Default::default()) } DnsServerBootstrapType::Constellix => { *self = DnsServerBootstrap::Constellix(Default::default()) } DnsServerBootstrapType::Cpanel => { *self = DnsServerBootstrap::Cpanel(Default::default()) } DnsServerBootstrapType::Ddnss => { *self = DnsServerBootstrap::Ddnss(Default::default()) } DnsServerBootstrapType::DnsMadeEasy => { *self = DnsServerBootstrap::DnsMadeEasy(Default::default()) } DnsServerBootstrapType::Domeneshop => { *self = DnsServerBootstrap::Domeneshop(Default::default()) } DnsServerBootstrapType::Dreamhost => { *self = DnsServerBootstrap::Dreamhost(Default::default()) } DnsServerBootstrapType::DuckDns => { *self = DnsServerBootstrap::DuckDns(Default::default()) } DnsServerBootstrapType::Dynu => { *self = DnsServerBootstrap::Dynu(Default::default()) } DnsServerBootstrapType::EasyDns => { *self = DnsServerBootstrap::EasyDns(Default::default()) } DnsServerBootstrapType::EdgeDns => { *self = DnsServerBootstrap::EdgeDns(Default::default()) } DnsServerBootstrapType::Exoscale => { *self = DnsServerBootstrap::Exoscale(Default::default()) } DnsServerBootstrapType::FreeMyIp => { *self = DnsServerBootstrap::FreeMyIp(Default::default()) } DnsServerBootstrapType::GandiV5 => { *self = DnsServerBootstrap::GandiV5(Default::default()) } DnsServerBootstrapType::Gcore => { *self = DnsServerBootstrap::Gcore(Default::default()) } DnsServerBootstrapType::Glesys => { *self = DnsServerBootstrap::Glesys(Default::default()) } DnsServerBootstrapType::Godaddy => { *self = DnsServerBootstrap::Godaddy(Default::default()) } DnsServerBootstrapType::Hetzner => { *self = DnsServerBootstrap::Hetzner(Default::default()) } DnsServerBootstrapType::HostingDe => { *self = DnsServerBootstrap::HostingDe(Default::default()) } DnsServerBootstrapType::Hostinger => { *self = DnsServerBootstrap::Hostinger(Default::default()) } DnsServerBootstrapType::HuaweiCloud => { *self = DnsServerBootstrap::HuaweiCloud(Default::default()) } DnsServerBootstrapType::Hurricane => { *self = DnsServerBootstrap::Hurricane(Default::default()) } DnsServerBootstrapType::IbmCloud => { *self = DnsServerBootstrap::IbmCloud(Default::default()) } DnsServerBootstrapType::Infoblox => { *self = DnsServerBootstrap::Infoblox(Default::default()) } DnsServerBootstrapType::Infomaniak => { *self = DnsServerBootstrap::Infomaniak(Default::default()) } DnsServerBootstrapType::Inwx => { *self = DnsServerBootstrap::Inwx(Default::default()) } DnsServerBootstrapType::Ionos => { *self = DnsServerBootstrap::Ionos(Default::default()) } DnsServerBootstrapType::Ipv64 => { *self = DnsServerBootstrap::Ipv64(Default::default()) } DnsServerBootstrapType::Joker => { *self = DnsServerBootstrap::Joker(Default::default()) } DnsServerBootstrapType::Lightsail => { *self = DnsServerBootstrap::Lightsail(Default::default()) } DnsServerBootstrapType::Linode => { *self = DnsServerBootstrap::Linode(Default::default()) } DnsServerBootstrapType::LuaDns => { *self = DnsServerBootstrap::LuaDns(Default::default()) } DnsServerBootstrapType::MythicBeasts => { *self = DnsServerBootstrap::MythicBeasts(Default::default()) } DnsServerBootstrapType::Namecheap => { *self = DnsServerBootstrap::Namecheap(Default::default()) } DnsServerBootstrapType::NameDotCom => { *self = DnsServerBootstrap::NameDotCom(Default::default()) } DnsServerBootstrapType::NameSilo => { *self = DnsServerBootstrap::NameSilo(Default::default()) } DnsServerBootstrapType::Netcup => { *self = DnsServerBootstrap::Netcup(Default::default()) } DnsServerBootstrapType::Netlify => { *self = DnsServerBootstrap::Netlify(Default::default()) } DnsServerBootstrapType::Nifcloud => { *self = DnsServerBootstrap::Nifcloud(Default::default()) } DnsServerBootstrapType::Ns1 => *self = DnsServerBootstrap::Ns1(Default::default()), DnsServerBootstrapType::OracleCloud => { *self = DnsServerBootstrap::OracleCloud(Default::default()) } DnsServerBootstrapType::Plesk => { *self = DnsServerBootstrap::Plesk(Default::default()) } DnsServerBootstrapType::Safedns => { *self = DnsServerBootstrap::Safedns(Default::default()) } DnsServerBootstrapType::Scaleway => { *self = DnsServerBootstrap::Scaleway(Default::default()) } DnsServerBootstrapType::TencentCloud => { *self = DnsServerBootstrap::TencentCloud(Default::default()) } DnsServerBootstrapType::Transip => { *self = DnsServerBootstrap::Transip(Default::default()) } DnsServerBootstrapType::UltraDns => { *self = DnsServerBootstrap::UltraDns(Default::default()) } DnsServerBootstrapType::Vercel => { *self = DnsServerBootstrap::Vercel(Default::default()) } DnsServerBootstrapType::Volcengine => { *self = DnsServerBootstrap::Volcengine(Default::default()) } DnsServerBootstrapType::Vultr => { *self = DnsServerBootstrap::Vultr(Default::default()) } DnsServerBootstrapType::WebSupport => { *self = DnsServerBootstrap::WebSupport(Default::default()) } DnsServerBootstrapType::YandexCloud => { *self = DnsServerBootstrap::YandexCloud(Default::default()) } } } match self { DnsServerBootstrap::Manual => pointer.assert_eof(), DnsServerBootstrap::Tsig(inner) => inner.patch(pointer, value), DnsServerBootstrap::Deprecated1 => pointer.assert_eof(), DnsServerBootstrap::Cloudflare(inner) => inner.patch(pointer, value), DnsServerBootstrap::DigitalOcean(inner) => inner.patch(pointer, value), DnsServerBootstrap::DeSEC(inner) => inner.patch(pointer, value), DnsServerBootstrap::Ovh(inner) => inner.patch(pointer, value), DnsServerBootstrap::Bunny(inner) => inner.patch(pointer, value), DnsServerBootstrap::Porkbun(inner) => inner.patch(pointer, value), DnsServerBootstrap::Dnsimple(inner) => inner.patch(pointer, value), DnsServerBootstrap::Spaceship(inner) => inner.patch(pointer, value), DnsServerBootstrap::Route53(inner) => inner.patch(pointer, value), DnsServerBootstrap::GoogleCloudDns(inner) => inner.patch(pointer, value), DnsServerBootstrap::Alidns(inner) => inner.patch(pointer, value), DnsServerBootstrap::ArvanCloud(inner) => inner.patch(pointer, value), DnsServerBootstrap::Autodns(inner) => inner.patch(pointer, value), DnsServerBootstrap::AzureDns(inner) => inner.patch(pointer, value), DnsServerBootstrap::BaiduCloud(inner) => inner.patch(pointer, value), DnsServerBootstrap::BluecatV2(inner) => inner.patch(pointer, value), DnsServerBootstrap::ClouDns(inner) => inner.patch(pointer, value), DnsServerBootstrap::Constellix(inner) => inner.patch(pointer, value), DnsServerBootstrap::Cpanel(inner) => inner.patch(pointer, value), DnsServerBootstrap::Ddnss(inner) => inner.patch(pointer, value), DnsServerBootstrap::DnsMadeEasy(inner) => inner.patch(pointer, value), DnsServerBootstrap::Domeneshop(inner) => inner.patch(pointer, value), DnsServerBootstrap::Dreamhost(inner) => inner.patch(pointer, value), DnsServerBootstrap::DuckDns(inner) => inner.patch(pointer, value), DnsServerBootstrap::Dynu(inner) => inner.patch(pointer, value), DnsServerBootstrap::EasyDns(inner) => inner.patch(pointer, value), DnsServerBootstrap::EdgeDns(inner) => inner.patch(pointer, value), DnsServerBootstrap::Exoscale(inner) => inner.patch(pointer, value), DnsServerBootstrap::FreeMyIp(inner) => inner.patch(pointer, value), DnsServerBootstrap::GandiV5(inner) => inner.patch(pointer, value), DnsServerBootstrap::Gcore(inner) => inner.patch(pointer, value), DnsServerBootstrap::Glesys(inner) => inner.patch(pointer, value), DnsServerBootstrap::Godaddy(inner) => inner.patch(pointer, value), DnsServerBootstrap::Hetzner(inner) => inner.patch(pointer, value), DnsServerBootstrap::HostingDe(inner) => inner.patch(pointer, value), DnsServerBootstrap::Hostinger(inner) => inner.patch(pointer, value), DnsServerBootstrap::HuaweiCloud(inner) => inner.patch(pointer, value), DnsServerBootstrap::Hurricane(inner) => inner.patch(pointer, value), DnsServerBootstrap::IbmCloud(inner) => inner.patch(pointer, value), DnsServerBootstrap::Infoblox(inner) => inner.patch(pointer, value), DnsServerBootstrap::Infomaniak(inner) => inner.patch(pointer, value), DnsServerBootstrap::Inwx(inner) => inner.patch(pointer, value), DnsServerBootstrap::Ionos(inner) => inner.patch(pointer, value), DnsServerBootstrap::Ipv64(inner) => inner.patch(pointer, value), DnsServerBootstrap::Joker(inner) => inner.patch(pointer, value), DnsServerBootstrap::Lightsail(inner) => inner.patch(pointer, value), DnsServerBootstrap::Linode(inner) => inner.patch(pointer, value), DnsServerBootstrap::LuaDns(inner) => inner.patch(pointer, value), DnsServerBootstrap::MythicBeasts(inner) => inner.patch(pointer, value), DnsServerBootstrap::Namecheap(inner) => inner.patch(pointer, value), DnsServerBootstrap::NameDotCom(inner) => inner.patch(pointer, value), DnsServerBootstrap::NameSilo(inner) => inner.patch(pointer, value), DnsServerBootstrap::Netcup(inner) => inner.patch(pointer, value), DnsServerBootstrap::Netlify(inner) => inner.patch(pointer, value), DnsServerBootstrap::Nifcloud(inner) => inner.patch(pointer, value), DnsServerBootstrap::Ns1(inner) => inner.patch(pointer, value), DnsServerBootstrap::OracleCloud(inner) => inner.patch(pointer, value), DnsServerBootstrap::Plesk(inner) => inner.patch(pointer, value), DnsServerBootstrap::Safedns(inner) => inner.patch(pointer, value), DnsServerBootstrap::Scaleway(inner) => inner.patch(pointer, value), DnsServerBootstrap::TencentCloud(inner) => inner.patch(pointer, value), DnsServerBootstrap::Transip(inner) => inner.patch(pointer, value), DnsServerBootstrap::UltraDns(inner) => inner.patch(pointer, value), DnsServerBootstrap::Vercel(inner) => inner.patch(pointer, value), DnsServerBootstrap::Volcengine(inner) => inner.patch(pointer, value), DnsServerBootstrap::Vultr(inner) => inner.patch(pointer, value), DnsServerBootstrap::WebSupport(inner) => inner.patch(pointer, value), DnsServerBootstrap::YandexCloud(inner) => inner.patch(pointer, value), } } } impl DnsServerBootstrap { pub fn object_type(&self) -> DnsServerBootstrapType { match self { DnsServerBootstrap::Manual => DnsServerBootstrapType::Manual, DnsServerBootstrap::Tsig(_) => DnsServerBootstrapType::Tsig, DnsServerBootstrap::Deprecated1 => DnsServerBootstrapType::Deprecated1, DnsServerBootstrap::Cloudflare(_) => DnsServerBootstrapType::Cloudflare, DnsServerBootstrap::DigitalOcean(_) => DnsServerBootstrapType::DigitalOcean, DnsServerBootstrap::DeSEC(_) => DnsServerBootstrapType::DeSEC, DnsServerBootstrap::Ovh(_) => DnsServerBootstrapType::Ovh, DnsServerBootstrap::Bunny(_) => DnsServerBootstrapType::Bunny, DnsServerBootstrap::Porkbun(_) => DnsServerBootstrapType::Porkbun, DnsServerBootstrap::Dnsimple(_) => DnsServerBootstrapType::Dnsimple, DnsServerBootstrap::Spaceship(_) => DnsServerBootstrapType::Spaceship, DnsServerBootstrap::Route53(_) => DnsServerBootstrapType::Route53, DnsServerBootstrap::GoogleCloudDns(_) => DnsServerBootstrapType::GoogleCloudDns, DnsServerBootstrap::Alidns(_) => DnsServerBootstrapType::Alidns, DnsServerBootstrap::ArvanCloud(_) => DnsServerBootstrapType::ArvanCloud, DnsServerBootstrap::Autodns(_) => DnsServerBootstrapType::Autodns, DnsServerBootstrap::AzureDns(_) => DnsServerBootstrapType::AzureDns, DnsServerBootstrap::BaiduCloud(_) => DnsServerBootstrapType::BaiduCloud, DnsServerBootstrap::BluecatV2(_) => DnsServerBootstrapType::BluecatV2, DnsServerBootstrap::ClouDns(_) => DnsServerBootstrapType::ClouDns, DnsServerBootstrap::Constellix(_) => DnsServerBootstrapType::Constellix, DnsServerBootstrap::Cpanel(_) => DnsServerBootstrapType::Cpanel, DnsServerBootstrap::Ddnss(_) => DnsServerBootstrapType::Ddnss, DnsServerBootstrap::DnsMadeEasy(_) => DnsServerBootstrapType::DnsMadeEasy, DnsServerBootstrap::Domeneshop(_) => DnsServerBootstrapType::Domeneshop, DnsServerBootstrap::Dreamhost(_) => DnsServerBootstrapType::Dreamhost, DnsServerBootstrap::DuckDns(_) => DnsServerBootstrapType::DuckDns, DnsServerBootstrap::Dynu(_) => DnsServerBootstrapType::Dynu, DnsServerBootstrap::EasyDns(_) => DnsServerBootstrapType::EasyDns, DnsServerBootstrap::EdgeDns(_) => DnsServerBootstrapType::EdgeDns, DnsServerBootstrap::Exoscale(_) => DnsServerBootstrapType::Exoscale, DnsServerBootstrap::FreeMyIp(_) => DnsServerBootstrapType::FreeMyIp, DnsServerBootstrap::GandiV5(_) => DnsServerBootstrapType::GandiV5, DnsServerBootstrap::Gcore(_) => DnsServerBootstrapType::Gcore, DnsServerBootstrap::Glesys(_) => DnsServerBootstrapType::Glesys, DnsServerBootstrap::Godaddy(_) => DnsServerBootstrapType::Godaddy, DnsServerBootstrap::Hetzner(_) => DnsServerBootstrapType::Hetzner, DnsServerBootstrap::HostingDe(_) => DnsServerBootstrapType::HostingDe, DnsServerBootstrap::Hostinger(_) => DnsServerBootstrapType::Hostinger, DnsServerBootstrap::HuaweiCloud(_) => DnsServerBootstrapType::HuaweiCloud, DnsServerBootstrap::Hurricane(_) => DnsServerBootstrapType::Hurricane, DnsServerBootstrap::IbmCloud(_) => DnsServerBootstrapType::IbmCloud, DnsServerBootstrap::Infoblox(_) => DnsServerBootstrapType::Infoblox, DnsServerBootstrap::Infomaniak(_) => DnsServerBootstrapType::Infomaniak, DnsServerBootstrap::Inwx(_) => DnsServerBootstrapType::Inwx, DnsServerBootstrap::Ionos(_) => DnsServerBootstrapType::Ionos, DnsServerBootstrap::Ipv64(_) => DnsServerBootstrapType::Ipv64, DnsServerBootstrap::Joker(_) => DnsServerBootstrapType::Joker, DnsServerBootstrap::Lightsail(_) => DnsServerBootstrapType::Lightsail, DnsServerBootstrap::Linode(_) => DnsServerBootstrapType::Linode, DnsServerBootstrap::LuaDns(_) => DnsServerBootstrapType::LuaDns, DnsServerBootstrap::MythicBeasts(_) => DnsServerBootstrapType::MythicBeasts, DnsServerBootstrap::Namecheap(_) => DnsServerBootstrapType::Namecheap, DnsServerBootstrap::NameDotCom(_) => DnsServerBootstrapType::NameDotCom, DnsServerBootstrap::NameSilo(_) => DnsServerBootstrapType::NameSilo, DnsServerBootstrap::Netcup(_) => DnsServerBootstrapType::Netcup, DnsServerBootstrap::Netlify(_) => DnsServerBootstrapType::Netlify, DnsServerBootstrap::Nifcloud(_) => DnsServerBootstrapType::Nifcloud, DnsServerBootstrap::Ns1(_) => DnsServerBootstrapType::Ns1, DnsServerBootstrap::OracleCloud(_) => DnsServerBootstrapType::OracleCloud, DnsServerBootstrap::Plesk(_) => DnsServerBootstrapType::Plesk, DnsServerBootstrap::Safedns(_) => DnsServerBootstrapType::Safedns, DnsServerBootstrap::Scaleway(_) => DnsServerBootstrapType::Scaleway, DnsServerBootstrap::TencentCloud(_) => DnsServerBootstrapType::TencentCloud, DnsServerBootstrap::Transip(_) => DnsServerBootstrapType::Transip, DnsServerBootstrap::UltraDns(_) => DnsServerBootstrapType::UltraDns, DnsServerBootstrap::Vercel(_) => DnsServerBootstrapType::Vercel, DnsServerBootstrap::Volcengine(_) => DnsServerBootstrapType::Volcengine, DnsServerBootstrap::Vultr(_) => DnsServerBootstrapType::Vultr, DnsServerBootstrap::WebSupport(_) => DnsServerBootstrapType::WebSupport, DnsServerBootstrap::YandexCloud(_) => DnsServerBootstrapType::YandexCloud, } } } impl DnsServerClouDns { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.auth_id { if value.is_empty() { errors.push(ValidationError::required(Property::AuthId)); } } if let Some(value) = &self.sub_auth_id { if value.is_empty() { errors.push(ValidationError::required(Property::SubAuthId)); } } let value = &self.password; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerClouDns { fn pickle(&self, out: &mut Vec) { self.auth_id.pickle(out); self.sub_auth_id.pickle(out); self.password.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.auth_id = Pickle::unpickle(stream)?; this.sub_auth_id = Pickle::unpickle(stream)?; this.password = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerClouDns { fn default() -> Self { Self { auth_id: Default::default(), sub_auth_id: Default::default(), password: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerClouDns { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(12); map.insert_unchecked(Property::AuthId, self.auth_id.into_value()); map.insert_unchecked(Property::SubAuthId, self.sub_auth_id.into_value()); map.insert_unchecked(Property::Password, self.password.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerClouDns { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AuthId) => self .auth_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SubAuthId) => self .sub_auth_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Password) => self.password.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerCloud { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.secret; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerCloud { fn pickle(&self, out: &mut Vec) { self.secret.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.secret = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerCloud { fn default() -> Self { Self { secret: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerCloud { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(10); map.insert_unchecked(Property::Secret, self.secret.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerCloud { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Secret) => self.secret.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerCloudflare { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.secret; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerCloudflare { fn pickle(&self, out: &mut Vec) { self.secret.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); if stream.version() < 1 { let _: Option = Pickle::unpickle(stream)?; } this.secret = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerCloudflare { fn default() -> Self { Self { secret: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerCloudflare { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(10); map.insert_unchecked(Property::Secret, self.secret.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerCloudflare { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(property @ Property::Email) => Ok(MaybeUnpatched::Unpatched { property, value }), Some(Property::Secret) => self.secret.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerConstellix { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.api_key; if value.is_empty() { errors.push(ValidationError::required(Property::ApiKey)); } let value = &self.secret_key; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerConstellix { fn pickle(&self, out: &mut Vec) { self.api_key.pickle(out); self.secret_key.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.api_key = Pickle::unpickle(stream)?; this.secret_key = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerConstellix { fn default() -> Self { Self { api_key: Default::default(), secret_key: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerConstellix { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::ApiKey, self.api_key.into_value()); map.insert_unchecked(Property::SecretKey, self.secret_key.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerConstellix { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ApiKey) => self .api_key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SecretKey) => self.secret_key.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerCpanel { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.base_url; if value.is_empty() { errors.push(ValidationError::required(Property::BaseUrl)); } let value = &self.username; if value.is_empty() { errors.push(ValidationError::required(Property::Username)); } let value = &self.token; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerCpanel { fn pickle(&self, out: &mut Vec) { self.base_url.pickle(out); self.username.pickle(out); self.token.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.base_url = Pickle::unpickle(stream)?; this.username = Pickle::unpickle(stream)?; this.token = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerCpanel { fn default() -> Self { Self { base_url: Default::default(), username: Default::default(), token: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerCpanel { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(12); map.insert_unchecked(Property::BaseUrl, self.base_url.into_value()); map.insert_unchecked(Property::Username, self.username.into_value()); map.insert_unchecked(Property::Token, self.token.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerCpanel { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::BaseUrl) => self .base_url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Username) => self .username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Token) => self.token.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerDnsMadeEasy { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.api_key; if value.is_empty() { errors.push(ValidationError::required(Property::ApiKey)); } let value = &self.secret; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerDnsMadeEasy { fn pickle(&self, out: &mut Vec) { self.api_key.pickle(out); self.secret.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.api_key = Pickle::unpickle(stream)?; this.secret = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerDnsMadeEasy { fn default() -> Self { Self { api_key: Default::default(), secret: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerDnsMadeEasy { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::ApiKey, self.api_key.into_value()); map.insert_unchecked(Property::Secret, self.secret.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerDnsMadeEasy { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ApiKey) => self .api_key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Secret) => self.secret.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerDnsimple { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.auth_token; value.validate(errors); let value = &self.account_identifier; if value.is_empty() { errors.push(ValidationError::required(Property::AccountIdentifier)); } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerDnsimple { fn pickle(&self, out: &mut Vec) { self.auth_token.pickle(out); self.account_identifier.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.auth_token = Pickle::unpickle(stream)?; this.account_identifier = Pickle::unpickle(stream)?; if stream.version() < 1 { let _: SecretKey = Pickle::unpickle(stream)?; } this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerDnsimple { fn default() -> Self { Self { auth_token: Default::default(), account_identifier: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerDnsimple { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::AuthToken, self.auth_token.into_value()); map.insert_unchecked( Property::AccountIdentifier, self.account_identifier.into_value(), ); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerDnsimple { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AuthToken) => self.auth_token.patch(pointer, value), Some(Property::AccountIdentifier) => self .account_identifier .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(property @ Property::Secret) => Ok(MaybeUnpatched::Unpatched { property, value }), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerDomeneshop { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.auth_token; if value.is_empty() { errors.push(ValidationError::required(Property::AuthToken)); } let value = &self.secret; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerDomeneshop { fn pickle(&self, out: &mut Vec) { self.auth_token.pickle(out); self.secret.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.auth_token = Pickle::unpickle(stream)?; this.secret = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerDomeneshop { fn default() -> Self { Self { auth_token: Default::default(), secret: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerDomeneshop { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::AuthToken, self.auth_token.into_value()); map.insert_unchecked(Property::Secret, self.secret.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerDomeneshop { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AuthToken) => self .auth_token .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Secret) => self.secret.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerEasyDns { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.token; if value.is_empty() { errors.push(ValidationError::required(Property::Token)); } let value = &self.key; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerEasyDns { fn pickle(&self, out: &mut Vec) { self.token.pickle(out); self.key.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.token = Pickle::unpickle(stream)?; this.key = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerEasyDns { fn default() -> Self { Self { token: Default::default(), key: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerEasyDns { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::Token, self.token.into_value()); map.insert_unchecked(Property::Key, self.key.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerEasyDns { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Token) => self .token .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Key) => self.key.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerEdgeDns { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.host; if value.is_empty() { errors.push(ValidationError::required(Property::Host)); } let value = &self.client_token; if value.is_empty() { errors.push(ValidationError::required(Property::ClientToken)); } let value = &self.client_secret; value.validate(errors); let value = &self.access_token; value.validate(errors); if let Some(value) = &self.account_switch_key { if value.is_empty() { errors.push(ValidationError::required(Property::AccountSwitchKey)); } } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerEdgeDns { fn pickle(&self, out: &mut Vec) { self.host.pickle(out); self.client_token.pickle(out); self.client_secret.pickle(out); self.access_token.pickle(out); self.account_switch_key.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.host = Pickle::unpickle(stream)?; this.client_token = Pickle::unpickle(stream)?; this.client_secret = Pickle::unpickle(stream)?; this.access_token = Pickle::unpickle(stream)?; this.account_switch_key = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerEdgeDns { fn default() -> Self { Self { host: Default::default(), client_token: Default::default(), client_secret: Default::default(), access_token: Default::default(), account_switch_key: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerEdgeDns { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked(Property::Host, self.host.into_value()); map.insert_unchecked(Property::ClientToken, self.client_token.into_value()); map.insert_unchecked(Property::ClientSecret, self.client_secret.into_value()); map.insert_unchecked(Property::AccessToken, self.access_token.into_value()); map.insert_unchecked( Property::AccountSwitchKey, self.account_switch_key.into_value(), ); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerEdgeDns { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Host) => self .host .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ClientToken) => self .client_token .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ClientSecret) => self.client_secret.patch(pointer, value), Some(Property::AccessToken) => self.access_token.patch(pointer, value), Some(Property::AccountSwitchKey) => self .account_switch_key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerExoscale { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.api_key; if value.is_empty() { errors.push(ValidationError::required(Property::ApiKey)); } let value = &self.secret; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerExoscale { fn pickle(&self, out: &mut Vec) { self.api_key.pickle(out); self.secret.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.api_key = Pickle::unpickle(stream)?; this.secret = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerExoscale { fn default() -> Self { Self { api_key: Default::default(), secret: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerExoscale { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::ApiKey, self.api_key.into_value()); map.insert_unchecked(Property::Secret, self.secret.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerExoscale { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ApiKey) => self .api_key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Secret) => self.secret.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerGlesys { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.api_user; if value.is_empty() { errors.push(ValidationError::required(Property::ApiUser)); } let value = &self.api_key; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerGlesys { fn pickle(&self, out: &mut Vec) { self.api_user.pickle(out); self.api_key.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.api_user = Pickle::unpickle(stream)?; this.api_key = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerGlesys { fn default() -> Self { Self { api_user: Default::default(), api_key: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerGlesys { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::ApiUser, self.api_user.into_value()); map.insert_unchecked(Property::ApiKey, self.api_key.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerGlesys { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ApiUser) => self .api_user .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ApiKey) => self.api_key.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerGodaddy { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.api_key; if value.is_empty() { errors.push(ValidationError::required(Property::ApiKey)); } let value = &self.secret; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerGodaddy { fn pickle(&self, out: &mut Vec) { self.api_key.pickle(out); self.secret.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.api_key = Pickle::unpickle(stream)?; this.secret = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerGodaddy { fn default() -> Self { Self { api_key: Default::default(), secret: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerGodaddy { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::ApiKey, self.api_key.into_value()); map.insert_unchecked(Property::Secret, self.secret.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerGodaddy { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ApiKey) => self .api_key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Secret) => self.secret.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerGoogleCloudDns { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.service_account_json; value.validate(errors); let value = &self.project_id; if value.is_empty() { errors.push(ValidationError::required(Property::ProjectId)); } if let Some(value) = &self.managed_zone { if value.is_empty() { errors.push(ValidationError::required(Property::ManagedZone)); } } if let Some(value) = &self.impersonate_service_account { if value.is_empty() { errors.push(ValidationError::required( Property::ImpersonateServiceAccount, )); } } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerGoogleCloudDns { fn pickle(&self, out: &mut Vec) { self.service_account_json.pickle(out); self.project_id.pickle(out); self.managed_zone.pickle(out); self.private_zone.pickle(out); self.impersonate_service_account.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.service_account_json = Pickle::unpickle(stream)?; this.project_id = Pickle::unpickle(stream)?; this.managed_zone = Pickle::unpickle(stream)?; this.private_zone = Pickle::unpickle(stream)?; this.impersonate_service_account = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerGoogleCloudDns { fn default() -> Self { Self { service_account_json: Default::default(), project_id: Default::default(), managed_zone: Default::default(), private_zone: false, impersonate_service_account: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerGoogleCloudDns { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked( Property::ServiceAccountJson, self.service_account_json.into_value(), ); map.insert_unchecked(Property::ProjectId, self.project_id.into_value()); map.insert_unchecked(Property::ManagedZone, self.managed_zone.into_value()); map.insert_unchecked(Property::PrivateZone, self.private_zone.into_value()); map.insert_unchecked( Property::ImpersonateServiceAccount, self.impersonate_service_account.into_value(), ); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerGoogleCloudDns { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ServiceAccountJson) => self.service_account_json.patch(pointer, value), Some(Property::ProjectId) => self .project_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ManagedZone) => self .managed_zone .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::PrivateZone) => self.private_zone.patch(pointer, value), Some(Property::ImpersonateServiceAccount) => self .impersonate_service_account .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerHuaweiCloud { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.access_key; if value.is_empty() { errors.push(ValidationError::required(Property::AccessKey)); } let value = &self.secret_key; value.validate(errors); let value = &self.region; if value.is_empty() { errors.push(ValidationError::required(Property::Region)); } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerHuaweiCloud { fn pickle(&self, out: &mut Vec) { self.access_key.pickle(out); self.secret_key.pickle(out); self.region.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.access_key = Pickle::unpickle(stream)?; this.secret_key = Pickle::unpickle(stream)?; this.region = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerHuaweiCloud { fn default() -> Self { Self { access_key: Default::default(), secret_key: Default::default(), region: "ap-southeast-1".to_string(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerHuaweiCloud { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(12); map.insert_unchecked(Property::AccessKey, self.access_key.into_value()); map.insert_unchecked(Property::SecretKey, self.secret_key.into_value()); map.insert_unchecked(Property::Region, self.region.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerHuaweiCloud { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AccessKey) => self .access_key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SecretKey) => self.secret_key.patch(pointer, value), Some(Property::Region) => self .region .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerHurricane { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.credentials; for value in value.values() { value.validate(errors); } if value.len() < 1 { errors.push(ValidationError::min_items(Property::Credentials, 1)); } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerHurricane { fn pickle(&self, out: &mut Vec) { self.credentials.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.credentials = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerHurricane { fn default() -> Self { Self { credentials: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerHurricane { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(10); map.insert_unchecked(Property::Credentials, self.credentials.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerHurricane { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Credentials) => self.credentials.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerIbmCloud { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.username; if value.is_empty() { errors.push(ValidationError::required(Property::Username)); } let value = &self.api_key; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerIbmCloud { fn pickle(&self, out: &mut Vec) { self.username.pickle(out); self.api_key.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.username = Pickle::unpickle(stream)?; this.api_key = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerIbmCloud { fn default() -> Self { Self { username: Default::default(), api_key: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerIbmCloud { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::Username, self.username.into_value()); map.insert_unchecked(Property::ApiKey, self.api_key.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerIbmCloud { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Username) => self .username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ApiKey) => self.api_key.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerInfoblox { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.host; if value.is_empty() { errors.push(ValidationError::required(Property::Host)); } if let Some(value) = &self.port { if value.is_empty() { errors.push(ValidationError::required(Property::Port)); } } let value = &self.username; if value.is_empty() { errors.push(ValidationError::required(Property::Username)); } let value = &self.password; value.validate(errors); if let Some(value) = &self.wapi_version { if value.is_empty() { errors.push(ValidationError::required(Property::WapiVersion)); } } if let Some(value) = &self.dns_view { if value.is_empty() { errors.push(ValidationError::required(Property::DnsView)); } } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerInfoblox { fn pickle(&self, out: &mut Vec) { self.host.pickle(out); self.port.pickle(out); self.username.pickle(out); self.password.pickle(out); self.wapi_version.pickle(out); self.dns_view.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.host = Pickle::unpickle(stream)?; this.port = Pickle::unpickle(stream)?; this.username = Pickle::unpickle(stream)?; this.password = Pickle::unpickle(stream)?; this.wapi_version = Pickle::unpickle(stream)?; this.dns_view = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerInfoblox { fn default() -> Self { Self { host: Default::default(), port: Default::default(), username: Default::default(), password: Default::default(), wapi_version: Default::default(), dns_view: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerInfoblox { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(15); map.insert_unchecked(Property::Host, self.host.into_value()); map.insert_unchecked(Property::Port, self.port.into_value()); map.insert_unchecked(Property::Username, self.username.into_value()); map.insert_unchecked(Property::Password, self.password.into_value()); map.insert_unchecked(Property::WapiVersion, self.wapi_version.into_value()); map.insert_unchecked(Property::DnsView, self.dns_view.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerInfoblox { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Host) => self .host .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Port) => self .port .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Username) => self .username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Password) => self.password.patch(pointer, value), Some(Property::WapiVersion) => self .wapi_version .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::DnsView) => self .dns_view .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerInwx { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.username; if value.is_empty() { errors.push(ValidationError::required(Property::Username)); } let value = &self.password; value.validate(errors); let value = &self.shared_secret; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerInwx { fn pickle(&self, out: &mut Vec) { self.username.pickle(out); self.password.pickle(out); self.shared_secret.pickle(out); self.sandbox.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.username = Pickle::unpickle(stream)?; this.password = Pickle::unpickle(stream)?; this.shared_secret = Pickle::unpickle(stream)?; this.sandbox = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerInwx { fn default() -> Self { Self { username: Default::default(), password: Default::default(), shared_secret: Default::default(), sandbox: false, description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerInwx { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(13); map.insert_unchecked(Property::Username, self.username.into_value()); map.insert_unchecked(Property::Password, self.password.into_value()); map.insert_unchecked(Property::SharedSecret, self.shared_secret.into_value()); map.insert_unchecked(Property::Sandbox, self.sandbox.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerInwx { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Username) => self .username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Password) => self.password.patch(pointer, value), Some(Property::SharedSecret) => self.shared_secret.patch(pointer, value), Some(Property::Sandbox) => self.sandbox.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerJoker { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.auth; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerJoker { fn pickle(&self, out: &mut Vec) { self.auth.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.auth = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerJoker { fn default() -> Self { Self { auth: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerJoker { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(10); map.insert_unchecked(Property::Auth, self.auth.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerJoker { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Auth) => self.auth.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerLightsail { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.access_key_id; if value.is_empty() { errors.push(ValidationError::required(Property::AccessKeyId)); } let value = &self.secret_access_key; value.validate(errors); let value = &self.session_token; value.validate(errors); if let Some(value) = &self.region { if value.is_empty() { errors.push(ValidationError::required(Property::Region)); } } if let Some(value) = &self.domain { if value.is_empty() { errors.push(ValidationError::required(Property::Domain)); } } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerLightsail { fn pickle(&self, out: &mut Vec) { self.access_key_id.pickle(out); self.secret_access_key.pickle(out); self.session_token.pickle(out); self.region.pickle(out); self.domain.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.access_key_id = Pickle::unpickle(stream)?; this.secret_access_key = Pickle::unpickle(stream)?; this.session_token = Pickle::unpickle(stream)?; this.region = Pickle::unpickle(stream)?; this.domain = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerLightsail { fn default() -> Self { Self { access_key_id: Default::default(), secret_access_key: Default::default(), session_token: Default::default(), region: Default::default(), domain: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerLightsail { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked(Property::AccessKeyId, self.access_key_id.into_value()); map.insert_unchecked( Property::SecretAccessKey, self.secret_access_key.into_value(), ); map.insert_unchecked(Property::SessionToken, self.session_token.into_value()); map.insert_unchecked(Property::Region, self.region.into_value()); map.insert_unchecked(Property::Domain, self.domain.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerLightsail { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AccessKeyId) => self .access_key_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SecretAccessKey) => self.secret_access_key.patch(pointer, value), Some(Property::SessionToken) => self.session_token.patch(pointer, value), Some(Property::Region) => self .region .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Domain) => self .domain .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerLuaDns { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.username; if value.is_empty() { errors.push(ValidationError::required(Property::Username)); } let value = &self.auth_token; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerLuaDns { fn pickle(&self, out: &mut Vec) { self.username.pickle(out); self.auth_token.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.username = Pickle::unpickle(stream)?; this.auth_token = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerLuaDns { fn default() -> Self { Self { username: Default::default(), auth_token: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerLuaDns { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::Username, self.username.into_value()); map.insert_unchecked(Property::AuthToken, self.auth_token.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerLuaDns { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Username) => self .username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AuthToken) => self.auth_token.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerMythicBeasts { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.username; if value.is_empty() { errors.push(ValidationError::required(Property::Username)); } let value = &self.password; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerMythicBeasts { fn pickle(&self, out: &mut Vec) { self.username.pickle(out); self.password.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.username = Pickle::unpickle(stream)?; this.password = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerMythicBeasts { fn default() -> Self { Self { username: Default::default(), password: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerMythicBeasts { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::Username, self.username.into_value()); map.insert_unchecked(Property::Password, self.password.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerMythicBeasts { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Username) => self .username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Password) => self.password.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerNameDotCom { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.username; if value.is_empty() { errors.push(ValidationError::required(Property::Username)); } let value = &self.auth_token; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerNameDotCom { fn pickle(&self, out: &mut Vec) { self.username.pickle(out); self.auth_token.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.username = Pickle::unpickle(stream)?; this.auth_token = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerNameDotCom { fn default() -> Self { Self { username: Default::default(), auth_token: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerNameDotCom { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::Username, self.username.into_value()); map.insert_unchecked(Property::AuthToken, self.auth_token.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerNameDotCom { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Username) => self .username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AuthToken) => self.auth_token.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerNamecheap { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.api_user; if value.is_empty() { errors.push(ValidationError::required(Property::ApiUser)); } let value = &self.api_key; value.validate(errors); let value = &self.client_ip; if value.is_empty() { errors.push(ValidationError::required(Property::ClientIp)); } if let Some(value) = &self.username { if value.is_empty() { errors.push(ValidationError::required(Property::Username)); } } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerNamecheap { fn pickle(&self, out: &mut Vec) { self.api_user.pickle(out); self.api_key.pickle(out); self.client_ip.pickle(out); self.username.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.api_user = Pickle::unpickle(stream)?; this.api_key = Pickle::unpickle(stream)?; this.client_ip = Pickle::unpickle(stream)?; this.username = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerNamecheap { fn default() -> Self { Self { api_user: Default::default(), api_key: Default::default(), client_ip: Default::default(), username: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerNamecheap { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(13); map.insert_unchecked(Property::ApiUser, self.api_user.into_value()); map.insert_unchecked(Property::ApiKey, self.api_key.into_value()); map.insert_unchecked(Property::ClientIp, self.client_ip.into_value()); map.insert_unchecked(Property::Username, self.username.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerNamecheap { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ApiUser) => self .api_user .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ApiKey) => self.api_key.patch(pointer, value), Some(Property::ClientIp) => self .client_ip .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Username) => self .username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerNetcup { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.customer_number; if value.is_empty() { errors.push(ValidationError::required(Property::CustomerNumber)); } let value = &self.api_key; if value.is_empty() { errors.push(ValidationError::required(Property::ApiKey)); } let value = &self.password; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerNetcup { fn pickle(&self, out: &mut Vec) { self.customer_number.pickle(out); self.api_key.pickle(out); self.password.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.customer_number = Pickle::unpickle(stream)?; this.api_key = Pickle::unpickle(stream)?; this.password = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerNetcup { fn default() -> Self { Self { customer_number: Default::default(), api_key: Default::default(), password: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerNetcup { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(12); map.insert_unchecked(Property::CustomerNumber, self.customer_number.into_value()); map.insert_unchecked(Property::ApiKey, self.api_key.into_value()); map.insert_unchecked(Property::Password, self.password.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerNetcup { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::CustomerNumber) => self .customer_number .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ApiKey) => self .api_key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Password) => self.password.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerNifcloud { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.access_key; if value.is_empty() { errors.push(ValidationError::required(Property::AccessKey)); } let value = &self.secret_key; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerNifcloud { fn pickle(&self, out: &mut Vec) { self.access_key.pickle(out); self.secret_key.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.access_key = Pickle::unpickle(stream)?; this.secret_key = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerNifcloud { fn default() -> Self { Self { access_key: Default::default(), secret_key: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerNifcloud { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::AccessKey, self.access_key.into_value()); map.insert_unchecked(Property::SecretKey, self.secret_key.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerNifcloud { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AccessKey) => self .access_key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SecretKey) => self.secret_key.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerOracleCloud { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.tenancy_ocid; if value.is_empty() { errors.push(ValidationError::required(Property::TenancyOcid)); } let value = &self.user_ocid; if value.is_empty() { errors.push(ValidationError::required(Property::UserOcid)); } let value = &self.fingerprint; if value.is_empty() { errors.push(ValidationError::required(Property::Fingerprint)); } let value = &self.private_key_pem; value.validate(errors); let value = &self.private_key_password; value.validate(errors); let value = &self.region; if value.is_empty() { errors.push(ValidationError::required(Property::Region)); } let value = &self.compartment_ocid; if value.is_empty() { errors.push(ValidationError::required(Property::CompartmentOcid)); } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerOracleCloud { fn pickle(&self, out: &mut Vec) { self.tenancy_ocid.pickle(out); self.user_ocid.pickle(out); self.fingerprint.pickle(out); self.private_key_pem.pickle(out); self.private_key_password.pickle(out); self.region.pickle(out); self.compartment_ocid.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.tenancy_ocid = Pickle::unpickle(stream)?; this.user_ocid = Pickle::unpickle(stream)?; this.fingerprint = Pickle::unpickle(stream)?; this.private_key_pem = Pickle::unpickle(stream)?; this.private_key_password = Pickle::unpickle(stream)?; this.region = Pickle::unpickle(stream)?; this.compartment_ocid = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerOracleCloud { fn default() -> Self { Self { tenancy_ocid: Default::default(), user_ocid: Default::default(), fingerprint: Default::default(), private_key_pem: Default::default(), private_key_password: Default::default(), region: Default::default(), compartment_ocid: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerOracleCloud { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(16); map.insert_unchecked(Property::TenancyOcid, self.tenancy_ocid.into_value()); map.insert_unchecked(Property::UserOcid, self.user_ocid.into_value()); map.insert_unchecked(Property::Fingerprint, self.fingerprint.into_value()); map.insert_unchecked(Property::PrivateKeyPem, self.private_key_pem.into_value()); map.insert_unchecked( Property::PrivateKeyPassword, self.private_key_password.into_value(), ); map.insert_unchecked(Property::Region, self.region.into_value()); map.insert_unchecked( Property::CompartmentOcid, self.compartment_ocid.into_value(), ); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerOracleCloud { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::TenancyOcid) => self .tenancy_ocid .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::UserOcid) => self .user_ocid .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Fingerprint) => self .fingerprint .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::PrivateKeyPem) => self.private_key_pem.patch(pointer, value), Some(Property::PrivateKeyPassword) => self.private_key_password.patch(pointer, value), Some(Property::Region) => self .region .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::CompartmentOcid) => self .compartment_ocid .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerOvh { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.application_key; if value.is_empty() { errors.push(ValidationError::required(Property::ApplicationKey)); } let value = &self.application_secret; value.validate(errors); let value = &self.consumer_key; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerOvh { fn pickle(&self, out: &mut Vec) { self.application_key.pickle(out); self.application_secret.pickle(out); self.consumer_key.pickle(out); self.ovh_endpoint.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.application_key = Pickle::unpickle(stream)?; this.application_secret = Pickle::unpickle(stream)?; this.consumer_key = Pickle::unpickle(stream)?; this.ovh_endpoint = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerOvh { fn default() -> Self { Self { application_key: Default::default(), application_secret: Default::default(), consumer_key: Default::default(), ovh_endpoint: OvhEndpoint::OvhEu, description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerOvh { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(13); map.insert_unchecked(Property::ApplicationKey, self.application_key.into_value()); map.insert_unchecked( Property::ApplicationSecret, self.application_secret.into_value(), ); map.insert_unchecked(Property::ConsumerKey, self.consumer_key.into_value()); map.insert_unchecked(Property::OvhEndpoint, self.ovh_endpoint.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerOvh { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ApplicationKey) => self .application_key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ApplicationSecret) => self.application_secret.patch(pointer, value), Some(Property::ConsumerKey) => self.consumer_key.patch(pointer, value), Some(Property::OvhEndpoint) => self.ovh_endpoint.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerPlesk { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.base_url; if value.is_empty() { errors.push(ValidationError::required(Property::BaseUrl)); } let value = &self.api_key; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerPlesk { fn pickle(&self, out: &mut Vec) { self.base_url.pickle(out); self.api_key.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.base_url = Pickle::unpickle(stream)?; this.api_key = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerPlesk { fn default() -> Self { Self { base_url: Default::default(), api_key: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerPlesk { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::BaseUrl, self.base_url.into_value()); map.insert_unchecked(Property::ApiKey, self.api_key.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerPlesk { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::BaseUrl) => self .base_url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ApiKey) => self.api_key.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerPorkbun { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.api_key; if value.is_empty() { errors.push(ValidationError::required(Property::ApiKey)); } let value = &self.secret_api_key; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerPorkbun { fn pickle(&self, out: &mut Vec) { self.api_key.pickle(out); self.secret_api_key.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.api_key = Pickle::unpickle(stream)?; this.secret_api_key = Pickle::unpickle(stream)?; if stream.version() < 1 { let _: SecretKey = Pickle::unpickle(stream)?; } this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerPorkbun { fn default() -> Self { Self { api_key: Default::default(), secret_api_key: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerPorkbun { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::ApiKey, self.api_key.into_value()); map.insert_unchecked(Property::SecretApiKey, self.secret_api_key.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerPorkbun { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ApiKey) => self .api_key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SecretApiKey) => self.secret_api_key.patch(pointer, value), Some(property @ Property::Secret) => Ok(MaybeUnpatched::Unpatched { property, value }), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerRoute53 { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.access_key_id; if value.is_empty() { errors.push(ValidationError::required(Property::AccessKeyId)); } let value = &self.secret_access_key; value.validate(errors); let value = &self.session_token; value.validate(errors); let value = &self.region; if value.is_empty() { errors.push(ValidationError::required(Property::Region)); } if let Some(value) = &self.hosted_zone_id { if value.is_empty() { errors.push(ValidationError::required(Property::HostedZoneId)); } } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerRoute53 { fn pickle(&self, out: &mut Vec) { self.access_key_id.pickle(out); self.secret_access_key.pickle(out); self.session_token.pickle(out); self.region.pickle(out); self.hosted_zone_id.pickle(out); self.private_zone_only.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.access_key_id = Pickle::unpickle(stream)?; this.secret_access_key = Pickle::unpickle(stream)?; this.session_token = Pickle::unpickle(stream)?; this.region = Pickle::unpickle(stream)?; this.hosted_zone_id = Pickle::unpickle(stream)?; this.private_zone_only = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerRoute53 { fn default() -> Self { Self { access_key_id: Default::default(), secret_access_key: Default::default(), session_token: Default::default(), region: "us-east-1".to_string(), hosted_zone_id: Default::default(), private_zone_only: false, description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerRoute53 { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(15); map.insert_unchecked(Property::AccessKeyId, self.access_key_id.into_value()); map.insert_unchecked( Property::SecretAccessKey, self.secret_access_key.into_value(), ); map.insert_unchecked(Property::SessionToken, self.session_token.into_value()); map.insert_unchecked(Property::Region, self.region.into_value()); map.insert_unchecked(Property::HostedZoneId, self.hosted_zone_id.into_value()); map.insert_unchecked( Property::PrivateZoneOnly, self.private_zone_only.into_value(), ); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerRoute53 { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AccessKeyId) => self .access_key_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SecretAccessKey) => self.secret_access_key.patch(pointer, value), Some(Property::SessionToken) => self.session_token.patch(pointer, value), Some(Property::Region) => self .region .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::HostedZoneId) => self .hosted_zone_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::PrivateZoneOnly) => self.private_zone_only.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerSpaceship { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.api_key; if value.is_empty() { errors.push(ValidationError::required(Property::ApiKey)); } let value = &self.secret; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerSpaceship { fn pickle(&self, out: &mut Vec) { self.api_key.pickle(out); self.secret.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.api_key = Pickle::unpickle(stream)?; this.secret = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerSpaceship { fn default() -> Self { Self { api_key: Default::default(), secret: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerSpaceship { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::ApiKey, self.api_key.into_value()); map.insert_unchecked(Property::Secret, self.secret.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerSpaceship { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ApiKey) => self .api_key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Secret) => self.secret.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerTencentCloud { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.secret_id; if value.is_empty() { errors.push(ValidationError::required(Property::SecretId)); } let value = &self.secret_key; value.validate(errors); if let Some(value) = &self.region { if value.is_empty() { errors.push(ValidationError::required(Property::Region)); } } let value = &self.session_token; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerTencentCloud { fn pickle(&self, out: &mut Vec) { self.secret_id.pickle(out); self.secret_key.pickle(out); self.region.pickle(out); self.session_token.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.secret_id = Pickle::unpickle(stream)?; this.secret_key = Pickle::unpickle(stream)?; this.region = Pickle::unpickle(stream)?; this.session_token = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerTencentCloud { fn default() -> Self { Self { secret_id: Default::default(), secret_key: Default::default(), region: Default::default(), session_token: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerTencentCloud { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(13); map.insert_unchecked(Property::SecretId, self.secret_id.into_value()); map.insert_unchecked(Property::SecretKey, self.secret_key.into_value()); map.insert_unchecked(Property::Region, self.region.into_value()); map.insert_unchecked(Property::SessionToken, self.session_token.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerTencentCloud { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::SecretId) => self .secret_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SecretKey) => self.secret_key.patch(pointer, value), Some(Property::Region) => self .region .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SessionToken) => self.session_token.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerTransip { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.username; if value.is_empty() { errors.push(ValidationError::required(Property::Username)); } let value = &self.private_key_pem; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerTransip { fn pickle(&self, out: &mut Vec) { self.username.pickle(out); self.private_key_pem.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.username = Pickle::unpickle(stream)?; this.private_key_pem = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerTransip { fn default() -> Self { Self { username: Default::default(), private_key_pem: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerTransip { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::Username, self.username.into_value()); map.insert_unchecked(Property::PrivateKeyPem, self.private_key_pem.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerTransip { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Username) => self .username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::PrivateKeyPem) => self.private_key_pem.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerTsig { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.host; if !value.is_valid() { errors.push(ValidationError::invalid(Property::Host, value)); } let value = &self.port; if *value > 65535 { errors.push(ValidationError::max_value(Property::Port, 65535)); } if *value < 1 { errors.push(ValidationError::min_value(Property::Port, 1)); } let value = &self.key_name; if value.is_empty() { errors.push(ValidationError::required(Property::KeyName)); } let value = &self.key; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerTsig { fn pickle(&self, out: &mut Vec) { self.host.pickle(out); self.port.pickle(out); self.key_name.pickle(out); self.key.pickle(out); self.protocol.pickle(out); self.tsig_algorithm.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.host = Pickle::unpickle(stream)?; this.port = Pickle::unpickle(stream)?; this.key_name = Pickle::unpickle(stream)?; this.key = Pickle::unpickle(stream)?; this.protocol = Pickle::unpickle(stream)?; this.tsig_algorithm = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerTsig { fn default() -> Self { Self { host: Default::default(), port: 53u64, key_name: Default::default(), key: Default::default(), protocol: IpProtocol::Udp, tsig_algorithm: TsigAlgorithm::HmacSha512, description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerTsig { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(15); map.insert_unchecked(Property::Host, self.host.into_value()); map.insert_unchecked(Property::Port, self.port.into_value()); map.insert_unchecked(Property::KeyName, self.key_name.into_value()); map.insert_unchecked(Property::Key, self.key.into_value()); map.insert_unchecked(Property::Protocol, self.protocol.into_value()); map.insert_unchecked(Property::TsigAlgorithm, self.tsig_algorithm.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerTsig { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Host) => self .host .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Port) => self.port.patch(pointer, value), Some(Property::KeyName) => self .key_name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Key) => self.key.patch(pointer, value), Some(Property::Protocol) => self.protocol.patch(pointer, value), Some(Property::TsigAlgorithm) => self.tsig_algorithm.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerUltraDns { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.username; if value.is_empty() { errors.push(ValidationError::required(Property::Username)); } let value = &self.password; value.validate(errors); if let Some(value) = &self.endpoint { if value.is_empty() { errors.push(ValidationError::required(Property::Endpoint)); } } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerUltraDns { fn pickle(&self, out: &mut Vec) { self.username.pickle(out); self.password.pickle(out); self.endpoint.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.username = Pickle::unpickle(stream)?; this.password = Pickle::unpickle(stream)?; this.endpoint = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerUltraDns { fn default() -> Self { Self { username: Default::default(), password: Default::default(), endpoint: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerUltraDns { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(12); map.insert_unchecked(Property::Username, self.username.into_value()); map.insert_unchecked(Property::Password, self.password.into_value()); map.insert_unchecked(Property::Endpoint, self.endpoint.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerUltraDns { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Username) => self .username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Password) => self.password.patch(pointer, value), Some(Property::Endpoint) => self .endpoint .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerVercel { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.auth_token; value.validate(errors); if let Some(value) = &self.team_id { if value.is_empty() { errors.push(ValidationError::required(Property::TeamId)); } } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerVercel { fn pickle(&self, out: &mut Vec) { self.auth_token.pickle(out); self.team_id.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.auth_token = Pickle::unpickle(stream)?; this.team_id = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerVercel { fn default() -> Self { Self { auth_token: Default::default(), team_id: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerVercel { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::AuthToken, self.auth_token.into_value()); map.insert_unchecked(Property::TeamId, self.team_id.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerVercel { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AuthToken) => self.auth_token.patch(pointer, value), Some(Property::TeamId) => self .team_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerVolcengine { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.access_key; if value.is_empty() { errors.push(ValidationError::required(Property::AccessKey)); } let value = &self.secret_key; value.validate(errors); if let Some(value) = &self.region { if value.is_empty() { errors.push(ValidationError::required(Property::Region)); } } if let Some(value) = &self.host { if value.is_empty() { errors.push(ValidationError::required(Property::Host)); } } if let Some(value) = &self.scheme { if value.is_empty() { errors.push(ValidationError::required(Property::Scheme)); } } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerVolcengine { fn pickle(&self, out: &mut Vec) { self.access_key.pickle(out); self.secret_key.pickle(out); self.region.pickle(out); self.host.pickle(out); self.scheme.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.access_key = Pickle::unpickle(stream)?; this.secret_key = Pickle::unpickle(stream)?; this.region = Pickle::unpickle(stream)?; this.host = Pickle::unpickle(stream)?; this.scheme = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerVolcengine { fn default() -> Self { Self { access_key: Default::default(), secret_key: Default::default(), region: Default::default(), host: Default::default(), scheme: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerVolcengine { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked(Property::AccessKey, self.access_key.into_value()); map.insert_unchecked(Property::SecretKey, self.secret_key.into_value()); map.insert_unchecked(Property::Region, self.region.into_value()); map.insert_unchecked(Property::Host, self.host.into_value()); map.insert_unchecked(Property::Scheme, self.scheme.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerVolcengine { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AccessKey) => self .access_key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SecretKey) => self.secret_key.patch(pointer, value), Some(Property::Region) => self .region .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Host) => self .host .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Scheme) => self .scheme .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerWebSupport { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.api_key; if value.is_empty() { errors.push(ValidationError::required(Property::ApiKey)); } let value = &self.secret; value.validate(errors); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerWebSupport { fn pickle(&self, out: &mut Vec) { self.api_key.pickle(out); self.secret.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.api_key = Pickle::unpickle(stream)?; this.secret = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerWebSupport { fn default() -> Self { Self { api_key: Default::default(), secret: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerWebSupport { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::ApiKey, self.api_key.into_value()); map.insert_unchecked(Property::Secret, self.secret.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerWebSupport { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ApiKey) => self .api_key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Secret) => self.secret.patch(pointer, value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl DnsServerYandexCloud { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.api_key; value.validate(errors); let value = &self.folder_id; if value.is_empty() { errors.push(ValidationError::required(Property::FolderId)); } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for DnsServerYandexCloud { fn pickle(&self, out: &mut Vec) { self.api_key.pickle(out); self.folder_id.pickle(out); self.description.pickle(out); self.member_tenant_id.pickle(out); self.timeout.pickle(out); self.ttl.pickle(out); self.polling_interval.pickle(out); self.propagation_timeout.pickle(out); self.propagation_delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.api_key = Pickle::unpickle(stream)?; this.folder_id = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.ttl = Pickle::unpickle(stream)?; this.polling_interval = Pickle::unpickle(stream)?; this.propagation_timeout = Pickle::unpickle(stream)?; this.propagation_delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for DnsServerYandexCloud { fn default() -> Self { Self { api_key: Default::default(), folder_id: Default::default(), description: Default::default(), member_tenant_id: Default::default(), timeout: Duration::from_millis(30000), ttl: Duration::from_millis(300000), polling_interval: Duration::from_millis(15000), propagation_timeout: Duration::from_millis(60000), propagation_delay: Default::default(), } } } impl IntoValue for DnsServerYandexCloud { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::ApiKey, self.api_key.into_value()); map.insert_unchecked(Property::FolderId, self.folder_id.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Ttl, self.ttl.into_value()); map.insert_unchecked( Property::PollingInterval, self.polling_interval.into_value(), ); map.insert_unchecked( Property::PropagationTimeout, self.propagation_timeout.into_value(), ); map.insert_unchecked( Property::PropagationDelay, self.propagation_delay.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DnsServerYandexCloud { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ApiKey) => self.api_key.patch(pointer, value), Some(Property::FolderId) => self .folder_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Ttl) => self.ttl.patch(pointer, value), Some(Property::PollingInterval) => self.polling_interval.patch(pointer, value), Some(Property::PropagationTimeout) => self.propagation_timeout.patch(pointer, value), Some(Property::PropagationDelay) => self.propagation_delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Domain { const FLAGS: u64 = OBJ_FILTER_TENANT | OBJ_SEQ_ID; const VERSION: u8 = 1; const OBJECT: ObjectType = ObjectType::Domain; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } let value = &self.aliases; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::Aliases)); } } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } if let Some(value) = &self.logo { if value.is_empty() { errors.push(ValidationError::required(Property::Logo)); } } let value = &self.certificate_management; value.validate(errors); let value = &self.dkim_management; value.validate(errors); let value = &self.dns_management; value.validate(errors); if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } if let Some(value) = &self.directory_id { if !value.is_valid() { errors.push(ValidationError::required(Property::DirectoryId)); } } if let Some(value) = &self.catch_all_address { if value.is_empty() { errors.push(ValidationError::required(Property::CatchAllAddress)); } } let value = &self.sub_addressing; value.validate(errors); if let Some(value) = &self.report_address_uri { if value.is_empty() { errors.push(ValidationError::required(Property::ReportAddressUri)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); i.text(Property::Text, &self.name); for value in self.aliases.iter() { i.unique(Property::Aliases, value); } for value in self.aliases.iter() { i.text(Property::Text, value); } if let Some(value) = &self.description { i.text(Property::Text, value); } self.certificate_management.index(i); self.dns_management.index(i); i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } i.foreign_key(ObjectType::Directory, self.directory_id, None); } } impl Pickle for Domain { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.aliases.pickle(out); self.is_enabled.pickle(out); self.created_at.pickle(out); self.description.pickle(out); self.logo.pickle(out); self.certificate_management.pickle(out); self.dkim_management.pickle(out); self.dns_management.pickle(out); self.member_tenant_id.pickle(out); self.directory_id.pickle(out); self.catch_all_address.pickle(out); self.sub_addressing.pickle(out); self.allow_relaying.pickle(out); self.report_address_uri.pickle(out); self.allow_scim_provisioning.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.aliases = Pickle::unpickle(stream)?; this.is_enabled = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.logo = Pickle::unpickle(stream)?; this.certificate_management = Pickle::unpickle(stream)?; this.dkim_management = Pickle::unpickle(stream)?; this.dns_management = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.directory_id = Pickle::unpickle(stream)?; this.catch_all_address = Pickle::unpickle(stream)?; this.sub_addressing = Pickle::unpickle(stream)?; this.allow_relaying = Pickle::unpickle(stream)?; this.report_address_uri = Pickle::unpickle(stream)?; if stream.version() >= 1 { this.allow_scim_provisioning = Pickle::unpickle(stream)?; } Some(this) } } impl Default for Domain { fn default() -> Self { Self { name: Default::default(), aliases: Default::default(), is_enabled: true, created_at: Default::default(), description: Default::default(), logo: Default::default(), certificate_management: Default::default(), dkim_management: Default::default(), dns_management: Default::default(), member_tenant_id: Default::default(), directory_id: Default::default(), catch_all_address: Default::default(), sub_addressing: Default::default(), allow_relaying: false, report_address_uri: Some("mailto:postmaster".to_string()), allow_scim_provisioning: false, } } } impl IntoValue for Domain { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(18); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Aliases, self.aliases.into_value()); map.insert_unchecked(Property::IsEnabled, self.is_enabled.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Logo, self.logo.into_value()); map.insert_unchecked( Property::CertificateManagement, self.certificate_management.into_value(), ); map.insert_unchecked(Property::DkimManagement, self.dkim_management.into_value()); map.insert_unchecked(Property::DnsManagement, self.dns_management.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::DirectoryId, self.directory_id.into_value()); map.insert_unchecked( Property::CatchAllAddress, self.catch_all_address.into_value(), ); map.insert_unchecked(Property::SubAddressing, self.sub_addressing.into_value()); map.insert_unchecked(Property::AllowRelaying, self.allow_relaying.into_value()); map.insert_unchecked( Property::ReportAddressUri, self.report_address_uri.into_value(), ); map.insert_unchecked( Property::AllowScimProvisioning, self.allow_scim_provisioning.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Domain { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self .name .patch(pointer.with_validators(&[StringValidator::Domain]), value), Some(Property::Aliases) => self .aliases .patch(pointer.with_validators(&[StringValidator::Domain]), value), Some(Property::IsEnabled) => self.is_enabled.patch(pointer, value), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Logo) => self.logo.patch(pointer, value), Some(Property::CertificateManagement) => { self.certificate_management.patch(pointer, value) } Some(Property::DkimManagement) => self.dkim_management.patch(pointer, value), Some(Property::DnsManagement) => self.dns_management.patch(pointer, value), Some(Property::DnsZoneFile) => pointer.assert_server_set(), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::DirectoryId) => self.directory_id.patch(pointer, value), Some(Property::CatchAllAddress) => self .catch_all_address .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::SubAddressing) => self.sub_addressing.patch(pointer, value), Some(Property::AllowRelaying) => self.allow_relaying.patch(pointer, value), Some(Property::ReportAddressUri) => self .report_address_uri .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AllowScimProvisioning) => { self.allow_scim_provisioning.patch(pointer, value) } Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for DsnReportSettings { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::DsnReportSettings; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.from_address; value.validate(errors); let value = &self.from_name; value.validate(errors); let value = &self.dkim_sign_domain; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl DsnReportSettings { pub fn ctx_from_address(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.from_address, default: Some(Expression { else_: "'MAILER-DAEMON@' + system('domain')".to_string(), ..Default::default() }), property: Property::FromAddress, allowed_variables: MTA_QUEUE_SENDER_VARIABLE, allowed_constants: &[], } } pub fn ctx_from_name(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.from_name, default: Some(Expression { else_: "'Mail Delivery Subsystem'".to_string(), ..Default::default() }), property: Property::FromName, allowed_variables: MTA_QUEUE_SENDER_VARIABLE, allowed_constants: &[], } } pub fn ctx_dkim_sign_domain(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.dkim_sign_domain, default: Some(Expression { else_: "system('domain')".to_string(), ..Default::default() }), property: Property::DkimSignDomain, allowed_variables: MTA_QUEUE_SENDER_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_from_address(), self.ctx_from_name(), self.ctx_dkim_sign_domain(), ] } } impl Pickle for DsnReportSettings { fn pickle(&self, out: &mut Vec) { self.from_address.pickle(out); self.from_name.pickle(out); self.dkim_sign_domain.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.from_address = Pickle::unpickle(stream)?; this.from_name = Pickle::unpickle(stream)?; this.dkim_sign_domain = Pickle::unpickle(stream)?; Some(this) } } impl Default for DsnReportSettings { fn default() -> Self { Self { from_address: Expression { else_: "'MAILER-DAEMON@' + system('domain')".to_string(), ..Default::default() }, from_name: Expression { else_: "'Mail Delivery Subsystem'".to_string(), ..Default::default() }, dkim_sign_domain: Expression { else_: "system('domain')".to_string(), ..Default::default() }, } } } impl IntoValue for DsnReportSettings { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::FromAddress, self.from_address.into_value()); map.insert_unchecked(Property::FromName, self.from_name.into_value()); map.insert_unchecked(Property::DkimSignDomain, self.dkim_sign_domain.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for DsnReportSettings { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::FromAddress) => self.from_address.patch(pointer, value), Some(Property::FromName) => self.from_name.patch(pointer, value), Some(Property::DkimSignDomain) => self.dkim_sign_domain.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ElasticSearchStore { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.url; if value.is_empty() { errors.push(ValidationError::required(Property::Url)); } let value = &self.num_replicas; if *value > 2048 { errors.push(ValidationError::max_value(Property::NumReplicas, 2048)); } let value = &self.num_shards; if *value > 1048576 { errors.push(ValidationError::max_value(Property::NumShards, 1048576)); } if *value < 1 { errors.push(ValidationError::min_value(Property::NumShards, 1)); } let value = &self.http_auth; value.validate(errors); let value = &self.http_headers; for value in value.values() { if value.is_empty() { errors.push(ValidationError::required(Property::HttpHeaders)); } } errors.len() == neb } } impl Pickle for ElasticSearchStore { fn pickle(&self, out: &mut Vec) { self.url.pickle(out); self.num_replicas.pickle(out); self.num_shards.pickle(out); self.include_source.pickle(out); self.timeout.pickle(out); self.allow_invalid_certs.pickle(out); self.http_auth.pickle(out); self.http_headers.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.url = Pickle::unpickle(stream)?; this.num_replicas = Pickle::unpickle(stream)?; this.num_shards = Pickle::unpickle(stream)?; this.include_source = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.allow_invalid_certs = Pickle::unpickle(stream)?; this.http_auth = Pickle::unpickle(stream)?; this.http_headers = Pickle::unpickle(stream)?; Some(this) } } impl Default for ElasticSearchStore { fn default() -> Self { Self { url: Default::default(), num_replicas: 0u64, num_shards: 3u64, include_source: false, timeout: Duration::from_millis(30000), allow_invalid_certs: false, http_auth: Default::default(), http_headers: Default::default(), } } } impl IntoValue for ElasticSearchStore { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(10); map.insert_unchecked(Property::Url, self.url.into_value()); map.insert_unchecked(Property::NumReplicas, self.num_replicas.into_value()); map.insert_unchecked(Property::NumShards, self.num_shards.into_value()); map.insert_unchecked(Property::IncludeSource, self.include_source.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked( Property::AllowInvalidCerts, self.allow_invalid_certs.into_value(), ); map.insert_unchecked(Property::HttpAuth, self.http_auth.into_value()); map.insert_unchecked(Property::HttpHeaders, self.http_headers.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ElasticSearchStore { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Url) => self .url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::NumReplicas) => self.num_replicas.patch(pointer, value), Some(Property::NumShards) => self.num_shards.patch(pointer, value), Some(Property::IncludeSource) => self.include_source.patch(pointer, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::AllowInvalidCerts) => self.allow_invalid_certs.patch(pointer, value), Some(Property::HttpAuth) => self.http_auth.patch(pointer, value), Some(Property::HttpHeaders) => self .http_headers .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Email { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Email; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.max_attachment_size; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxAttachmentSize, 1)); } let value = &self.max_message_size; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxMessageSize, 1)); } let value = &self.max_mailbox_depth; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxMailboxDepth, 1)); } let value = &self.max_mailbox_name_length; if *value < 1 { errors.push(ValidationError::min_value( Property::MaxMailboxNameLength, 1, )); } let value = &self.default_folders; for value in value.values() { value.validate(errors); } if let Some(value) = &self.max_messages { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxMessages, 1)); } } if let Some(value) = &self.max_submissions { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxSubmissions, 1)); } } if let Some(value) = &self.max_identities { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxIdentities, 1)); } } if let Some(value) = &self.max_mailboxes { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxMailboxes, 1)); } } if let Some(value) = &self.max_masked_addresses { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxMaskedAddresses, 1)); } } if let Some(value) = &self.max_public_keys { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxPublicKeys, 1)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for Email { fn pickle(&self, out: &mut Vec) { self.max_attachment_size.pickle(out); self.max_message_size.pickle(out); self.max_mailbox_depth.pickle(out); self.max_mailbox_name_length.pickle(out); self.encrypt_on_append.pickle(out); self.encrypt_at_rest.pickle(out); self.compression_algorithm.pickle(out); self.default_folders.pickle(out); self.max_messages.pickle(out); self.max_submissions.pickle(out); self.max_identities.pickle(out); self.max_mailboxes.pickle(out); self.max_masked_addresses.pickle(out); self.max_public_keys.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.max_attachment_size = Pickle::unpickle(stream)?; this.max_message_size = Pickle::unpickle(stream)?; this.max_mailbox_depth = Pickle::unpickle(stream)?; this.max_mailbox_name_length = Pickle::unpickle(stream)?; this.encrypt_on_append = Pickle::unpickle(stream)?; this.encrypt_at_rest = Pickle::unpickle(stream)?; this.compression_algorithm = Pickle::unpickle(stream)?; this.default_folders = Pickle::unpickle(stream)?; this.max_messages = Pickle::unpickle(stream)?; this.max_submissions = Pickle::unpickle(stream)?; this.max_identities = Pickle::unpickle(stream)?; this.max_mailboxes = Pickle::unpickle(stream)?; this.max_masked_addresses = Pickle::unpickle(stream)?; this.max_public_keys = Pickle::unpickle(stream)?; Some(this) } } impl Default for Email { fn default() -> Self { Self { max_attachment_size: 50000000u64, max_message_size: 75000000u64, max_mailbox_depth: 10u64, max_mailbox_name_length: 255u64, encrypt_on_append: false, encrypt_at_rest: true, compression_algorithm: CompressionAlgo::Lz4, default_folders: Default::default(), max_messages: Default::default(), max_submissions: Some(500u64), max_identities: Some(20u64), max_mailboxes: Some(250u64), max_masked_addresses: Some(5u64), max_public_keys: Some(5u64), } } } impl IntoValue for Email { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(16); map.insert_unchecked( Property::MaxAttachmentSize, self.max_attachment_size.into_value(), ); map.insert_unchecked(Property::MaxMessageSize, self.max_message_size.into_value()); map.insert_unchecked( Property::MaxMailboxDepth, self.max_mailbox_depth.into_value(), ); map.insert_unchecked( Property::MaxMailboxNameLength, self.max_mailbox_name_length.into_value(), ); map.insert_unchecked( Property::EncryptOnAppend, self.encrypt_on_append.into_value(), ); map.insert_unchecked(Property::EncryptAtRest, self.encrypt_at_rest.into_value()); map.insert_unchecked( Property::CompressionAlgorithm, self.compression_algorithm.into_value(), ); map.insert_unchecked(Property::DefaultFolders, self.default_folders.into_value()); map.insert_unchecked(Property::MaxMessages, self.max_messages.into_value()); map.insert_unchecked(Property::MaxSubmissions, self.max_submissions.into_value()); map.insert_unchecked(Property::MaxIdentities, self.max_identities.into_value()); map.insert_unchecked(Property::MaxMailboxes, self.max_mailboxes.into_value()); map.insert_unchecked( Property::MaxMaskedAddresses, self.max_masked_addresses.into_value(), ); map.insert_unchecked(Property::MaxPublicKeys, self.max_public_keys.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Email { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::MaxAttachmentSize) => self.max_attachment_size.patch(pointer, value), Some(Property::MaxMessageSize) => self.max_message_size.patch(pointer, value), Some(Property::MaxMailboxDepth) => self.max_mailbox_depth.patch(pointer, value), Some(Property::MaxMailboxNameLength) => { self.max_mailbox_name_length.patch(pointer, value) } Some(Property::EncryptOnAppend) => self.encrypt_on_append.patch(pointer, value), Some(Property::EncryptAtRest) => self.encrypt_at_rest.patch(pointer, value), Some(Property::CompressionAlgorithm) => { self.compression_algorithm.patch(pointer, value) } Some(Property::DefaultFolders) => self.default_folders.patch(pointer, value), Some(Property::MaxMessages) => self.max_messages.patch(pointer, value), Some(Property::MaxSubmissions) => self.max_submissions.patch(pointer, value), Some(Property::MaxIdentities) => self.max_identities.patch(pointer, value), Some(Property::MaxMailboxes) => self.max_mailboxes.patch(pointer, value), Some(Property::MaxMaskedAddresses) => self.max_masked_addresses.patch(pointer, value), Some(Property::MaxPublicKeys) => self.max_public_keys.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl EmailAlias { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } let value = &self.domain_id; if !value.is_valid() { errors.push(ValidationError::required(Property::DomainId)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique_global_composite(Property::Email, &self.name, &self.domain_id); i.text(Property::Text, &self.name); i.foreign_key(ObjectType::Domain, self.domain_id.into(), None); } } impl Pickle for EmailAlias { fn pickle(&self, out: &mut Vec) { self.enabled.pickle(out); self.name.pickle(out); self.domain_id.pickle(out); self.description.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.enabled = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.domain_id = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; Some(this) } } impl Default for EmailAlias { fn default() -> Self { Self { enabled: true, name: Default::default(), domain_id: Default::default(), description: Default::default(), } } } impl IntoValue for EmailAlias { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Enabled, self.enabled.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::DomainId, self.domain_id.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for EmailAlias { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Enabled) => self.enabled.patch(pointer, value), Some(Property::Name) => self.name.patch( pointer.with_validators(&[StringValidator::EmailLocalPart]), value, ), Some(Property::DomainId) => self.domain_id.patch(pointer, value), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl EmailFolder { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } let value = &self.aliases; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::Aliases)); } } errors.len() == neb } } impl Pickle for EmailFolder { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.create.pickle(out); self.subscribe.pickle(out); self.aliases.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.create = Pickle::unpickle(stream)?; this.subscribe = Pickle::unpickle(stream)?; this.aliases = Pickle::unpickle(stream)?; Some(this) } } impl Default for EmailFolder { fn default() -> Self { Self { name: Default::default(), create: true, subscribe: true, aliases: Default::default(), } } } impl IntoValue for EmailFolder { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Create, self.create.into_value()); map.insert_unchecked(Property::Subscribe, self.subscribe.into_value()); map.insert_unchecked(Property::Aliases, self.aliases.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for EmailFolder { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self .name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Create) => self.create.patch(pointer, value), Some(Property::Subscribe) => self.subscribe.patch(pointer, value), Some(Property::Aliases) => self .aliases .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl EncryptionAtRest { fn validate(&self, errors: &mut Vec) -> bool { match self { EncryptionAtRest::Disabled => true, EncryptionAtRest::Aes128(inner) => inner.validate(errors), EncryptionAtRest::Aes256(inner) => inner.validate(errors), EncryptionAtRest::Aes256Gcm(inner) => inner.validate(errors), EncryptionAtRest::ChaCha20Poly1305(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { EncryptionAtRest::Disabled => {} EncryptionAtRest::Aes128(object) => { object.index(i); } EncryptionAtRest::Aes256(object) => { object.index(i); } EncryptionAtRest::Aes256Gcm(object) => { object.index(i); } EncryptionAtRest::ChaCha20Poly1305(object) => { object.index(i); } } } } impl Default for EncryptionAtRest { fn default() -> Self { EncryptionAtRest::Disabled } } impl Pickle for EncryptionAtRest { fn pickle(&self, out: &mut Vec) { match self { EncryptionAtRest::Disabled => { 0u16.pickle(out); } EncryptionAtRest::Aes128(inner) => { 1u16.pickle(out); inner.pickle(out); } EncryptionAtRest::Aes256(inner) => { 2u16.pickle(out); inner.pickle(out); } EncryptionAtRest::Aes256Gcm(inner) => { 3u16.pickle(out); inner.pickle(out); } EncryptionAtRest::ChaCha20Poly1305(inner) => { 4u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(EncryptionAtRest::Disabled), 1 => Pickle::unpickle(stream).map(EncryptionAtRest::Aes128), 2 => Pickle::unpickle(stream).map(EncryptionAtRest::Aes256), 3 => Pickle::unpickle(stream).map(EncryptionAtRest::Aes256Gcm), 4 => Pickle::unpickle(stream).map(EncryptionAtRest::ChaCha20Poly1305), _ => None, } } } impl IntoValue for EncryptionAtRest { fn into_value(self) -> JmapValue<'static> { match self { EncryptionAtRest::Disabled => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Disabled".into())); JmapValue::Object(obj) } EncryptionAtRest::Aes128(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Aes128".into())); obj } EncryptionAtRest::Aes256(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Aes256".into())); obj } EncryptionAtRest::Aes256Gcm(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Aes256Gcm".into())); obj } EncryptionAtRest::ChaCha20Poly1305(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("ChaCha20Poly1305".into())); obj } } } } impl RegistryJsonPatch for EncryptionAtRest { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { EncryptionAtRestType::Disabled => *self = EncryptionAtRest::Disabled, EncryptionAtRestType::Aes128 => { *self = EncryptionAtRest::Aes128(Default::default()) } EncryptionAtRestType::Aes256 => { *self = EncryptionAtRest::Aes256(Default::default()) } EncryptionAtRestType::Aes256Gcm => { *self = EncryptionAtRest::Aes256Gcm(Default::default()) } EncryptionAtRestType::ChaCha20Poly1305 => { *self = EncryptionAtRest::ChaCha20Poly1305(Default::default()) } } } match self { EncryptionAtRest::Disabled => pointer.assert_eof(), EncryptionAtRest::Aes128(inner) => inner.patch(pointer, value), EncryptionAtRest::Aes256(inner) => inner.patch(pointer, value), EncryptionAtRest::Aes256Gcm(inner) => inner.patch(pointer, value), EncryptionAtRest::ChaCha20Poly1305(inner) => inner.patch(pointer, value), } } } impl EncryptionAtRest { pub fn object_type(&self) -> EncryptionAtRestType { match self { EncryptionAtRest::Disabled => EncryptionAtRestType::Disabled, EncryptionAtRest::Aes128(_) => EncryptionAtRestType::Aes128, EncryptionAtRest::Aes256(_) => EncryptionAtRestType::Aes256, EncryptionAtRest::Aes256Gcm(_) => EncryptionAtRestType::Aes256Gcm, EncryptionAtRest::ChaCha20Poly1305(_) => EncryptionAtRestType::ChaCha20Poly1305, } } } impl EncryptionSettings { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.public_key; if !value.is_valid() { errors.push(ValidationError::required(Property::PublicKey)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::PublicKey, self.public_key.into(), None); } } impl Pickle for EncryptionSettings { fn pickle(&self, out: &mut Vec) { self.public_key.pickle(out); self.encrypt_on_append.pickle(out); self.allow_spam_training.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.public_key = Pickle::unpickle(stream)?; this.encrypt_on_append = Pickle::unpickle(stream)?; this.allow_spam_training = Pickle::unpickle(stream)?; Some(this) } } impl Default for EncryptionSettings { fn default() -> Self { Self { public_key: Default::default(), encrypt_on_append: false, allow_spam_training: false, } } } impl IntoValue for EncryptionSettings { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::PublicKey, self.public_key.into_value()); map.insert_unchecked( Property::EncryptOnAppend, self.encrypt_on_append.into_value(), ); map.insert_unchecked( Property::AllowSpamTraining, self.allow_spam_training.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for EncryptionSettings { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::PublicKey) => self.public_key.patch(pointer, value), Some(Property::EncryptOnAppend) => self.encrypt_on_append.patch(pointer, value), Some(Property::AllowSpamTraining) => self.allow_spam_training.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Enterprise { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Enterprise; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.api_key; value.validate(errors); let value = &self.license_key; value.validate(errors); if let Some(value) = &self.logo_url { if value.is_empty() { errors.push(ValidationError::required(Property::LogoUrl)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for Enterprise { fn pickle(&self, out: &mut Vec) { self.api_key.pickle(out); self.license_key.pickle(out); self.logo_url.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.api_key = Pickle::unpickle(stream)?; this.license_key = Pickle::unpickle(stream)?; this.logo_url = Pickle::unpickle(stream)?; Some(this) } } impl Default for Enterprise { fn default() -> Self { Self { api_key: Default::default(), license_key: Default::default(), logo_url: Default::default(), } } } impl IntoValue for Enterprise { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::ApiKey, self.api_key.into_value()); map.insert_unchecked(Property::LicenseKey, self.license_key.into_value()); map.insert_unchecked(Property::LogoUrl, self.logo_url.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Enterprise { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ApiKey) => self.api_key.patch(pointer, value), Some(Property::LicenseKey) => self.license_key.patch(pointer, value), Some(Property::LogoUrl) => self .logo_url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for EventTracingLevel { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::EventTracingLevel; fn validate(&self, _: &mut Vec) -> bool { true } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Event, &self.event); } } impl Pickle for EventTracingLevel { fn pickle(&self, out: &mut Vec) { self.event.pickle(out); self.level.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.event = Pickle::unpickle(stream)?; this.level = Pickle::unpickle(stream)?; Some(this) } } impl Default for EventTracingLevel { fn default() -> Self { Self { event: Default::default(), level: TracingLevelOpt::Info, } } } impl IntoValue for EventTracingLevel { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Event, self.event.into_value()); map.insert_unchecked(Property::Level, self.level.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for EventTracingLevel { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Event) => self.event.patch(pointer.assert_read_only()?, value), Some(Property::Level) => self.level.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl Expression { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.match_; for value in value.values() { value.validate(errors); } let value = &self.else_; if value.is_empty() { errors.push(ValidationError::required(Property::Else)); } errors.len() == neb } } impl Pickle for Expression { fn pickle(&self, out: &mut Vec) { self.match_.pickle(out); self.else_.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.match_ = Pickle::unpickle(stream)?; this.else_ = Pickle::unpickle(stream)?; Some(this) } } impl Default for Expression { fn default() -> Self { Self { match_: Default::default(), else_: Default::default(), } } } impl IntoValue for Expression { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Match, self.match_.into_value()); map.insert_unchecked(Property::Else, self.else_.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Expression { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Match) => self.match_.patch(pointer, value), Some(Property::Else) => self.else_.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ExpressionMatch { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.if_; if value.is_empty() { errors.push(ValidationError::required(Property::If)); } let value = &self.then; if value.is_empty() { errors.push(ValidationError::required(Property::Then)); } errors.len() == neb } } impl Pickle for ExpressionMatch { fn pickle(&self, out: &mut Vec) { self.if_.pickle(out); self.then.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.if_ = Pickle::unpickle(stream)?; this.then = Pickle::unpickle(stream)?; Some(this) } } impl Default for ExpressionMatch { fn default() -> Self { Self { if_: Default::default(), then: Default::default(), } } } impl IntoValue for ExpressionMatch { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::If, self.if_.into_value()); map.insert_unchecked(Property::Then, self.then.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ExpressionMatch { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::If) => self.if_.patch(pointer, value), Some(Property::Then) => self.then.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for FileStorage { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::FileStorage; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.max_files { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxFiles, 1)); } } if let Some(value) = &self.max_folders { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxFolders, 1)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for FileStorage { fn pickle(&self, out: &mut Vec) { self.max_size.pickle(out); self.max_files.pickle(out); self.max_folders.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.max_size = Pickle::unpickle(stream)?; this.max_files = Pickle::unpickle(stream)?; this.max_folders = Pickle::unpickle(stream)?; Some(this) } } impl Default for FileStorage { fn default() -> Self { Self { max_size: 26214400, max_files: Default::default(), max_folders: Default::default(), } } } impl IntoValue for FileStorage { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::MaxSize, self.max_size.into_value()); map.insert_unchecked(Property::MaxFiles, self.max_files.into_value()); map.insert_unchecked(Property::MaxFolders, self.max_folders.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for FileStorage { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::MaxSize) => self.max_size.patch(pointer, value), Some(Property::MaxFiles) => self.max_files.patch(pointer, value), Some(Property::MaxFolders) => self.max_folders.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl FileSystemStore { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.path; if value.is_empty() { errors.push(ValidationError::required(Property::Path)); } let value = &self.depth; if *value > 5 { errors.push(ValidationError::max_value(Property::Depth, 5)); } errors.len() == neb } } impl Pickle for FileSystemStore { fn pickle(&self, out: &mut Vec) { self.path.pickle(out); self.depth.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.path = Pickle::unpickle(stream)?; this.depth = Pickle::unpickle(stream)?; Some(this) } } impl Default for FileSystemStore { fn default() -> Self { Self { path: Default::default(), depth: 2u64, } } } impl IntoValue for FileSystemStore { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Path, self.path.into_value()); map.insert_unchecked(Property::Depth, self.depth.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for FileSystemStore { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Path) => self .path .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Depth) => self.depth.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl FoundationDbStore { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.cluster_file { if value.is_empty() { errors.push(ValidationError::required(Property::ClusterFile)); } } if let Some(value) = &self.datacenter_id { if value.is_empty() { errors.push(ValidationError::required(Property::DatacenterId)); } } if let Some(value) = &self.machine_id { if value.is_empty() { errors.push(ValidationError::required(Property::MachineId)); } } if let Some(value) = &self.transaction_retry_limit { if *value > 1000 { errors.push(ValidationError::max_value( Property::TransactionRetryLimit, 1000, )); } if *value < 1 { errors.push(ValidationError::min_value( Property::TransactionRetryLimit, 1, )); } } errors.len() == neb } } impl Pickle for FoundationDbStore { fn pickle(&self, out: &mut Vec) { self.cluster_file.pickle(out); self.datacenter_id.pickle(out); self.machine_id.pickle(out); self.transaction_retry_delay.pickle(out); self.transaction_retry_limit.pickle(out); self.transaction_timeout.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.cluster_file = Pickle::unpickle(stream)?; this.datacenter_id = Pickle::unpickle(stream)?; this.machine_id = Pickle::unpickle(stream)?; this.transaction_retry_delay = Pickle::unpickle(stream)?; this.transaction_retry_limit = Pickle::unpickle(stream)?; this.transaction_timeout = Pickle::unpickle(stream)?; Some(this) } } impl Default for FoundationDbStore { fn default() -> Self { Self { cluster_file: Default::default(), datacenter_id: Default::default(), machine_id: Default::default(), transaction_retry_delay: Default::default(), transaction_retry_limit: Default::default(), transaction_timeout: Default::default(), } } } impl IntoValue for FoundationDbStore { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::ClusterFile, self.cluster_file.into_value()); map.insert_unchecked(Property::DatacenterId, self.datacenter_id.into_value()); map.insert_unchecked(Property::MachineId, self.machine_id.into_value()); map.insert_unchecked( Property::TransactionRetryDelay, self.transaction_retry_delay.into_value(), ); map.insert_unchecked( Property::TransactionRetryLimit, self.transaction_retry_limit.into_value(), ); map.insert_unchecked( Property::TransactionTimeout, self.transaction_timeout.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for FoundationDbStore { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ClusterFile) => self .cluster_file .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::DatacenterId) => self .datacenter_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MachineId) => self .machine_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::TransactionRetryDelay) => { self.transaction_retry_delay.patch(pointer, value) } Some(Property::TransactionRetryLimit) => { self.transaction_retry_limit.patch(pointer, value) } Some(Property::TransactionTimeout) => self.transaction_timeout.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl FtrlParameters { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.alpha; if *value < Float::new(0.0) { errors.push(ValidationError::min_value(Property::Alpha, 0)); } let value = &self.beta; if *value < Float::new(0.0) { errors.push(ValidationError::min_value(Property::Beta, 0)); } let value = &self.l1_ratio; if *value < Float::new(0.0) { errors.push(ValidationError::min_value(Property::L1Ratio, 0)); } let value = &self.l2_ratio; if *value < Float::new(0.0) { errors.push(ValidationError::min_value(Property::L2Ratio, 0)); } errors.len() == neb } } impl Pickle for FtrlParameters { fn pickle(&self, out: &mut Vec) { self.alpha.pickle(out); self.beta.pickle(out); self.num_features.pickle(out); self.l1_ratio.pickle(out); self.l2_ratio.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.alpha = Pickle::unpickle(stream)?; this.beta = Pickle::unpickle(stream)?; this.num_features = Pickle::unpickle(stream)?; this.l1_ratio = Pickle::unpickle(stream)?; this.l2_ratio = Pickle::unpickle(stream)?; Some(this) } } impl Default for FtrlParameters { fn default() -> Self { Self { alpha: Float::new(2.0f64), beta: Float::new(1.0f64), num_features: ModelSize::V20, l1_ratio: Float::new(0.001f64), l2_ratio: Float::new(0.0001f64), } } } impl IntoValue for FtrlParameters { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Alpha, self.alpha.into_value()); map.insert_unchecked(Property::Beta, self.beta.into_value()); map.insert_unchecked(Property::NumFeatures, self.num_features.into_value()); map.insert_unchecked(Property::L1Ratio, self.l1_ratio.into_value()); map.insert_unchecked(Property::L2Ratio, self.l2_ratio.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for FtrlParameters { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Alpha) => self.alpha.patch(pointer, value), Some(Property::Beta) => self.beta.patch(pointer, value), Some(Property::NumFeatures) => self.num_features.patch(pointer, value), Some(Property::L1Ratio) => self.l1_ratio.patch(pointer, value), Some(Property::L2Ratio) => self.l2_ratio.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl GroupAccount { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } let value = &self.domain_id; if !value.is_valid() { errors.push(ValidationError::required(Property::DomainId)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } let value = &self.roles; value.validate(errors); let value = &self.permissions; value.validate(errors); let value = &self.aliases; for value in value.values() { value.validate(errors); } if let Some(value) = &self.external_id { if value.is_empty() { errors.push(ValidationError::required(Property::ExternalId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique_global_composite(Property::Email, &self.name, &self.domain_id); i.text(Property::Text, &self.name); i.search(Property::Name, &self.name); i.foreign_key(ObjectType::Domain, self.domain_id.into(), None); i.search(Property::DomainId, &self.domain_id); if let Some(value) = &self.description { i.text(Property::Text, value); } i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } self.roles.index(i); for item in self.aliases.values() { item.index(i); } if let Some(value) = &self.external_id { i.search(Property::ExternalId, value); } } } impl Pickle for GroupAccount { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.domain_id.pickle(out); self.description.pickle(out); self.created_at.pickle(out); self.member_tenant_id.pickle(out); self.roles.pickle(out); self.quotas.pickle(out); self.permissions.pickle(out); self.aliases.pickle(out); self.locale.pickle(out); self.time_zone.pickle(out); self.external_id.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.domain_id = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.roles = Pickle::unpickle(stream)?; this.quotas = Pickle::unpickle(stream)?; this.permissions = Pickle::unpickle(stream)?; this.aliases = Pickle::unpickle(stream)?; this.locale = Pickle::unpickle(stream)?; this.time_zone = Pickle::unpickle(stream)?; if stream.version() >= 1 { this.external_id = Pickle::unpickle(stream)?; } Some(this) } } impl Default for GroupAccount { fn default() -> Self { Self { name: Default::default(), domain_id: Default::default(), description: Default::default(), created_at: Default::default(), member_tenant_id: Default::default(), roles: Default::default(), quotas: Default::default(), permissions: Default::default(), aliases: Default::default(), locale: Locale::EnUS, time_zone: Default::default(), external_id: Default::default(), } } } impl IntoValue for GroupAccount { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::DomainId, self.domain_id.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Roles, self.roles.into_value()); map.insert_unchecked(Property::Quotas, self.quotas.into_value()); map.insert_unchecked(Property::Permissions, self.permissions.into_value()); map.insert_unchecked(Property::Aliases, self.aliases.into_value()); map.insert_unchecked(Property::Locale, self.locale.into_value()); map.insert_unchecked(Property::TimeZone, self.time_zone.into_value()); map.insert_unchecked(Property::ExternalId, self.external_id.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for GroupAccount { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self.name.patch( pointer.with_validators(&[StringValidator::EmailLocalPart]), value, ), Some(Property::DomainId) => self.domain_id.patch(pointer, value), Some(Property::EmailAddress) => pointer.assert_server_set(), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Roles) => self.roles.patch(pointer, value), Some(Property::Quotas) => self.quotas.patch(pointer, value), Some(Property::UsedDiskQuota) => pointer.assert_server_set(), Some(Property::Permissions) => self.permissions.patch(pointer, value), Some(Property::Aliases) => self.aliases.patch(pointer, value), Some(Property::Locale) => self.locale.patch(pointer, value), Some(Property::TimeZone) => self.time_zone.patch(pointer, value), Some(Property::ExternalId) => self.external_id.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Http { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 1; const OBJECT: ObjectType = ObjectType::Http; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.rate_limit_authenticated { value.validate(errors); } if let Some(value) = &self.rate_limit_anonymous { value.validate(errors); } let value = &self.allowed_endpoints; value.validate(errors); let value = &self.response_headers; for value in value.values() { if value.is_empty() { errors.push(ValidationError::required(Property::ResponseHeaders)); } } if let Some(value) = &self.redirect_root { if value.is_empty() { errors.push(ValidationError::required(Property::RedirectRoot)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Http { pub fn ctx_allowed_endpoints(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.allowed_endpoints, default: Some(Expression { else_: "200".to_string(), ..Default::default() }), property: Property::AllowedEndpoints, allowed_variables: HTTP_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_allowed_endpoints()] } } impl Pickle for Http { fn pickle(&self, out: &mut Vec) { self.rate_limit_authenticated.pickle(out); self.rate_limit_anonymous.pickle(out); self.allowed_endpoints.pickle(out); self.enable_hsts.pickle(out); self.use_permissive_cors.pickle(out); self.response_headers.pickle(out); self.use_x_forwarded.pickle(out); self.redirect_root.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.rate_limit_authenticated = Pickle::unpickle(stream)?; this.rate_limit_anonymous = Pickle::unpickle(stream)?; this.allowed_endpoints = Pickle::unpickle(stream)?; this.enable_hsts = Pickle::unpickle(stream)?; this.use_permissive_cors = Pickle::unpickle(stream)?; this.response_headers = Pickle::unpickle(stream)?; this.use_x_forwarded = Pickle::unpickle(stream)?; if stream.version() >= 1 { this.redirect_root = Pickle::unpickle(stream)?; } Some(this) } } impl Default for Http { fn default() -> Self { Self { rate_limit_authenticated: Some(Rate { count: 1000u64, period: Duration::from_millis(60000), }), rate_limit_anonymous: Some(Rate { count: 100u64, period: Duration::from_millis(60000), }), allowed_endpoints: Expression { else_: "200".to_string(), ..Default::default() }, enable_hsts: false, use_permissive_cors: false, response_headers: Default::default(), use_x_forwarded: false, redirect_root: Some("/account".to_string()), } } } impl IntoValue for Http { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(10); map.insert_unchecked( Property::RateLimitAuthenticated, self.rate_limit_authenticated.into_value(), ); map.insert_unchecked( Property::RateLimitAnonymous, self.rate_limit_anonymous.into_value(), ); map.insert_unchecked( Property::AllowedEndpoints, self.allowed_endpoints.into_value(), ); map.insert_unchecked(Property::EnableHsts, self.enable_hsts.into_value()); map.insert_unchecked( Property::UsePermissiveCors, self.use_permissive_cors.into_value(), ); map.insert_unchecked( Property::ResponseHeaders, self.response_headers.into_value(), ); map.insert_unchecked(Property::UseXForwarded, self.use_x_forwarded.into_value()); map.insert_unchecked(Property::RedirectRoot, self.redirect_root.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Http { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::RateLimitAuthenticated) => { self.rate_limit_authenticated.patch(pointer, value) } Some(Property::RateLimitAnonymous) => self.rate_limit_anonymous.patch(pointer, value), Some(Property::AllowedEndpoints) => self.allowed_endpoints.patch(pointer, value), Some(Property::EnableHsts) => self.enable_hsts.patch(pointer, value), Some(Property::UsePermissiveCors) => self.use_permissive_cors.patch(pointer, value), Some(Property::ResponseHeaders) => self .response_headers .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::UseXForwarded) => self.use_x_forwarded.patch(pointer, value), Some(Property::RedirectRoot) => self .redirect_root .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl HttpAuth { fn validate(&self, errors: &mut Vec) -> bool { match self { HttpAuth::Unauthenticated => true, HttpAuth::Basic(inner) => inner.validate(errors), HttpAuth::Bearer(inner) => inner.validate(errors), } } } impl Default for HttpAuth { fn default() -> Self { HttpAuth::Unauthenticated } } impl Pickle for HttpAuth { fn pickle(&self, out: &mut Vec) { match self { HttpAuth::Unauthenticated => { 0u16.pickle(out); } HttpAuth::Basic(inner) => { 1u16.pickle(out); inner.pickle(out); } HttpAuth::Bearer(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(HttpAuth::Unauthenticated), 1 => Pickle::unpickle(stream).map(HttpAuth::Basic), 2 => Pickle::unpickle(stream).map(HttpAuth::Bearer), _ => None, } } } impl IntoValue for HttpAuth { fn into_value(self) -> JmapValue<'static> { match self { HttpAuth::Unauthenticated => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Unauthenticated".into())); JmapValue::Object(obj) } HttpAuth::Basic(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Basic".into())); obj } HttpAuth::Bearer(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Bearer".into())); obj } } } } impl RegistryJsonPatch for HttpAuth { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { HttpAuthType::Unauthenticated => *self = HttpAuth::Unauthenticated, HttpAuthType::Basic => *self = HttpAuth::Basic(Default::default()), HttpAuthType::Bearer => *self = HttpAuth::Bearer(Default::default()), } } match self { HttpAuth::Unauthenticated => pointer.assert_eof(), HttpAuth::Basic(inner) => inner.patch(pointer, value), HttpAuth::Bearer(inner) => inner.patch(pointer, value), } } } impl HttpAuth { pub fn object_type(&self) -> HttpAuthType { match self { HttpAuth::Unauthenticated => HttpAuthType::Unauthenticated, HttpAuth::Basic(_) => HttpAuthType::Basic, HttpAuth::Bearer(_) => HttpAuthType::Bearer, } } } impl HttpAuthBasic { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.username; if value.is_empty() { errors.push(ValidationError::required(Property::Username)); } let value = &self.secret; value.validate(errors); errors.len() == neb } } impl Pickle for HttpAuthBasic { fn pickle(&self, out: &mut Vec) { self.username.pickle(out); self.secret.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.username = Pickle::unpickle(stream)?; this.secret = Pickle::unpickle(stream)?; Some(this) } } impl Default for HttpAuthBasic { fn default() -> Self { Self { username: Default::default(), secret: Default::default(), } } } impl IntoValue for HttpAuthBasic { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Username, self.username.into_value()); map.insert_unchecked(Property::Secret, self.secret.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for HttpAuthBasic { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Username) => self .username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Secret) => self.secret.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl HttpAuthBearer { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.bearer_token; value.validate(errors); errors.len() == neb } } impl Pickle for HttpAuthBearer { fn pickle(&self, out: &mut Vec) { self.bearer_token.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.bearer_token = Pickle::unpickle(stream)?; Some(this) } } impl Default for HttpAuthBearer { fn default() -> Self { Self { bearer_token: Default::default(), } } } impl IntoValue for HttpAuthBearer { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::BearerToken, self.bearer_token.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for HttpAuthBearer { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::BearerToken) => self.bearer_token.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for HttpForm { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::HttpForm; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.deliver_to; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::DeliverTo)); } } let value = &self.default_from_address; if value.is_empty() { errors.push(ValidationError::required(Property::DefaultFromAddress)); } if let Some(value) = &self.field_email { if value.is_empty() { errors.push(ValidationError::required(Property::FieldEmail)); } } if let Some(value) = &self.field_honey_pot { if value.is_empty() { errors.push(ValidationError::required(Property::FieldHoneyPot)); } } let value = &self.default_name; if value.is_empty() { errors.push(ValidationError::required(Property::DefaultName)); } if let Some(value) = &self.field_name { if value.is_empty() { errors.push(ValidationError::required(Property::FieldName)); } } if let Some(value) = &self.rate_limit { value.validate(errors); } let value = &self.default_subject; if value.is_empty() { errors.push(ValidationError::required(Property::DefaultSubject)); } if let Some(value) = &self.field_subject { if value.is_empty() { errors.push(ValidationError::required(Property::FieldSubject)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for HttpForm { fn pickle(&self, out: &mut Vec) { self.deliver_to.pickle(out); self.default_from_address.pickle(out); self.field_email.pickle(out); self.enable.pickle(out); self.field_honey_pot.pickle(out); self.max_size.pickle(out); self.default_name.pickle(out); self.field_name.pickle(out); self.rate_limit.pickle(out); self.default_subject.pickle(out); self.field_subject.pickle(out); self.validate_domain.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.deliver_to = Pickle::unpickle(stream)?; this.default_from_address = Pickle::unpickle(stream)?; this.field_email = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.field_honey_pot = Pickle::unpickle(stream)?; this.max_size = Pickle::unpickle(stream)?; this.default_name = Pickle::unpickle(stream)?; this.field_name = Pickle::unpickle(stream)?; this.rate_limit = Pickle::unpickle(stream)?; this.default_subject = Pickle::unpickle(stream)?; this.field_subject = Pickle::unpickle(stream)?; this.validate_domain = Pickle::unpickle(stream)?; Some(this) } } impl Default for HttpForm { fn default() -> Self { Self { deliver_to: Default::default(), default_from_address: "postmaster@localhost".to_string(), field_email: Default::default(), enable: false, field_honey_pot: Default::default(), max_size: 102400, default_name: "Anonymous".to_string(), field_name: Default::default(), rate_limit: Some(Rate { count: 5u64, period: Duration::from_millis(3600000), }), default_subject: "Contact form submission".to_string(), field_subject: Default::default(), validate_domain: true, } } } impl IntoValue for HttpForm { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked(Property::DeliverTo, self.deliver_to.into_value()); map.insert_unchecked( Property::DefaultFromAddress, self.default_from_address.into_value(), ); map.insert_unchecked(Property::FieldEmail, self.field_email.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::FieldHoneyPot, self.field_honey_pot.into_value()); map.insert_unchecked(Property::MaxSize, self.max_size.into_value()); map.insert_unchecked(Property::DefaultName, self.default_name.into_value()); map.insert_unchecked(Property::FieldName, self.field_name.into_value()); map.insert_unchecked(Property::RateLimit, self.rate_limit.into_value()); map.insert_unchecked(Property::DefaultSubject, self.default_subject.into_value()); map.insert_unchecked(Property::FieldSubject, self.field_subject.into_value()); map.insert_unchecked(Property::ValidateDomain, self.validate_domain.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for HttpForm { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::DeliverTo) => self .deliver_to .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::DefaultFromAddress) => self .default_from_address .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::FieldEmail) => self .field_email .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::FieldHoneyPot) => self .field_honey_pot .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MaxSize) => self.max_size.patch(pointer, value), Some(Property::DefaultName) => self .default_name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::FieldName) => self .field_name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::RateLimit) => self.rate_limit.patch(pointer, value), Some(Property::DefaultSubject) => self .default_subject .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::FieldSubject) => self .field_subject .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ValidateDomain) => self.validate_domain.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for HttpLookup { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::HttpLookup; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.namespace; if value.is_empty() { errors.push(ValidationError::required(Property::Namespace)); } let value = &self.format; value.validate(errors); let value = &self.max_entries; if *value > 1048576 { errors.push(ValidationError::max_value(Property::MaxEntries, 1048576)); } if *value < 1 { errors.push(ValidationError::min_value(Property::MaxEntries, 1)); } let value = &self.max_entry_size; if *value > 1048576 { errors.push(ValidationError::max_value(Property::MaxEntrySize, 1048576)); } if *value < 1 { errors.push(ValidationError::min_value(Property::MaxEntrySize, 1)); } let value = &self.max_size; if *value > 1073741824 { errors.push(ValidationError::max_value(Property::MaxSize, 1073741824)); } if *value < 10 { errors.push(ValidationError::min_value(Property::MaxSize, 10)); } let value = &self.url; if value.is_empty() { errors.push(ValidationError::required(Property::Url)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique_global(Property::Namespace, &self.namespace); } } impl Pickle for HttpLookup { fn pickle(&self, out: &mut Vec) { self.namespace.pickle(out); self.enable.pickle(out); self.format.pickle(out); self.is_gzipped.pickle(out); self.max_entries.pickle(out); self.max_entry_size.pickle(out); self.max_size.pickle(out); self.refresh.pickle(out); self.retry.pickle(out); self.timeout.pickle(out); self.url.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.namespace = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.format = Pickle::unpickle(stream)?; this.is_gzipped = Pickle::unpickle(stream)?; this.max_entries = Pickle::unpickle(stream)?; this.max_entry_size = Pickle::unpickle(stream)?; this.max_size = Pickle::unpickle(stream)?; this.refresh = Pickle::unpickle(stream)?; this.retry = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.url = Pickle::unpickle(stream)?; Some(this) } } impl Default for HttpLookup { fn default() -> Self { Self { namespace: Default::default(), enable: true, format: Default::default(), is_gzipped: false, max_entries: 100000u64, max_entry_size: 512u64, max_size: 104857600, refresh: Duration::from_millis(43200000), retry: Duration::from_millis(3600000), timeout: Duration::from_millis(30000), url: Default::default(), } } } impl IntoValue for HttpLookup { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(13); map.insert_unchecked(Property::Namespace, self.namespace.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Format, self.format.into_value()); map.insert_unchecked(Property::IsGzipped, self.is_gzipped.into_value()); map.insert_unchecked(Property::MaxEntries, self.max_entries.into_value()); map.insert_unchecked(Property::MaxEntrySize, self.max_entry_size.into_value()); map.insert_unchecked(Property::MaxSize, self.max_size.into_value()); map.insert_unchecked(Property::Refresh, self.refresh.into_value()); map.insert_unchecked(Property::Retry, self.retry.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Url, self.url.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for HttpLookup { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Namespace) => self.namespace.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::Trim]), value, ), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Format) => self.format.patch(pointer, value), Some(Property::IsGzipped) => self.is_gzipped.patch(pointer, value), Some(Property::MaxEntries) => self.max_entries.patch(pointer, value), Some(Property::MaxEntrySize) => self.max_entry_size.patch(pointer, value), Some(Property::MaxSize) => self.max_size.patch(pointer, value), Some(Property::Refresh) => self.refresh.patch(pointer, value), Some(Property::Retry) => self.retry.patch(pointer, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Url) => self .url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl HttpLookupCsv { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.separator; if value.is_empty() { errors.push(ValidationError::required(Property::Separator)); } errors.len() == neb } } impl Pickle for HttpLookupCsv { fn pickle(&self, out: &mut Vec) { self.index_key.pickle(out); self.index_value.pickle(out); self.separator.pickle(out); self.skip_first.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.index_key = Pickle::unpickle(stream)?; this.index_value = Pickle::unpickle(stream)?; this.separator = Pickle::unpickle(stream)?; this.skip_first = Pickle::unpickle(stream)?; Some(this) } } impl Default for HttpLookupCsv { fn default() -> Self { Self { index_key: 0u64, index_value: Default::default(), separator: ",".to_string(), skip_first: false, } } } impl IntoValue for HttpLookupCsv { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::IndexKey, self.index_key.into_value()); map.insert_unchecked(Property::IndexValue, self.index_value.into_value()); map.insert_unchecked(Property::Separator, self.separator.into_value()); map.insert_unchecked(Property::SkipFirst, self.skip_first.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for HttpLookupCsv { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::IndexKey) => self.index_key.patch(pointer, value), Some(Property::IndexValue) => self.index_value.patch(pointer, value), Some(Property::Separator) => self .separator .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SkipFirst) => self.skip_first.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl HttpLookupFormat { fn validate(&self, errors: &mut Vec) -> bool { match self { HttpLookupFormat::Csv(inner) => inner.validate(errors), HttpLookupFormat::List => true, } } } impl Default for HttpLookupFormat { fn default() -> Self { HttpLookupFormat::Csv(Default::default()) } } impl Pickle for HttpLookupFormat { fn pickle(&self, out: &mut Vec) { match self { HttpLookupFormat::Csv(inner) => { 0u16.pickle(out); inner.pickle(out); } HttpLookupFormat::List => { 1u16.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(HttpLookupFormat::Csv), 1 => Some(HttpLookupFormat::List), _ => None, } } } impl IntoValue for HttpLookupFormat { fn into_value(self) -> JmapValue<'static> { match self { HttpLookupFormat::Csv(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Csv".into())); obj } HttpLookupFormat::List => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("List".into())); JmapValue::Object(obj) } } } } impl RegistryJsonPatch for HttpLookupFormat { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { HttpLookupFormatType::Csv => *self = HttpLookupFormat::Csv(Default::default()), HttpLookupFormatType::List => *self = HttpLookupFormat::List, } } match self { HttpLookupFormat::Csv(inner) => inner.patch(pointer, value), HttpLookupFormat::List => pointer.assert_eof(), } } } impl HttpLookupFormat { pub fn object_type(&self) -> HttpLookupFormatType { match self { HttpLookupFormat::Csv(_) => HttpLookupFormatType::Csv, HttpLookupFormat::List => HttpLookupFormatType::List, } } } impl HurricaneCredential { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.zone; if value.is_empty() { errors.push(ValidationError::required(Property::Zone)); } let value = &self.secret; value.validate(errors); errors.len() == neb } } impl Pickle for HurricaneCredential { fn pickle(&self, out: &mut Vec) { self.zone.pickle(out); self.secret.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.zone = Pickle::unpickle(stream)?; this.secret = Pickle::unpickle(stream)?; Some(this) } } impl Default for HurricaneCredential { fn default() -> Self { Self { zone: Default::default(), secret: Default::default(), } } } impl IntoValue for HurricaneCredential { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Zone, self.zone.into_value()); map.insert_unchecked(Property::Secret, self.secret.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for HurricaneCredential { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Zone) => self.zone.patch( pointer.with_validators(&[StringValidator::Domain, StringValidator::Trim]), value, ), Some(Property::Secret) => self.secret.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Imap { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 1; const OBJECT: ObjectType = ObjectType::Imap; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.max_auth_failures; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxAuthFailures, 1)); } if let Some(value) = &self.max_concurrent { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxConcurrent, 1)); } } if let Some(value) = &self.max_request_rate { value.validate(errors); } let value = &self.max_messages_per_command; if *value < 1000 { errors.push(ValidationError::min_value( Property::MaxMessagesPerCommand, 1000, )); } let value = &self.min_uid_batch_size; if *value < 1 { errors.push(ValidationError::min_value(Property::MinUidBatchSize, 1)); } if *value > 500 { errors.push(ValidationError::max_value(Property::MinUidBatchSize, 500)); } let value = &self.max_uid_batches; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxUidBatches, 1)); } let value = &self.max_messages_per_save; if *value < 1000 { errors.push(ValidationError::min_value( Property::MaxMessagesPerSave, 1000, )); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for Imap { fn pickle(&self, out: &mut Vec) { self.allow_plain_text_auth.pickle(out); self.max_auth_failures.pickle(out); self.max_concurrent.pickle(out); self.max_request_rate.pickle(out); self.max_request_size.pickle(out); self.timeout_anonymous.pickle(out); self.timeout_authenticated.pickle(out); self.timeout_idle.pickle(out); self.max_messages_per_command.pickle(out); self.min_uid_batch_size.pickle(out); self.max_uid_batches.pickle(out); self.max_messages_per_save.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.allow_plain_text_auth = Pickle::unpickle(stream)?; this.max_auth_failures = Pickle::unpickle(stream)?; this.max_concurrent = Pickle::unpickle(stream)?; this.max_request_rate = Pickle::unpickle(stream)?; this.max_request_size = Pickle::unpickle(stream)?; this.timeout_anonymous = Pickle::unpickle(stream)?; this.timeout_authenticated = Pickle::unpickle(stream)?; this.timeout_idle = Pickle::unpickle(stream)?; if stream.version() >= 1 { this.max_messages_per_command = Pickle::unpickle(stream)?; } if stream.version() >= 1 { this.min_uid_batch_size = Pickle::unpickle(stream)?; } if stream.version() >= 1 { this.max_uid_batches = Pickle::unpickle(stream)?; } if stream.version() >= 1 { this.max_messages_per_save = Pickle::unpickle(stream)?; } Some(this) } } impl Default for Imap { fn default() -> Self { Self { allow_plain_text_auth: false, max_auth_failures: 3u64, max_concurrent: Some(16u64), max_request_rate: Some(Rate { count: 2000u64, period: Duration::from_millis(60000), }), max_request_size: 52428800, timeout_anonymous: Duration::from_millis(60000), timeout_authenticated: Duration::from_millis(1800000), timeout_idle: Duration::from_millis(1800000), max_messages_per_command: 1000000u64, min_uid_batch_size: 500u64, max_uid_batches: 10000u64, max_messages_per_save: 1000000u64, } } } impl IntoValue for Imap { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked( Property::AllowPlainTextAuth, self.allow_plain_text_auth.into_value(), ); map.insert_unchecked( Property::MaxAuthFailures, self.max_auth_failures.into_value(), ); map.insert_unchecked(Property::MaxConcurrent, self.max_concurrent.into_value()); map.insert_unchecked(Property::MaxRequestRate, self.max_request_rate.into_value()); map.insert_unchecked(Property::MaxRequestSize, self.max_request_size.into_value()); map.insert_unchecked( Property::TimeoutAnonymous, self.timeout_anonymous.into_value(), ); map.insert_unchecked( Property::TimeoutAuthenticated, self.timeout_authenticated.into_value(), ); map.insert_unchecked(Property::TimeoutIdle, self.timeout_idle.into_value()); map.insert_unchecked( Property::MaxMessagesPerCommand, self.max_messages_per_command.into_value(), ); map.insert_unchecked( Property::MinUidBatchSize, self.min_uid_batch_size.into_value(), ); map.insert_unchecked(Property::MaxUidBatches, self.max_uid_batches.into_value()); map.insert_unchecked( Property::MaxMessagesPerSave, self.max_messages_per_save.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Imap { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AllowPlainTextAuth) => self.allow_plain_text_auth.patch(pointer, value), Some(Property::MaxAuthFailures) => self.max_auth_failures.patch(pointer, value), Some(Property::MaxConcurrent) => self.max_concurrent.patch(pointer, value), Some(Property::MaxRequestRate) => self.max_request_rate.patch(pointer, value), Some(Property::MaxRequestSize) => self.max_request_size.patch(pointer, value), Some(Property::TimeoutAnonymous) => self.timeout_anonymous.patch(pointer, value), Some(Property::TimeoutAuthenticated) => { self.timeout_authenticated.patch(pointer, value) } Some(Property::TimeoutIdle) => self.timeout_idle.patch(pointer, value), Some(Property::MaxMessagesPerCommand) => { self.max_messages_per_command.patch(pointer, value) } Some(Property::MinUidBatchSize) => self.min_uid_batch_size.patch(pointer, value), Some(Property::MaxUidBatches) => self.max_uid_batches.patch(pointer, value), Some(Property::MaxMessagesPerSave) => self.max_messages_per_save.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for InMemoryStore { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::InMemoryStore; fn validate(&self, errors: &mut Vec) -> bool { match self { InMemoryStore::Default => true, InMemoryStore::Sharded(inner) => inner.validate(errors), InMemoryStore::Redis(inner) => inner.validate(errors), InMemoryStore::RedisCluster(inner) => inner.validate(errors), InMemoryStore::RedisSentinel(inner) => inner.validate(errors), } } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Default for InMemoryStore { fn default() -> Self { InMemoryStore::Default } } impl Pickle for InMemoryStore { fn pickle(&self, out: &mut Vec) { match self { InMemoryStore::Default => { 0u16.pickle(out); } InMemoryStore::Sharded(inner) => { 1u16.pickle(out); inner.pickle(out); } InMemoryStore::Redis(inner) => { 2u16.pickle(out); inner.pickle(out); } InMemoryStore::RedisCluster(inner) => { 3u16.pickle(out); inner.pickle(out); } InMemoryStore::RedisSentinel(inner) => { 4u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(InMemoryStore::Default), 1 => Pickle::unpickle(stream).map(InMemoryStore::Sharded), 2 => Pickle::unpickle(stream).map(InMemoryStore::Redis), 3 => Pickle::unpickle(stream).map(InMemoryStore::RedisCluster), 4 => Pickle::unpickle(stream).map(InMemoryStore::RedisSentinel), _ => None, } } } impl IntoValue for InMemoryStore { fn into_value(self) -> JmapValue<'static> { match self { InMemoryStore::Default => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Default".into())); JmapValue::Object(obj) } InMemoryStore::Sharded(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Sharded".into())); obj } InMemoryStore::Redis(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Redis".into())); obj } InMemoryStore::RedisCluster(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("RedisCluster".into())); obj } InMemoryStore::RedisSentinel(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("RedisSentinel".into())); obj } } } } impl RegistryJsonPatch for InMemoryStore { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { InMemoryStoreType::Default => *self = InMemoryStore::Default, InMemoryStoreType::Sharded => *self = InMemoryStore::Sharded(Default::default()), InMemoryStoreType::Redis => *self = InMemoryStore::Redis(Default::default()), InMemoryStoreType::RedisCluster => { *self = InMemoryStore::RedisCluster(Default::default()) } InMemoryStoreType::RedisSentinel => { *self = InMemoryStore::RedisSentinel(Default::default()) } } } match self { InMemoryStore::Default => pointer.assert_eof(), InMemoryStore::Sharded(inner) => inner.patch(pointer, value), InMemoryStore::Redis(inner) => inner.patch(pointer, value), InMemoryStore::RedisCluster(inner) => inner.patch(pointer, value), InMemoryStore::RedisSentinel(inner) => inner.patch(pointer, value), } } } impl InMemoryStore { pub fn object_type(&self) -> InMemoryStoreType { match self { InMemoryStore::Default => InMemoryStoreType::Default, InMemoryStore::Sharded(_) => InMemoryStoreType::Sharded, InMemoryStore::Redis(_) => InMemoryStoreType::Redis, InMemoryStore::RedisCluster(_) => InMemoryStoreType::RedisCluster, InMemoryStore::RedisSentinel(_) => InMemoryStoreType::RedisSentinel, } } } impl InMemoryStoreBase { fn validate(&self, errors: &mut Vec) -> bool { match self { InMemoryStoreBase::Redis(inner) => inner.validate(errors), InMemoryStoreBase::RedisCluster(inner) => inner.validate(errors), InMemoryStoreBase::RedisSentinel(inner) => inner.validate(errors), } } } impl Default for InMemoryStoreBase { fn default() -> Self { InMemoryStoreBase::Redis(Default::default()) } } impl Pickle for InMemoryStoreBase { fn pickle(&self, out: &mut Vec) { match self { InMemoryStoreBase::Redis(inner) => { 0u16.pickle(out); inner.pickle(out); } InMemoryStoreBase::RedisCluster(inner) => { 1u16.pickle(out); inner.pickle(out); } InMemoryStoreBase::RedisSentinel(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(InMemoryStoreBase::Redis), 1 => Pickle::unpickle(stream).map(InMemoryStoreBase::RedisCluster), 2 => Pickle::unpickle(stream).map(InMemoryStoreBase::RedisSentinel), _ => None, } } } impl IntoValue for InMemoryStoreBase { fn into_value(self) -> JmapValue<'static> { match self { InMemoryStoreBase::Redis(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Redis".into())); obj } InMemoryStoreBase::RedisCluster(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("RedisCluster".into())); obj } InMemoryStoreBase::RedisSentinel(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("RedisSentinel".into())); obj } } } } impl RegistryJsonPatch for InMemoryStoreBase { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { InMemoryStoreBaseType::Redis => { *self = InMemoryStoreBase::Redis(Default::default()) } InMemoryStoreBaseType::RedisCluster => { *self = InMemoryStoreBase::RedisCluster(Default::default()) } InMemoryStoreBaseType::RedisSentinel => { *self = InMemoryStoreBase::RedisSentinel(Default::default()) } } } match self { InMemoryStoreBase::Redis(inner) => inner.patch(pointer, value), InMemoryStoreBase::RedisCluster(inner) => inner.patch(pointer, value), InMemoryStoreBase::RedisSentinel(inner) => inner.patch(pointer, value), } } } impl InMemoryStoreBase { pub fn object_type(&self) -> InMemoryStoreBaseType { match self { InMemoryStoreBase::Redis(_) => InMemoryStoreBaseType::Redis, InMemoryStoreBase::RedisCluster(_) => InMemoryStoreBaseType::RedisCluster, InMemoryStoreBase::RedisSentinel(_) => InMemoryStoreBaseType::RedisSentinel, } } } impl ObjectImpl for Jmap { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 2; const OBJECT: ObjectType = ObjectType::Jmap; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.parse_limit_event; if *value < 1 { errors.push(ValidationError::min_value(Property::ParseLimitEvent, 1)); } let value = &self.parse_limit_contact; if *value < 1 { errors.push(ValidationError::min_value(Property::ParseLimitContact, 1)); } let value = &self.parse_limit_email; if *value < 1 { errors.push(ValidationError::min_value(Property::ParseLimitEmail, 1)); } let value = &self.changes_max_results; if *value < 1 { errors.push(ValidationError::min_value(Property::ChangesMaxResults, 1)); } let value = &self.get_max_results; if *value < 1 { errors.push(ValidationError::min_value(Property::GetMaxResults, 1)); } let value = &self.query_max_results; if *value < 1 { errors.push(ValidationError::min_value(Property::QueryMaxResults, 1)); } let value = &self.max_method_calls; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxMethodCalls, 1)); } if let Some(value) = &self.max_concurrent_requests { if *value < 1 { errors.push(ValidationError::min_value( Property::MaxConcurrentRequests, 1, )); } } let value = &self.max_request_size; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxRequestSize, 1)); } let value = &self.set_max_objects; if *value < 1 { errors.push(ValidationError::min_value(Property::SetMaxObjects, 1)); } let value = &self.snippet_max_results; if *value < 1 { errors.push(ValidationError::min_value(Property::SnippetMaxResults, 1)); } if let Some(value) = &self.max_concurrent_uploads { if *value < 1 { errors.push(ValidationError::min_value( Property::MaxConcurrentUploads, 1, )); } } let value = &self.max_upload_size; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxUploadSize, 1)); } let value = &self.max_upload_count; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxUploadCount, 1)); } let value = &self.upload_quota; if *value < 1 { errors.push(ValidationError::min_value(Property::UploadQuota, 1)); } let value = &self.upload_ttl; if !value.is_valid() { errors.push(ValidationError::invalid(Property::UploadTtl, value)); } if *value < Duration::from_millis(1000) { errors.push(ValidationError::min_value(Property::UploadTtl, 1000)); } let value = &self.push_max_attempts; if *value < 1 { errors.push(ValidationError::min_value(Property::PushMaxAttempts, 1)); } let value = &self.push_shards_total; if *value < 1 { errors.push(ValidationError::min_value(Property::PushShardsTotal, 1)); } if let Some(value) = &self.max_subscriptions { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxSubscriptions, 1)); } } let value = &self.web_push_key; value.validate(errors); if let Some(value) = &self.web_push_contact { if value.is_empty() { errors.push(ValidationError::required(Property::WebPushContact)); } } let value = &self.max_push_size; if *value < 512 { errors.push(ValidationError::min_value(Property::MaxPushSize, 512)); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for Jmap { fn pickle(&self, out: &mut Vec) { self.parse_limit_event.pickle(out); self.parse_limit_contact.pickle(out); self.parse_limit_email.pickle(out); self.changes_max_results.pickle(out); self.get_max_results.pickle(out); self.query_max_results.pickle(out); self.max_method_calls.pickle(out); self.max_concurrent_requests.pickle(out); self.max_request_size.pickle(out); self.set_max_objects.pickle(out); self.snippet_max_results.pickle(out); self.max_concurrent_uploads.pickle(out); self.max_upload_size.pickle(out); self.max_upload_count.pickle(out); self.upload_quota.pickle(out); self.upload_ttl.pickle(out); self.event_source_throttle.pickle(out); self.push_attempt_wait.pickle(out); self.push_max_attempts.pickle(out); self.push_retry_wait.pickle(out); self.push_throttle.pickle(out); self.push_request_timeout.pickle(out); self.push_verify_timeout.pickle(out); self.push_shards_total.pickle(out); self.websocket_heartbeat.pickle(out); self.websocket_throttle.pickle(out); self.websocket_timeout.pickle(out); self.max_subscriptions.pickle(out); self.web_push_key.pickle(out); self.web_push_contact.pickle(out); self.max_push_size.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.parse_limit_event = Pickle::unpickle(stream)?; this.parse_limit_contact = Pickle::unpickle(stream)?; this.parse_limit_email = Pickle::unpickle(stream)?; this.changes_max_results = Pickle::unpickle(stream)?; this.get_max_results = Pickle::unpickle(stream)?; this.query_max_results = Pickle::unpickle(stream)?; this.max_method_calls = Pickle::unpickle(stream)?; this.max_concurrent_requests = Pickle::unpickle(stream)?; this.max_request_size = Pickle::unpickle(stream)?; this.set_max_objects = Pickle::unpickle(stream)?; this.snippet_max_results = Pickle::unpickle(stream)?; this.max_concurrent_uploads = Pickle::unpickle(stream)?; this.max_upload_size = Pickle::unpickle(stream)?; this.max_upload_count = Pickle::unpickle(stream)?; this.upload_quota = Pickle::unpickle(stream)?; this.upload_ttl = Pickle::unpickle(stream)?; this.event_source_throttle = Pickle::unpickle(stream)?; this.push_attempt_wait = Pickle::unpickle(stream)?; this.push_max_attempts = Pickle::unpickle(stream)?; this.push_retry_wait = Pickle::unpickle(stream)?; this.push_throttle = Pickle::unpickle(stream)?; this.push_request_timeout = Pickle::unpickle(stream)?; this.push_verify_timeout = Pickle::unpickle(stream)?; this.push_shards_total = Pickle::unpickle(stream)?; this.websocket_heartbeat = Pickle::unpickle(stream)?; this.websocket_throttle = Pickle::unpickle(stream)?; this.websocket_timeout = Pickle::unpickle(stream)?; this.max_subscriptions = Pickle::unpickle(stream)?; if stream.version() >= 1 { this.web_push_key = Pickle::unpickle(stream)?; } if stream.version() >= 1 { this.web_push_contact = Pickle::unpickle(stream)?; } if stream.version() >= 2 { this.max_push_size = Pickle::unpickle(stream)?; } Some(this) } } impl Default for Jmap { fn default() -> Self { Self { parse_limit_event: 10u64, parse_limit_contact: 10u64, parse_limit_email: 10u64, changes_max_results: 5000u64, get_max_results: 500u64, query_max_results: 5000u64, max_method_calls: 16u64, max_concurrent_requests: Some(4u64), max_request_size: 10000000u64, set_max_objects: 500u64, snippet_max_results: 100u64, max_concurrent_uploads: Some(4u64), max_upload_size: 50000000u64, max_upload_count: 1000u64, upload_quota: 50000000u64, upload_ttl: Duration::from_millis(3600000), event_source_throttle: Duration::from_millis(1000), push_attempt_wait: Duration::from_millis(60000), push_max_attempts: 3u64, push_retry_wait: Duration::from_millis(1000), push_throttle: Duration::from_millis(1000), push_request_timeout: Duration::from_millis(10000), push_verify_timeout: Duration::from_millis(60000), push_shards_total: 1u64, websocket_heartbeat: Duration::from_millis(60000), websocket_throttle: Duration::from_millis(1000), websocket_timeout: Duration::from_millis(600000), max_subscriptions: Some(15u64), web_push_key: Default::default(), web_push_contact: Default::default(), max_push_size: 4096u64, } } } impl IntoValue for Jmap { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(33); map.insert_unchecked( Property::ParseLimitEvent, self.parse_limit_event.into_value(), ); map.insert_unchecked( Property::ParseLimitContact, self.parse_limit_contact.into_value(), ); map.insert_unchecked( Property::ParseLimitEmail, self.parse_limit_email.into_value(), ); map.insert_unchecked( Property::ChangesMaxResults, self.changes_max_results.into_value(), ); map.insert_unchecked(Property::GetMaxResults, self.get_max_results.into_value()); map.insert_unchecked( Property::QueryMaxResults, self.query_max_results.into_value(), ); map.insert_unchecked(Property::MaxMethodCalls, self.max_method_calls.into_value()); map.insert_unchecked( Property::MaxConcurrentRequests, self.max_concurrent_requests.into_value(), ); map.insert_unchecked(Property::MaxRequestSize, self.max_request_size.into_value()); map.insert_unchecked(Property::SetMaxObjects, self.set_max_objects.into_value()); map.insert_unchecked( Property::SnippetMaxResults, self.snippet_max_results.into_value(), ); map.insert_unchecked( Property::MaxConcurrentUploads, self.max_concurrent_uploads.into_value(), ); map.insert_unchecked(Property::MaxUploadSize, self.max_upload_size.into_value()); map.insert_unchecked(Property::MaxUploadCount, self.max_upload_count.into_value()); map.insert_unchecked(Property::UploadQuota, self.upload_quota.into_value()); map.insert_unchecked(Property::UploadTtl, self.upload_ttl.into_value()); map.insert_unchecked( Property::EventSourceThrottle, self.event_source_throttle.into_value(), ); map.insert_unchecked( Property::PushAttemptWait, self.push_attempt_wait.into_value(), ); map.insert_unchecked( Property::PushMaxAttempts, self.push_max_attempts.into_value(), ); map.insert_unchecked(Property::PushRetryWait, self.push_retry_wait.into_value()); map.insert_unchecked(Property::PushThrottle, self.push_throttle.into_value()); map.insert_unchecked( Property::PushRequestTimeout, self.push_request_timeout.into_value(), ); map.insert_unchecked( Property::PushVerifyTimeout, self.push_verify_timeout.into_value(), ); map.insert_unchecked( Property::PushShardsTotal, self.push_shards_total.into_value(), ); map.insert_unchecked( Property::WebsocketHeartbeat, self.websocket_heartbeat.into_value(), ); map.insert_unchecked( Property::WebsocketThrottle, self.websocket_throttle.into_value(), ); map.insert_unchecked( Property::WebsocketTimeout, self.websocket_timeout.into_value(), ); map.insert_unchecked( Property::MaxSubscriptions, self.max_subscriptions.into_value(), ); map.insert_unchecked(Property::WebPushKey, self.web_push_key.into_value()); map.insert_unchecked(Property::WebPushContact, self.web_push_contact.into_value()); map.insert_unchecked(Property::MaxPushSize, self.max_push_size.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Jmap { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ParseLimitEvent) => self.parse_limit_event.patch(pointer, value), Some(Property::ParseLimitContact) => self.parse_limit_contact.patch(pointer, value), Some(Property::ParseLimitEmail) => self.parse_limit_email.patch(pointer, value), Some(Property::ChangesMaxResults) => self.changes_max_results.patch(pointer, value), Some(Property::GetMaxResults) => self.get_max_results.patch(pointer, value), Some(Property::QueryMaxResults) => self.query_max_results.patch(pointer, value), Some(Property::MaxMethodCalls) => self.max_method_calls.patch(pointer, value), Some(Property::MaxConcurrentRequests) => { self.max_concurrent_requests.patch(pointer, value) } Some(Property::MaxRequestSize) => self.max_request_size.patch(pointer, value), Some(Property::SetMaxObjects) => self.set_max_objects.patch(pointer, value), Some(Property::SnippetMaxResults) => self.snippet_max_results.patch(pointer, value), Some(Property::MaxConcurrentUploads) => { self.max_concurrent_uploads.patch(pointer, value) } Some(Property::MaxUploadSize) => self.max_upload_size.patch(pointer, value), Some(Property::MaxUploadCount) => self.max_upload_count.patch(pointer, value), Some(Property::UploadQuota) => self.upload_quota.patch(pointer, value), Some(Property::UploadTtl) => self.upload_ttl.patch(pointer, value), Some(Property::EventSourceThrottle) => self.event_source_throttle.patch(pointer, value), Some(Property::PushAttemptWait) => self.push_attempt_wait.patch(pointer, value), Some(Property::PushMaxAttempts) => self.push_max_attempts.patch(pointer, value), Some(Property::PushRetryWait) => self.push_retry_wait.patch(pointer, value), Some(Property::PushThrottle) => self.push_throttle.patch(pointer, value), Some(Property::PushRequestTimeout) => self.push_request_timeout.patch(pointer, value), Some(Property::PushVerifyTimeout) => self.push_verify_timeout.patch(pointer, value), Some(Property::PushShardsTotal) => self.push_shards_total.patch(pointer, value), Some(Property::WebsocketHeartbeat) => self.websocket_heartbeat.patch(pointer, value), Some(Property::WebsocketThrottle) => self.websocket_throttle.patch(pointer, value), Some(Property::WebsocketTimeout) => self.websocket_timeout.patch(pointer, value), Some(Property::MaxSubscriptions) => self.max_subscriptions.patch(pointer, value), Some(Property::WebPushKey) => self.web_push_key.patch(pointer, value), Some(Property::WebPushContact) => self .web_push_contact .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MaxPushSize) => self.max_push_size.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl JokerAuth { fn validate(&self, errors: &mut Vec) -> bool { match self { JokerAuth::ApiKey(inner) => inner.validate(errors), JokerAuth::UsernamePassword(inner) => inner.validate(errors), } } } impl Default for JokerAuth { fn default() -> Self { JokerAuth::ApiKey(Default::default()) } } impl Pickle for JokerAuth { fn pickle(&self, out: &mut Vec) { match self { JokerAuth::ApiKey(inner) => { 0u16.pickle(out); inner.pickle(out); } JokerAuth::UsernamePassword(inner) => { 1u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(JokerAuth::ApiKey), 1 => Pickle::unpickle(stream).map(JokerAuth::UsernamePassword), _ => None, } } } impl IntoValue for JokerAuth { fn into_value(self) -> JmapValue<'static> { match self { JokerAuth::ApiKey(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("ApiKey".into())); obj } JokerAuth::UsernamePassword(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("UsernamePassword".into())); obj } } } } impl RegistryJsonPatch for JokerAuth { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { JokerAuthType::ApiKey => *self = JokerAuth::ApiKey(Default::default()), JokerAuthType::UsernamePassword => { *self = JokerAuth::UsernamePassword(Default::default()) } } } match self { JokerAuth::ApiKey(inner) => inner.patch(pointer, value), JokerAuth::UsernamePassword(inner) => inner.patch(pointer, value), } } } impl JokerAuth { pub fn object_type(&self) -> JokerAuthType { match self { JokerAuth::ApiKey(_) => JokerAuthType::ApiKey, JokerAuth::UsernamePassword(_) => JokerAuthType::UsernamePassword, } } } impl JokerAuthApiKey { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.api_key; value.validate(errors); errors.len() == neb } } impl Pickle for JokerAuthApiKey { fn pickle(&self, out: &mut Vec) { self.api_key.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.api_key = Pickle::unpickle(stream)?; Some(this) } } impl Default for JokerAuthApiKey { fn default() -> Self { Self { api_key: Default::default(), } } } impl IntoValue for JokerAuthApiKey { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::ApiKey, self.api_key.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for JokerAuthApiKey { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ApiKey) => self.api_key.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl JokerAuthUsernamePassword { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.username; if value.is_empty() { errors.push(ValidationError::required(Property::Username)); } let value = &self.password; value.validate(errors); errors.len() == neb } } impl Pickle for JokerAuthUsernamePassword { fn pickle(&self, out: &mut Vec) { self.username.pickle(out); self.password.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.username = Pickle::unpickle(stream)?; this.password = Pickle::unpickle(stream)?; Some(this) } } impl Default for JokerAuthUsernamePassword { fn default() -> Self { Self { username: Default::default(), password: Default::default(), } } } impl IntoValue for JokerAuthUsernamePassword { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Username, self.username.into_value()); map.insert_unchecked(Property::Password, self.password.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for JokerAuthUsernamePassword { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Username) => self .username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Password) => self.password.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl KafkaCoordinator { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.brokers; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::Brokers)); } } if value.len() < 1 { errors.push(ValidationError::min_items(Property::Brokers, 1)); } let value = &self.group_id; if value.is_empty() { errors.push(ValidationError::required(Property::GroupId)); } errors.len() == neb } } impl Pickle for KafkaCoordinator { fn pickle(&self, out: &mut Vec) { self.brokers.pickle(out); self.group_id.pickle(out); self.timeout_message.pickle(out); self.timeout_session.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.brokers = Pickle::unpickle(stream)?; this.group_id = Pickle::unpickle(stream)?; this.timeout_message = Pickle::unpickle(stream)?; this.timeout_session = Pickle::unpickle(stream)?; Some(this) } } impl Default for KafkaCoordinator { fn default() -> Self { Self { brokers: Default::default(), group_id: Default::default(), timeout_message: Duration::from_millis(5000), timeout_session: Duration::from_millis(5000), } } } impl IntoValue for KafkaCoordinator { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Brokers, self.brokers.into_value()); map.insert_unchecked(Property::GroupId, self.group_id.into_value()); map.insert_unchecked(Property::TimeoutMessage, self.timeout_message.into_value()); map.insert_unchecked(Property::TimeoutSession, self.timeout_session.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for KafkaCoordinator { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Brokers) => self.brokers.patch(pointer, value), Some(Property::GroupId) => self .group_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::TimeoutMessage) => self.timeout_message.patch(pointer, value), Some(Property::TimeoutSession) => self.timeout_session.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl LdapDirectory { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } let value = &self.url; if value.is_empty() { errors.push(ValidationError::required(Property::Url)); } let value = &self.base_dn; if value.is_empty() { errors.push(ValidationError::required(Property::BaseDn)); } if let Some(value) = &self.bind_dn { if value.is_empty() { errors.push(ValidationError::required(Property::BindDn)); } } let value = &self.bind_secret; value.validate(errors); let value = &self.filter_login; if value.is_empty() { errors.push(ValidationError::required(Property::FilterLogin)); } let value = &self.filter_mailbox; if value.is_empty() { errors.push(ValidationError::required(Property::FilterMailbox)); } if let Some(value) = &self.filter_member_of { if value.is_empty() { errors.push(ValidationError::required(Property::FilterMemberOf)); } } let value = &self.attr_class; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::AttrClass)); } } let value = &self.attr_description; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::AttrDescription)); } } let value = &self.attr_email; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::AttrEmail)); } } let value = &self.attr_email_alias; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::AttrEmailAlias)); } } let value = &self.attr_member_of; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::AttrMemberOf)); } } let value = &self.attr_secret; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::AttrSecret)); } } let value = &self.attr_secret_changed; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::AttrSecretChanged)); } } let value = &self.group_class; if value.is_empty() { errors.push(ValidationError::required(Property::GroupClass)); } let value = &self.pool_max_connections; if *value > 8192 { errors.push(ValidationError::max_value( Property::PoolMaxConnections, 8192, )); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for LdapDirectory { fn pickle(&self, out: &mut Vec) { self.description.pickle(out); self.url.pickle(out); self.timeout.pickle(out); self.allow_invalid_certs.pickle(out); self.use_tls.pickle(out); self.base_dn.pickle(out); self.bind_dn.pickle(out); self.bind_secret.pickle(out); self.bind_authentication.pickle(out); self.filter_login.pickle(out); self.filter_mailbox.pickle(out); self.filter_member_of.pickle(out); self.attr_class.pickle(out); self.attr_description.pickle(out); self.attr_email.pickle(out); self.attr_email_alias.pickle(out); self.attr_member_of.pickle(out); self.attr_secret.pickle(out); self.attr_secret_changed.pickle(out); self.group_class.pickle(out); self.pool_max_connections.pickle(out); self.pool_timeout_create.pickle(out); self.pool_timeout_recycle.pickle(out); self.pool_timeout_wait.pickle(out); self.member_tenant_id.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.description = Pickle::unpickle(stream)?; this.url = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.allow_invalid_certs = Pickle::unpickle(stream)?; this.use_tls = Pickle::unpickle(stream)?; this.base_dn = Pickle::unpickle(stream)?; this.bind_dn = Pickle::unpickle(stream)?; this.bind_secret = Pickle::unpickle(stream)?; this.bind_authentication = Pickle::unpickle(stream)?; this.filter_login = Pickle::unpickle(stream)?; this.filter_mailbox = Pickle::unpickle(stream)?; this.filter_member_of = Pickle::unpickle(stream)?; this.attr_class = Pickle::unpickle(stream)?; this.attr_description = Pickle::unpickle(stream)?; this.attr_email = Pickle::unpickle(stream)?; this.attr_email_alias = Pickle::unpickle(stream)?; this.attr_member_of = Pickle::unpickle(stream)?; this.attr_secret = Pickle::unpickle(stream)?; this.attr_secret_changed = Pickle::unpickle(stream)?; this.group_class = Pickle::unpickle(stream)?; this.pool_max_connections = Pickle::unpickle(stream)?; this.pool_timeout_create = Pickle::unpickle(stream)?; this.pool_timeout_recycle = Pickle::unpickle(stream)?; this.pool_timeout_wait = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; Some(this) } } impl Default for LdapDirectory { fn default() -> Self { Self { description: Default::default(), url: "ldap://localhost:389".to_string(), timeout: Duration::from_millis(30000), allow_invalid_certs: false, use_tls: false, base_dn: Default::default(), bind_dn: Default::default(), bind_secret: Default::default(), bind_authentication: true, filter_login: "(&(objectClass=inetOrgPerson)(mail=?))".to_string(), filter_mailbox: "(|(&(objectClass=inetOrgPerson)(|(mail=?)(mailAlias=?)))(&(objectClass=groupOfNames)(|(mail=?)(mailAlias=?))))".to_string(), filter_member_of: Some("(&(objectClass=groupOfNames)(member=?))".to_string()), attr_class: Map::new(vec!["objectClass".to_string()]), attr_description: Map::new(vec!["description".to_string()]), attr_email: Map::new(vec!["mail".to_string()]), attr_email_alias: Map::new(vec!["mailAlias".to_string()]), attr_member_of: Map::new(vec!["memberOf".to_string()]), attr_secret: Map::new(vec!["userPassword".to_string()]), attr_secret_changed: Map::new(vec!["pwdChangeTime".to_string()]), group_class: "groupOfNames".to_string(), pool_max_connections: 10u64, pool_timeout_create: Duration::from_millis(30000), pool_timeout_recycle: Duration::from_millis(30000), pool_timeout_wait: Duration::from_millis(30000), member_tenant_id: Default::default(), } } } impl IntoValue for LdapDirectory { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(27); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Url, self.url.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked( Property::AllowInvalidCerts, self.allow_invalid_certs.into_value(), ); map.insert_unchecked(Property::UseTls, self.use_tls.into_value()); map.insert_unchecked(Property::BaseDn, self.base_dn.into_value()); map.insert_unchecked(Property::BindDn, self.bind_dn.into_value()); map.insert_unchecked(Property::BindSecret, self.bind_secret.into_value()); map.insert_unchecked( Property::BindAuthentication, self.bind_authentication.into_value(), ); map.insert_unchecked(Property::FilterLogin, self.filter_login.into_value()); map.insert_unchecked(Property::FilterMailbox, self.filter_mailbox.into_value()); map.insert_unchecked(Property::FilterMemberOf, self.filter_member_of.into_value()); map.insert_unchecked(Property::AttrClass, self.attr_class.into_value()); map.insert_unchecked( Property::AttrDescription, self.attr_description.into_value(), ); map.insert_unchecked(Property::AttrEmail, self.attr_email.into_value()); map.insert_unchecked(Property::AttrEmailAlias, self.attr_email_alias.into_value()); map.insert_unchecked(Property::AttrMemberOf, self.attr_member_of.into_value()); map.insert_unchecked(Property::AttrSecret, self.attr_secret.into_value()); map.insert_unchecked( Property::AttrSecretChanged, self.attr_secret_changed.into_value(), ); map.insert_unchecked(Property::GroupClass, self.group_class.into_value()); map.insert_unchecked( Property::PoolMaxConnections, self.pool_max_connections.into_value(), ); map.insert_unchecked( Property::PoolTimeoutCreate, self.pool_timeout_create.into_value(), ); map.insert_unchecked( Property::PoolTimeoutRecycle, self.pool_timeout_recycle.into_value(), ); map.insert_unchecked( Property::PoolTimeoutWait, self.pool_timeout_wait.into_value(), ); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for LdapDirectory { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Url) => self .url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::AllowInvalidCerts) => self.allow_invalid_certs.patch(pointer, value), Some(Property::UseTls) => self.use_tls.patch(pointer, value), Some(Property::BaseDn) => self .base_dn .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::BindDn) => self .bind_dn .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::BindSecret) => self.bind_secret.patch(pointer, value), Some(Property::BindAuthentication) => self.bind_authentication.patch(pointer, value), Some(Property::FilterLogin) => self .filter_login .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::FilterMailbox) => self .filter_mailbox .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::FilterMemberOf) => self .filter_member_of .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AttrClass) => self .attr_class .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AttrDescription) => self .attr_description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AttrEmail) => self .attr_email .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AttrEmailAlias) => self .attr_email_alias .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AttrMemberOf) => self .attr_member_of .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AttrSecret) => self .attr_secret .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AttrSecretChanged) => self .attr_secret_changed .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::GroupClass) => self .group_class .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::PoolMaxConnections) => self.pool_max_connections.patch(pointer, value), Some(Property::PoolTimeoutCreate) => self.pool_timeout_create.patch(pointer, value), Some(Property::PoolTimeoutRecycle) => self.pool_timeout_recycle.patch(pointer, value), Some(Property::PoolTimeoutWait) => self.pool_timeout_wait.patch(pointer, value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Log { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Log; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.timestamp; if !value.is_valid() { errors.push(ValidationError::invalid(Property::Timestamp, value)); } let value = &self.details; if value.is_empty() { errors.push(ValidationError::required(Property::Details)); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for Log { fn pickle(&self, out: &mut Vec) { self.timestamp.pickle(out); self.level.pickle(out); self.event.pickle(out); self.details.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.timestamp = Pickle::unpickle(stream)?; this.level = Pickle::unpickle(stream)?; this.event = Pickle::unpickle(stream)?; this.details = Pickle::unpickle(stream)?; Some(this) } } impl Default for Log { fn default() -> Self { Self { timestamp: Default::default(), level: Default::default(), event: Default::default(), details: Default::default(), } } } impl IntoValue for Log { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Timestamp, self.timestamp.into_value()); map.insert_unchecked(Property::Level, self.level.into_value()); map.insert_unchecked(Property::Event, self.event.into_value()); map.insert_unchecked(Property::Details, self.details.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Log { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Timestamp) => self.timestamp.patch(pointer, value), Some(Property::Level) => self.level.patch(pointer, value), Some(Property::Event) => self.event.patch(pointer, value), Some(Property::Details) => self.details.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl LookupStore { fn validate(&self, errors: &mut Vec) -> bool { match self { LookupStore::PostgreSql(inner) => inner.validate(errors), LookupStore::MySql(inner) => inner.validate(errors), LookupStore::Sqlite(inner) => inner.validate(errors), LookupStore::Sharded(inner) => inner.validate(errors), LookupStore::Redis(inner) => inner.validate(errors), LookupStore::RedisCluster(inner) => inner.validate(errors), LookupStore::RedisSentinel(inner) => inner.validate(errors), } } } impl Default for LookupStore { fn default() -> Self { LookupStore::PostgreSql(Default::default()) } } impl Pickle for LookupStore { fn pickle(&self, out: &mut Vec) { match self { LookupStore::PostgreSql(inner) => { 0u16.pickle(out); inner.pickle(out); } LookupStore::MySql(inner) => { 1u16.pickle(out); inner.pickle(out); } LookupStore::Sqlite(inner) => { 2u16.pickle(out); inner.pickle(out); } LookupStore::Sharded(inner) => { 3u16.pickle(out); inner.pickle(out); } LookupStore::Redis(inner) => { 4u16.pickle(out); inner.pickle(out); } LookupStore::RedisCluster(inner) => { 5u16.pickle(out); inner.pickle(out); } LookupStore::RedisSentinel(inner) => { 6u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(LookupStore::PostgreSql), 1 => Pickle::unpickle(stream).map(LookupStore::MySql), 2 => Pickle::unpickle(stream).map(LookupStore::Sqlite), 3 => Pickle::unpickle(stream).map(LookupStore::Sharded), 4 => Pickle::unpickle(stream).map(LookupStore::Redis), 5 => Pickle::unpickle(stream).map(LookupStore::RedisCluster), 6 => Pickle::unpickle(stream).map(LookupStore::RedisSentinel), _ => None, } } } impl IntoValue for LookupStore { fn into_value(self) -> JmapValue<'static> { match self { LookupStore::PostgreSql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("PostgreSql".into())); obj } LookupStore::MySql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("MySql".into())); obj } LookupStore::Sqlite(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Sqlite".into())); obj } LookupStore::Sharded(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Sharded".into())); obj } LookupStore::Redis(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Redis".into())); obj } LookupStore::RedisCluster(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("RedisCluster".into())); obj } LookupStore::RedisSentinel(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("RedisSentinel".into())); obj } } } } impl RegistryJsonPatch for LookupStore { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { LookupStoreType::PostgreSql => *self = LookupStore::PostgreSql(Default::default()), LookupStoreType::MySql => *self = LookupStore::MySql(Default::default()), LookupStoreType::Sqlite => *self = LookupStore::Sqlite(Default::default()), LookupStoreType::Sharded => *self = LookupStore::Sharded(Default::default()), LookupStoreType::Redis => *self = LookupStore::Redis(Default::default()), LookupStoreType::RedisCluster => { *self = LookupStore::RedisCluster(Default::default()) } LookupStoreType::RedisSentinel => { *self = LookupStore::RedisSentinel(Default::default()) } } } match self { LookupStore::PostgreSql(inner) => inner.patch(pointer, value), LookupStore::MySql(inner) => inner.patch(pointer, value), LookupStore::Sqlite(inner) => inner.patch(pointer, value), LookupStore::Sharded(inner) => inner.patch(pointer, value), LookupStore::Redis(inner) => inner.patch(pointer, value), LookupStore::RedisCluster(inner) => inner.patch(pointer, value), LookupStore::RedisSentinel(inner) => inner.patch(pointer, value), } } } impl LookupStore { pub fn object_type(&self) -> LookupStoreType { match self { LookupStore::PostgreSql(_) => LookupStoreType::PostgreSql, LookupStore::MySql(_) => LookupStoreType::MySql, LookupStore::Sqlite(_) => LookupStoreType::Sqlite, LookupStore::Sharded(_) => LookupStoreType::Sharded, LookupStore::Redis(_) => LookupStoreType::Redis, LookupStore::RedisCluster(_) => LookupStoreType::RedisCluster, LookupStore::RedisSentinel(_) => LookupStoreType::RedisSentinel, } } } impl MailExchanger { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.hostname { if value.is_empty() { errors.push(ValidationError::required(Property::Hostname)); } } let value = &self.priority; if *value < 1 { errors.push(ValidationError::min_value(Property::Priority, 1)); } if *value > 65535 { errors.push(ValidationError::max_value(Property::Priority, 65535)); } errors.len() == neb } } impl Pickle for MailExchanger { fn pickle(&self, out: &mut Vec) { self.hostname.pickle(out); self.priority.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.hostname = Pickle::unpickle(stream)?; this.priority = Pickle::unpickle(stream)?; Some(this) } } impl Default for MailExchanger { fn default() -> Self { Self { hostname: Default::default(), priority: 10u64, } } } impl IntoValue for MailExchanger { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Hostname, self.hostname.into_value()); map.insert_unchecked(Property::Priority, self.priority.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MailExchanger { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Hostname) => self .hostname .patch(pointer.with_validators(&[StringValidator::Hostname]), value), Some(Property::Priority) => self.priority.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MailingList { const FLAGS: u64 = OBJ_FILTER_TENANT | OBJ_SEQ_ID; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MailingList; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } let value = &self.domain_id; if !value.is_valid() { errors.push(ValidationError::required(Property::DomainId)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.aliases; for value in value.values() { value.validate(errors); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } let value = &self.recipients; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::Recipients)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique_global_composite(Property::Email, &self.name, &self.domain_id); i.text(Property::Text, &self.name); i.foreign_key(ObjectType::Domain, self.domain_id.into(), None); if let Some(value) = &self.description { i.text(Property::Text, value); } for item in self.aliases.values() { item.index(i); } i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } for value in self.recipients.iter() { i.text(Property::Text, value); } } } impl Pickle for MailingList { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.domain_id.pickle(out); self.description.pickle(out); self.aliases.pickle(out); self.member_tenant_id.pickle(out); self.recipients.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.domain_id = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.aliases = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.recipients = Pickle::unpickle(stream)?; Some(this) } } impl Default for MailingList { fn default() -> Self { Self { name: Default::default(), domain_id: Default::default(), description: Default::default(), aliases: Default::default(), member_tenant_id: Default::default(), recipients: Default::default(), } } } impl IntoValue for MailingList { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::DomainId, self.domain_id.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Aliases, self.aliases.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Recipients, self.recipients.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MailingList { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self.name.patch( pointer.with_validators(&[StringValidator::EmailLocalPart]), value, ), Some(Property::DomainId) => self.domain_id.patch(pointer, value), Some(Property::EmailAddress) => pointer.assert_server_set(), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Aliases) => self.aliases.patch(pointer, value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Recipients) => self .recipients .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MaskedEmail { const FLAGS: u64 = OBJ_FILTER_ACCOUNT; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MaskedEmail; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.account_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } let value = &self.email; if value.is_empty() { errors.push(ValidationError::required(Property::Email)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } if let Some(value) = &self.for_domain { if value.is_empty() { errors.push(ValidationError::required(Property::ForDomain)); } } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } if let Some(value) = &self.created_by { if value.is_empty() { errors.push(ValidationError::required(Property::CreatedBy)); } } if let Some(value) = &self.expires_at { if !value.is_valid() { errors.push(ValidationError::invalid(Property::ExpiresAt, value)); } } if let Some(value) = &self.url { if value.is_empty() { errors.push(ValidationError::required(Property::Url)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id.into(), None); i.search(Property::AccountId, &self.account_id); } } impl Pickle for MaskedEmail { fn pickle(&self, out: &mut Vec) { self.enabled.pickle(out); self.account_id.pickle(out); self.email.pickle(out); self.description.pickle(out); self.for_domain.pickle(out); self.created_at.pickle(out); self.created_by.pickle(out); self.expires_at.pickle(out); self.url.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.enabled = Pickle::unpickle(stream)?; this.account_id = Pickle::unpickle(stream)?; this.email = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.for_domain = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.created_by = Pickle::unpickle(stream)?; this.expires_at = Pickle::unpickle(stream)?; this.url = Pickle::unpickle(stream)?; Some(this) } } impl Default for MaskedEmail { fn default() -> Self { Self { enabled: true, account_id: Default::default(), email: Default::default(), description: Default::default(), for_domain: Default::default(), created_at: Default::default(), created_by: Default::default(), expires_at: Default::default(), url: Default::default(), } } } impl IntoValue for MaskedEmail { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::Enabled, self.enabled.into_value()); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked(Property::Email, self.email.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::ForDomain, self.for_domain.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::CreatedBy, self.created_by.into_value()); map.insert_unchecked(Property::ExpiresAt, self.expires_at.into_value()); map.insert_unchecked(Property::Url, self.url.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MaskedEmail { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Enabled) => self.enabled.patch(pointer, value), Some(Property::AccountId) => self .account_id .patch(pointer.assert_read_only()?.assert_can_set_account()?, value), Some(Property::Email) => pointer.assert_server_set(), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::ForDomain) => self.for_domain.patch(pointer, value), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::CreatedBy) => self.created_by.patch(pointer, value), Some(Property::ExpiresAt) => self.expires_at.patch(pointer.assert_read_only()?, value), Some(Property::Url) => self.url.patch(pointer, value), Some(property @ Property::EmailPrefix) => { Ok(MaybeUnpatched::Unpatched { property, value }) } Some(property @ Property::EmailDomain) => { Ok(MaybeUnpatched::Unpatched { property, value }) } Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl MeilisearchStore { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.url; if value.is_empty() { errors.push(ValidationError::required(Property::Url)); } let value = &self.max_retries; if *value > 1024 { errors.push(ValidationError::max_value(Property::MaxRetries, 1024)); } if *value < 1 { errors.push(ValidationError::min_value(Property::MaxRetries, 1)); } let value = &self.http_auth; value.validate(errors); let value = &self.http_headers; for value in value.values() { if value.is_empty() { errors.push(ValidationError::required(Property::HttpHeaders)); } } errors.len() == neb } } impl Pickle for MeilisearchStore { fn pickle(&self, out: &mut Vec) { self.url.pickle(out); self.poll_interval.pickle(out); self.max_retries.pickle(out); self.fail_on_timeout.pickle(out); self.timeout.pickle(out); self.allow_invalid_certs.pickle(out); self.http_auth.pickle(out); self.http_headers.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.url = Pickle::unpickle(stream)?; this.poll_interval = Pickle::unpickle(stream)?; this.max_retries = Pickle::unpickle(stream)?; this.fail_on_timeout = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.allow_invalid_certs = Pickle::unpickle(stream)?; this.http_auth = Pickle::unpickle(stream)?; this.http_headers = Pickle::unpickle(stream)?; Some(this) } } impl Default for MeilisearchStore { fn default() -> Self { Self { url: Default::default(), poll_interval: Duration::from_millis(500), max_retries: 120u64, fail_on_timeout: true, timeout: Duration::from_millis(30000), allow_invalid_certs: false, http_auth: Default::default(), http_headers: Default::default(), } } } impl IntoValue for MeilisearchStore { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(10); map.insert_unchecked(Property::Url, self.url.into_value()); map.insert_unchecked(Property::PollInterval, self.poll_interval.into_value()); map.insert_unchecked(Property::MaxRetries, self.max_retries.into_value()); map.insert_unchecked(Property::FailOnTimeout, self.fail_on_timeout.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked( Property::AllowInvalidCerts, self.allow_invalid_certs.into_value(), ); map.insert_unchecked(Property::HttpAuth, self.http_auth.into_value()); map.insert_unchecked(Property::HttpHeaders, self.http_headers.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MeilisearchStore { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Url) => self .url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::PollInterval) => self.poll_interval.patch(pointer, value), Some(Property::MaxRetries) => self.max_retries.patch(pointer, value), Some(Property::FailOnTimeout) => self.fail_on_timeout.patch(pointer, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::AllowInvalidCerts) => self.allow_invalid_certs.patch(pointer, value), Some(Property::HttpAuth) => self.http_auth.patch(pointer, value), Some(Property::HttpHeaders) => self .http_headers .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MemoryLookupKey { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MemoryLookupKey; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.namespace; if value.is_empty() { errors.push(ValidationError::required(Property::Namespace)); } let value = &self.key; if value.is_empty() { errors.push(ValidationError::required(Property::Key)); } if value.len() > 255 { errors.push(ValidationError::max_length(Property::Key, 255)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique_global_composite(Property::Namespace, &self.namespace, &self.key); i.search(Property::Namespace, &self.namespace); } } impl Pickle for MemoryLookupKey { fn pickle(&self, out: &mut Vec) { self.namespace.pickle(out); self.key.pickle(out); self.is_glob_pattern.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.namespace = Pickle::unpickle(stream)?; this.key = Pickle::unpickle(stream)?; this.is_glob_pattern = Pickle::unpickle(stream)?; Some(this) } } impl Default for MemoryLookupKey { fn default() -> Self { Self { namespace: Default::default(), key: Default::default(), is_glob_pattern: false, } } } impl IntoValue for MemoryLookupKey { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::Namespace, self.namespace.into_value()); map.insert_unchecked(Property::Key, self.key.into_value()); map.insert_unchecked(Property::IsGlobPattern, self.is_glob_pattern.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MemoryLookupKey { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Namespace) => self.namespace.patch(pointer, value), Some(Property::Key) => self.key.patch(pointer, value), Some(Property::IsGlobPattern) => self.is_glob_pattern.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MemoryLookupKeyValue { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MemoryLookupKeyValue; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.namespace; if value.is_empty() { errors.push(ValidationError::required(Property::Namespace)); } let value = &self.key; if value.is_empty() { errors.push(ValidationError::required(Property::Key)); } if value.len() > 255 { errors.push(ValidationError::max_length(Property::Key, 255)); } let value = &self.value; if value.is_empty() { errors.push(ValidationError::required(Property::Value)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique_global_composite(Property::Namespace, &self.namespace, &self.key); i.search(Property::Namespace, &self.namespace); } } impl Pickle for MemoryLookupKeyValue { fn pickle(&self, out: &mut Vec) { self.namespace.pickle(out); self.key.pickle(out); self.value.pickle(out); self.is_glob_pattern.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.namespace = Pickle::unpickle(stream)?; this.key = Pickle::unpickle(stream)?; this.value = Pickle::unpickle(stream)?; this.is_glob_pattern = Pickle::unpickle(stream)?; Some(this) } } impl Default for MemoryLookupKeyValue { fn default() -> Self { Self { namespace: Default::default(), key: Default::default(), value: Default::default(), is_glob_pattern: false, } } } impl IntoValue for MemoryLookupKeyValue { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Namespace, self.namespace.into_value()); map.insert_unchecked(Property::Key, self.key.into_value()); map.insert_unchecked(Property::Value, self.value.into_value()); map.insert_unchecked(Property::IsGlobPattern, self.is_glob_pattern.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MemoryLookupKeyValue { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Namespace) => self.namespace.patch(pointer, value), Some(Property::Key) => self.key.patch(pointer, value), Some(Property::Value) => self.value.patch(pointer, value), Some(Property::IsGlobPattern) => self.is_glob_pattern.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Metric { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Metric; fn validate(&self, errors: &mut Vec) -> bool { match self { Metric::Counter(inner) => inner.validate(errors), Metric::Gauge(inner) => inner.validate(errors), Metric::Histogram(inner) => inner.validate(errors), } } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Default for Metric { fn default() -> Self { Metric::Counter(Default::default()) } } impl Pickle for Metric { fn pickle(&self, out: &mut Vec) { match self { Metric::Counter(inner) => { 0u16.pickle(out); inner.pickle(out); } Metric::Gauge(inner) => { 1u16.pickle(out); inner.pickle(out); } Metric::Histogram(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(Metric::Counter), 1 => Pickle::unpickle(stream).map(Metric::Gauge), 2 => Pickle::unpickle(stream).map(Metric::Histogram), _ => None, } } } impl IntoValue for Metric { fn into_value(self) -> JmapValue<'static> { match self { Metric::Counter(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Counter".into())); obj } Metric::Gauge(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Gauge".into())); obj } Metric::Histogram(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Histogram".into())); obj } } } } impl RegistryJsonPatch for Metric { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { MetricType::Counter => *self = Metric::Counter(Default::default()), MetricType::Gauge => *self = Metric::Gauge(Default::default()), MetricType::Histogram => *self = Metric::Histogram(Default::default()), } } match self { Metric::Counter(inner) => inner.patch(pointer, value), Metric::Gauge(inner) => inner.patch(pointer, value), Metric::Histogram(inner) => inner.patch(pointer, value), } } } impl Metric { pub fn object_type(&self) -> MetricType { match self { Metric::Counter(_) => MetricType::Counter, Metric::Gauge(_) => MetricType::Gauge, Metric::Histogram(_) => MetricType::Histogram, } } } impl MetricCount { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for MetricCount { fn pickle(&self, out: &mut Vec) { self.count.pickle(out); self.metric.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.count = Pickle::unpickle(stream)?; this.metric = Pickle::unpickle(stream)?; Some(this) } } impl Default for MetricCount { fn default() -> Self { Self { count: 0u64, metric: Default::default(), } } } impl IntoValue for MetricCount { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Count, self.count.into_value()); map.insert_unchecked(Property::Metric, self.metric.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MetricCount { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Count) => self.count.patch(pointer, value), Some(Property::Metric) => self.metric.patch(pointer, value), Some(property @ Property::Timestamp) => { Ok(MaybeUnpatched::Unpatched { property, value }) } Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl MetricSum { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for MetricSum { fn pickle(&self, out: &mut Vec) { self.count.pickle(out); self.sum.pickle(out); self.metric.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.count = Pickle::unpickle(stream)?; this.sum = Pickle::unpickle(stream)?; this.metric = Pickle::unpickle(stream)?; Some(this) } } impl Default for MetricSum { fn default() -> Self { Self { count: 0u64, sum: 0u64, metric: Default::default(), } } } impl IntoValue for MetricSum { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::Count, self.count.into_value()); map.insert_unchecked(Property::Sum, self.sum.into_value()); map.insert_unchecked(Property::Metric, self.metric.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MetricSum { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Count) => self.count.patch(pointer, value), Some(Property::Sum) => self.sum.patch(pointer, value), Some(Property::Metric) => self.metric.patch(pointer, value), Some(property @ Property::Timestamp) => { Ok(MaybeUnpatched::Unpatched { property, value }) } Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Metrics { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Metrics; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.open_telemetry; value.validate(errors); let value = &self.prometheus; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for Metrics { fn pickle(&self, out: &mut Vec) { self.open_telemetry.pickle(out); self.prometheus.pickle(out); self.metrics.pickle(out); self.metrics_policy.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.open_telemetry = Pickle::unpickle(stream)?; this.prometheus = Pickle::unpickle(stream)?; this.metrics = Pickle::unpickle(stream)?; this.metrics_policy = Pickle::unpickle(stream)?; Some(this) } } impl Default for Metrics { fn default() -> Self { Self { open_telemetry: Default::default(), prometheus: Default::default(), metrics: Default::default(), metrics_policy: EventPolicy::Exclude, } } } impl IntoValue for Metrics { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::OpenTelemetry, self.open_telemetry.into_value()); map.insert_unchecked(Property::Prometheus, self.prometheus.into_value()); map.insert_unchecked(Property::Metrics, self.metrics.into_value()); map.insert_unchecked(Property::MetricsPolicy, self.metrics_policy.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Metrics { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::OpenTelemetry) => self.open_telemetry.patch(pointer, value), Some(Property::Prometheus) => self.prometheus.patch(pointer, value), Some(Property::Metrics) => self.metrics.patch(pointer, value), Some(Property::MetricsPolicy) => self.metrics_policy.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl MetricsOtel { fn validate(&self, errors: &mut Vec) -> bool { match self { MetricsOtel::Disabled => true, MetricsOtel::Http(inner) => inner.validate(errors), MetricsOtel::Grpc(inner) => inner.validate(errors), } } } impl Default for MetricsOtel { fn default() -> Self { MetricsOtel::Disabled } } impl Pickle for MetricsOtel { fn pickle(&self, out: &mut Vec) { match self { MetricsOtel::Disabled => { 0u16.pickle(out); } MetricsOtel::Http(inner) => { 1u16.pickle(out); inner.pickle(out); } MetricsOtel::Grpc(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(MetricsOtel::Disabled), 1 => Pickle::unpickle(stream).map(MetricsOtel::Http), 2 => Pickle::unpickle(stream).map(MetricsOtel::Grpc), _ => None, } } } impl IntoValue for MetricsOtel { fn into_value(self) -> JmapValue<'static> { match self { MetricsOtel::Disabled => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Disabled".into())); JmapValue::Object(obj) } MetricsOtel::Http(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Http".into())); obj } MetricsOtel::Grpc(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Grpc".into())); obj } } } } impl RegistryJsonPatch for MetricsOtel { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { MetricsOtelType::Disabled => *self = MetricsOtel::Disabled, MetricsOtelType::Http => *self = MetricsOtel::Http(Default::default()), MetricsOtelType::Grpc => *self = MetricsOtel::Grpc(Default::default()), } } match self { MetricsOtel::Disabled => pointer.assert_eof(), MetricsOtel::Http(inner) => inner.patch(pointer, value), MetricsOtel::Grpc(inner) => inner.patch(pointer, value), } } } impl MetricsOtel { pub fn object_type(&self) -> MetricsOtelType { match self { MetricsOtel::Disabled => MetricsOtelType::Disabled, MetricsOtel::Http(_) => MetricsOtelType::Http, MetricsOtel::Grpc(_) => MetricsOtelType::Grpc, } } } impl MetricsOtelGrpc { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.endpoint { if value.is_empty() { errors.push(ValidationError::required(Property::Endpoint)); } } errors.len() == neb } } impl Pickle for MetricsOtelGrpc { fn pickle(&self, out: &mut Vec) { self.endpoint.pickle(out); self.interval.pickle(out); self.timeout.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.endpoint = Pickle::unpickle(stream)?; this.interval = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; Some(this) } } impl Default for MetricsOtelGrpc { fn default() -> Self { Self { endpoint: Default::default(), interval: Duration::from_millis(60000), timeout: Duration::from_millis(10000), } } } impl IntoValue for MetricsOtelGrpc { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::Endpoint, self.endpoint.into_value()); map.insert_unchecked(Property::Interval, self.interval.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MetricsOtelGrpc { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Endpoint) => self .endpoint .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Interval) => self.interval.patch(pointer, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl MetricsOtelHttp { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.endpoint; if value.is_empty() { errors.push(ValidationError::required(Property::Endpoint)); } let value = &self.http_auth; value.validate(errors); let value = &self.http_headers; for value in value.values() { if value.is_empty() { errors.push(ValidationError::required(Property::HttpHeaders)); } } errors.len() == neb } } impl Pickle for MetricsOtelHttp { fn pickle(&self, out: &mut Vec) { self.endpoint.pickle(out); self.interval.pickle(out); self.timeout.pickle(out); self.http_auth.pickle(out); self.http_headers.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.endpoint = Pickle::unpickle(stream)?; this.interval = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.http_auth = Pickle::unpickle(stream)?; this.http_headers = Pickle::unpickle(stream)?; Some(this) } } impl Default for MetricsOtelHttp { fn default() -> Self { Self { endpoint: Default::default(), interval: Duration::from_millis(60000), timeout: Duration::from_millis(10000), http_auth: Default::default(), http_headers: Default::default(), } } } impl IntoValue for MetricsOtelHttp { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Endpoint, self.endpoint.into_value()); map.insert_unchecked(Property::Interval, self.interval.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::HttpAuth, self.http_auth.into_value()); map.insert_unchecked(Property::HttpHeaders, self.http_headers.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MetricsOtelHttp { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Endpoint) => self .endpoint .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Interval) => self.interval.patch(pointer, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::HttpAuth) => self.http_auth.patch(pointer, value), Some(Property::HttpHeaders) => self .http_headers .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl MetricsPrometheus { fn validate(&self, errors: &mut Vec) -> bool { match self { MetricsPrometheus::Disabled => true, MetricsPrometheus::Enabled(inner) => inner.validate(errors), } } } impl Default for MetricsPrometheus { fn default() -> Self { MetricsPrometheus::Disabled } } impl Pickle for MetricsPrometheus { fn pickle(&self, out: &mut Vec) { match self { MetricsPrometheus::Disabled => { 0u16.pickle(out); } MetricsPrometheus::Enabled(inner) => { 1u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(MetricsPrometheus::Disabled), 1 => Pickle::unpickle(stream).map(MetricsPrometheus::Enabled), _ => None, } } } impl IntoValue for MetricsPrometheus { fn into_value(self) -> JmapValue<'static> { match self { MetricsPrometheus::Disabled => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Disabled".into())); JmapValue::Object(obj) } MetricsPrometheus::Enabled(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Enabled".into())); obj } } } } impl RegistryJsonPatch for MetricsPrometheus { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { MetricsPrometheusType::Disabled => *self = MetricsPrometheus::Disabled, MetricsPrometheusType::Enabled => { *self = MetricsPrometheus::Enabled(Default::default()) } } } match self { MetricsPrometheus::Disabled => pointer.assert_eof(), MetricsPrometheus::Enabled(inner) => inner.patch(pointer, value), } } } impl MetricsPrometheus { pub fn object_type(&self) -> MetricsPrometheusType { match self { MetricsPrometheus::Disabled => MetricsPrometheusType::Disabled, MetricsPrometheus::Enabled(_) => MetricsPrometheusType::Enabled, } } } impl MetricsPrometheusProperties { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.auth_secret; value.validate(errors); if let Some(value) = &self.auth_username { if value.is_empty() { errors.push(ValidationError::required(Property::AuthUsername)); } } errors.len() == neb } } impl Pickle for MetricsPrometheusProperties { fn pickle(&self, out: &mut Vec) { self.auth_secret.pickle(out); self.auth_username.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.auth_secret = Pickle::unpickle(stream)?; this.auth_username = Pickle::unpickle(stream)?; Some(this) } } impl Default for MetricsPrometheusProperties { fn default() -> Self { Self { auth_secret: Default::default(), auth_username: Default::default(), } } } impl IntoValue for MetricsPrometheusProperties { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::AuthSecret, self.auth_secret.into_value()); map.insert_unchecked(Property::AuthUsername, self.auth_username.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MetricsPrometheusProperties { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AuthSecret) => self.auth_secret.patch(pointer, value), Some(Property::AuthUsername) => self .auth_username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MetricsStore { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MetricsStore; fn validate(&self, errors: &mut Vec) -> bool { match self { MetricsStore::Disabled => true, MetricsStore::Default => true, MetricsStore::FoundationDb(inner) => inner.validate(errors), MetricsStore::PostgreSql(inner) => inner.validate(errors), MetricsStore::MySql(inner) => inner.validate(errors), } } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Default for MetricsStore { fn default() -> Self { MetricsStore::Disabled } } impl Pickle for MetricsStore { fn pickle(&self, out: &mut Vec) { match self { MetricsStore::Disabled => { 0u16.pickle(out); } MetricsStore::Default => { 1u16.pickle(out); } MetricsStore::FoundationDb(inner) => { 2u16.pickle(out); inner.pickle(out); } MetricsStore::PostgreSql(inner) => { 3u16.pickle(out); inner.pickle(out); } MetricsStore::MySql(inner) => { 4u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(MetricsStore::Disabled), 1 => Some(MetricsStore::Default), 2 => Pickle::unpickle(stream).map(MetricsStore::FoundationDb), 3 => Pickle::unpickle(stream).map(MetricsStore::PostgreSql), 4 => Pickle::unpickle(stream).map(MetricsStore::MySql), _ => None, } } } impl IntoValue for MetricsStore { fn into_value(self) -> JmapValue<'static> { match self { MetricsStore::Disabled => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Disabled".into())); JmapValue::Object(obj) } MetricsStore::Default => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Default".into())); JmapValue::Object(obj) } MetricsStore::FoundationDb(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("FoundationDb".into())); obj } MetricsStore::PostgreSql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("PostgreSql".into())); obj } MetricsStore::MySql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("MySql".into())); obj } } } } impl RegistryJsonPatch for MetricsStore { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { MetricsStoreType::Disabled => *self = MetricsStore::Disabled, MetricsStoreType::Default => *self = MetricsStore::Default, MetricsStoreType::FoundationDb => { *self = MetricsStore::FoundationDb(Default::default()) } MetricsStoreType::PostgreSql => { *self = MetricsStore::PostgreSql(Default::default()) } MetricsStoreType::MySql => *self = MetricsStore::MySql(Default::default()), } } match self { MetricsStore::Disabled => pointer.assert_eof(), MetricsStore::Default => pointer.assert_eof(), MetricsStore::FoundationDb(inner) => inner.patch(pointer, value), MetricsStore::PostgreSql(inner) => inner.patch(pointer, value), MetricsStore::MySql(inner) => inner.patch(pointer, value), } } } impl MetricsStore { pub fn object_type(&self) -> MetricsStoreType { match self { MetricsStore::Disabled => MetricsStoreType::Disabled, MetricsStore::Default => MetricsStoreType::Default, MetricsStore::FoundationDb(_) => MetricsStoreType::FoundationDb, MetricsStore::PostgreSql(_) => MetricsStoreType::PostgreSql, MetricsStore::MySql(_) => MetricsStoreType::MySql, } } } impl MtaConnectionIpHost { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.ehlo_hostname { if value.is_empty() { errors.push(ValidationError::required(Property::EhloHostname)); } } let value = &self.source_ip; if !value.is_valid() { errors.push(ValidationError::invalid(Property::SourceIp, value)); } errors.len() == neb } } impl Pickle for MtaConnectionIpHost { fn pickle(&self, out: &mut Vec) { self.ehlo_hostname.pickle(out); self.source_ip.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.ehlo_hostname = Pickle::unpickle(stream)?; this.source_ip = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaConnectionIpHost { fn default() -> Self { Self { ehlo_hostname: Default::default(), source_ip: Default::default(), } } } impl IntoValue for MtaConnectionIpHost { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::EhloHostname, self.ehlo_hostname.into_value()); map.insert_unchecked(Property::SourceIp, self.source_ip.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaConnectionIpHost { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::EhloHostname) => self .ehlo_hostname .patch(pointer.with_validators(&[StringValidator::Hostname]), value), Some(Property::SourceIp) => self.source_ip.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaConnectionStrategy { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaConnectionStrategy; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } if let Some(value) = &self.ehlo_hostname { if value.is_empty() { errors.push(ValidationError::required(Property::EhloHostname)); } } let value = &self.source_ips; for value in value.values() { value.validate(errors); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl Pickle for MtaConnectionStrategy { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.description.pickle(out); self.ehlo_hostname.pickle(out); self.source_ips.pickle(out); self.connect_timeout.pickle(out); self.data_timeout.pickle(out); self.ehlo_timeout.pickle(out); self.greeting_timeout.pickle(out); self.mail_from_timeout.pickle(out); self.rcpt_to_timeout.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.ehlo_hostname = Pickle::unpickle(stream)?; this.source_ips = Pickle::unpickle(stream)?; this.connect_timeout = Pickle::unpickle(stream)?; this.data_timeout = Pickle::unpickle(stream)?; this.ehlo_timeout = Pickle::unpickle(stream)?; this.greeting_timeout = Pickle::unpickle(stream)?; this.mail_from_timeout = Pickle::unpickle(stream)?; this.rcpt_to_timeout = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaConnectionStrategy { fn default() -> Self { Self { name: Default::default(), description: Default::default(), ehlo_hostname: Default::default(), source_ips: Default::default(), connect_timeout: Duration::from_millis(300000), data_timeout: Duration::from_millis(600000), ehlo_timeout: Duration::from_millis(300000), greeting_timeout: Duration::from_millis(300000), mail_from_timeout: Duration::from_millis(300000), rcpt_to_timeout: Duration::from_millis(300000), } } } impl IntoValue for MtaConnectionStrategy { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(12); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::EhloHostname, self.ehlo_hostname.into_value()); map.insert_unchecked(Property::SourceIps, self.source_ips.into_value()); map.insert_unchecked(Property::ConnectTimeout, self.connect_timeout.into_value()); map.insert_unchecked(Property::DataTimeout, self.data_timeout.into_value()); map.insert_unchecked(Property::EhloTimeout, self.ehlo_timeout.into_value()); map.insert_unchecked( Property::GreetingTimeout, self.greeting_timeout.into_value(), ); map.insert_unchecked( Property::MailFromTimeout, self.mail_from_timeout.into_value(), ); map.insert_unchecked(Property::RcptToTimeout, self.rcpt_to_timeout.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaConnectionStrategy { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self.name.patch(pointer.assert_read_only()?, value), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::EhloHostname) => self .ehlo_hostname .patch(pointer.with_validators(&[StringValidator::Hostname]), value), Some(Property::SourceIps) => self.source_ips.patch(pointer, value), Some(Property::ConnectTimeout) => self.connect_timeout.patch(pointer, value), Some(Property::DataTimeout) => self.data_timeout.patch(pointer, value), Some(Property::EhloTimeout) => self.ehlo_timeout.patch(pointer, value), Some(Property::GreetingTimeout) => self.greeting_timeout.patch(pointer, value), Some(Property::MailFromTimeout) => self.mail_from_timeout.patch(pointer, value), Some(Property::RcptToTimeout) => self.rcpt_to_timeout.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl MtaDeliveryExpiration { fn validate(&self, errors: &mut Vec) -> bool { match self { MtaDeliveryExpiration::Ttl(inner) => inner.validate(errors), MtaDeliveryExpiration::Attempts(inner) => inner.validate(errors), } } } impl Default for MtaDeliveryExpiration { fn default() -> Self { MtaDeliveryExpiration::Ttl(Default::default()) } } impl Pickle for MtaDeliveryExpiration { fn pickle(&self, out: &mut Vec) { match self { MtaDeliveryExpiration::Ttl(inner) => { 0u16.pickle(out); inner.pickle(out); } MtaDeliveryExpiration::Attempts(inner) => { 1u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(MtaDeliveryExpiration::Ttl), 1 => Pickle::unpickle(stream).map(MtaDeliveryExpiration::Attempts), _ => None, } } } impl IntoValue for MtaDeliveryExpiration { fn into_value(self) -> JmapValue<'static> { match self { MtaDeliveryExpiration::Ttl(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ttl".into())); obj } MtaDeliveryExpiration::Attempts(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Attempts".into())); obj } } } } impl RegistryJsonPatch for MtaDeliveryExpiration { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { MtaDeliveryExpirationType::Ttl => { *self = MtaDeliveryExpiration::Ttl(Default::default()) } MtaDeliveryExpirationType::Attempts => { *self = MtaDeliveryExpiration::Attempts(Default::default()) } } } match self { MtaDeliveryExpiration::Ttl(inner) => inner.patch(pointer, value), MtaDeliveryExpiration::Attempts(inner) => inner.patch(pointer, value), } } } impl MtaDeliveryExpiration { pub fn object_type(&self) -> MtaDeliveryExpirationType { match self { MtaDeliveryExpiration::Ttl(_) => MtaDeliveryExpirationType::Ttl, MtaDeliveryExpiration::Attempts(_) => MtaDeliveryExpirationType::Attempts, } } } impl MtaDeliveryExpirationAttempts { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.max_attempts; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxAttempts, 1)); } errors.len() == neb } } impl Pickle for MtaDeliveryExpirationAttempts { fn pickle(&self, out: &mut Vec) { self.max_attempts.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.max_attempts = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaDeliveryExpirationAttempts { fn default() -> Self { Self { max_attempts: 5u64 } } } impl IntoValue for MtaDeliveryExpirationAttempts { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::MaxAttempts, self.max_attempts.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaDeliveryExpirationAttempts { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::MaxAttempts) => self.max_attempts.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl MtaDeliveryExpirationTtl { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for MtaDeliveryExpirationTtl { fn pickle(&self, out: &mut Vec) { self.expire.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.expire = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaDeliveryExpirationTtl { fn default() -> Self { Self { expire: Duration::from_millis(259200000), } } } impl IntoValue for MtaDeliveryExpirationTtl { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Expire, self.expire.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaDeliveryExpirationTtl { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Expire) => self.expire.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaDeliverySchedule { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaDeliverySchedule; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.expiry; value.validate(errors); let value = &self.notify; value.validate(errors); let value = &self.queue_id; if !value.is_valid() { errors.push(ValidationError::required(Property::QueueId)); } let value = &self.retry; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); i.foreign_key(ObjectType::MtaVirtualQueue, self.queue_id.into(), None); } } impl Pickle for MtaDeliverySchedule { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.description.pickle(out); self.expiry.pickle(out); self.notify.pickle(out); self.queue_id.pickle(out); self.retry.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.expiry = Pickle::unpickle(stream)?; this.notify = Pickle::unpickle(stream)?; this.queue_id = Pickle::unpickle(stream)?; this.retry = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaDeliverySchedule { fn default() -> Self { Self { name: Default::default(), description: Default::default(), expiry: Default::default(), notify: Default::default(), queue_id: Default::default(), retry: Default::default(), } } } impl IntoValue for MtaDeliverySchedule { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Expiry, self.expiry.into_value()); map.insert_unchecked(Property::Notify, self.notify.into_value()); map.insert_unchecked(Property::QueueId, self.queue_id.into_value()); map.insert_unchecked(Property::Retry, self.retry.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaDeliverySchedule { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self.name.patch(pointer.assert_read_only()?, value), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Expiry) => self.expiry.patch(pointer, value), Some(Property::Notify) => self.notify.patch(pointer, value), Some(Property::QueueId) => self.queue_id.patch(pointer, value), Some(Property::Retry) => self.retry.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl MtaDeliveryScheduleInterval { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for MtaDeliveryScheduleInterval { fn pickle(&self, out: &mut Vec) { self.duration.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.duration = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaDeliveryScheduleInterval { fn default() -> Self { Self { duration: Duration::from_millis(3600000), } } } impl IntoValue for MtaDeliveryScheduleInterval { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Duration, self.duration.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaDeliveryScheduleInterval { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Duration) => self.duration.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl MtaDeliveryScheduleIntervals { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.intervals; for value in value.values() { value.validate(errors); } if value.len() < 1 { errors.push(ValidationError::min_items(Property::Intervals, 1)); } errors.len() == neb } } impl Pickle for MtaDeliveryScheduleIntervals { fn pickle(&self, out: &mut Vec) { self.intervals.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.intervals = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaDeliveryScheduleIntervals { fn default() -> Self { Self { intervals: Default::default(), } } } impl IntoValue for MtaDeliveryScheduleIntervals { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Intervals, self.intervals.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaDeliveryScheduleIntervals { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Intervals) => self.intervals.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl MtaDeliveryScheduleIntervalsOrDefault { fn validate(&self, errors: &mut Vec) -> bool { match self { MtaDeliveryScheduleIntervalsOrDefault::Default => true, MtaDeliveryScheduleIntervalsOrDefault::Custom(inner) => inner.validate(errors), } } } impl Default for MtaDeliveryScheduleIntervalsOrDefault { fn default() -> Self { MtaDeliveryScheduleIntervalsOrDefault::Default } } impl Pickle for MtaDeliveryScheduleIntervalsOrDefault { fn pickle(&self, out: &mut Vec) { match self { MtaDeliveryScheduleIntervalsOrDefault::Default => { 0u16.pickle(out); } MtaDeliveryScheduleIntervalsOrDefault::Custom(inner) => { 1u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(MtaDeliveryScheduleIntervalsOrDefault::Default), 1 => Pickle::unpickle(stream).map(MtaDeliveryScheduleIntervalsOrDefault::Custom), _ => None, } } } impl IntoValue for MtaDeliveryScheduleIntervalsOrDefault { fn into_value(self) -> JmapValue<'static> { match self { MtaDeliveryScheduleIntervalsOrDefault::Default => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Default".into())); JmapValue::Object(obj) } MtaDeliveryScheduleIntervalsOrDefault::Custom(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Custom".into())); obj } } } } impl RegistryJsonPatch for MtaDeliveryScheduleIntervalsOrDefault { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { MtaDeliveryScheduleIntervalsOrDefaultType::Default => { *self = MtaDeliveryScheduleIntervalsOrDefault::Default } MtaDeliveryScheduleIntervalsOrDefaultType::Custom => { *self = MtaDeliveryScheduleIntervalsOrDefault::Custom(Default::default()) } } } match self { MtaDeliveryScheduleIntervalsOrDefault::Default => pointer.assert_eof(), MtaDeliveryScheduleIntervalsOrDefault::Custom(inner) => inner.patch(pointer, value), } } } impl MtaDeliveryScheduleIntervalsOrDefault { pub fn object_type(&self) -> MtaDeliveryScheduleIntervalsOrDefaultType { match self { MtaDeliveryScheduleIntervalsOrDefault::Default => { MtaDeliveryScheduleIntervalsOrDefaultType::Default } MtaDeliveryScheduleIntervalsOrDefault::Custom(_) => { MtaDeliveryScheduleIntervalsOrDefaultType::Custom } } } } impl ObjectImpl for MtaExtensions { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaExtensions; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.chunking; value.validate(errors); let value = &self.deliver_by; value.validate(errors); let value = &self.dsn; value.validate(errors); let value = &self.expn; value.validate(errors); let value = &self.future_release; value.validate(errors); let value = &self.mt_priority; value.validate(errors); let value = &self.no_soliciting; value.validate(errors); let value = &self.pipelining; value.validate(errors); let value = &self.require_tls; value.validate(errors); let value = &self.vrfy; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl MtaExtensions { pub fn ctx_chunking(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.chunking, default: Some(Expression { else_: "true".to_string(), ..Default::default() }), property: Property::Chunking, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_deliver_by(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.deliver_by, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "!is_empty(authenticated_as)".to_string(), then: "15d".to_string(), }]), }), property: Property::DeliverBy, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_dsn(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.dsn, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "!is_empty(authenticated_as)".to_string(), then: "true".to_string(), }]), }), property: Property::Dsn, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_expn(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.expn, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "!is_empty(authenticated_as)".to_string(), then: "true".to_string(), }]), }), property: Property::Expn, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_future_release(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.future_release, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "!is_empty(authenticated_as)".to_string(), then: "7d".to_string(), }]), }), property: Property::FutureRelease, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_mt_priority(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.mt_priority, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "!is_empty(authenticated_as)".to_string(), then: "mixer".to_string(), }]), }), property: Property::MtPriority, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: MTA_PRIORITY_CONSTANT, } } pub fn ctx_no_soliciting(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.no_soliciting, default: Some(Expression { else_: "''".to_string(), ..Default::default() }), property: Property::NoSoliciting, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_pipelining(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.pipelining, default: Some(Expression { else_: "true".to_string(), ..Default::default() }), property: Property::Pipelining, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_require_tls(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.require_tls, default: Some(Expression { else_: "true".to_string(), ..Default::default() }), property: Property::RequireTls, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_vrfy(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.vrfy, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "!is_empty(authenticated_as)".to_string(), then: "true".to_string(), }]), }), property: Property::Vrfy, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_chunking(), self.ctx_deliver_by(), self.ctx_dsn(), self.ctx_expn(), self.ctx_future_release(), self.ctx_mt_priority(), self.ctx_no_soliciting(), self.ctx_pipelining(), self.ctx_require_tls(), self.ctx_vrfy(), ] } } impl Pickle for MtaExtensions { fn pickle(&self, out: &mut Vec) { self.chunking.pickle(out); self.deliver_by.pickle(out); self.dsn.pickle(out); self.expn.pickle(out); self.future_release.pickle(out); self.mt_priority.pickle(out); self.no_soliciting.pickle(out); self.pipelining.pickle(out); self.require_tls.pickle(out); self.vrfy.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.chunking = Pickle::unpickle(stream)?; this.deliver_by = Pickle::unpickle(stream)?; this.dsn = Pickle::unpickle(stream)?; this.expn = Pickle::unpickle(stream)?; this.future_release = Pickle::unpickle(stream)?; this.mt_priority = Pickle::unpickle(stream)?; this.no_soliciting = Pickle::unpickle(stream)?; this.pipelining = Pickle::unpickle(stream)?; this.require_tls = Pickle::unpickle(stream)?; this.vrfy = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaExtensions { fn default() -> Self { Self { chunking: Expression { else_: "true".to_string(), ..Default::default() }, deliver_by: Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "!is_empty(authenticated_as)".to_string(), then: "15d".to_string(), }]), }, dsn: Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "!is_empty(authenticated_as)".to_string(), then: "true".to_string(), }]), }, expn: Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "!is_empty(authenticated_as)".to_string(), then: "true".to_string(), }]), }, future_release: Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "!is_empty(authenticated_as)".to_string(), then: "7d".to_string(), }]), }, mt_priority: Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "!is_empty(authenticated_as)".to_string(), then: "mixer".to_string(), }]), }, no_soliciting: Expression { else_: "''".to_string(), ..Default::default() }, pipelining: Expression { else_: "true".to_string(), ..Default::default() }, require_tls: Expression { else_: "true".to_string(), ..Default::default() }, vrfy: Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "!is_empty(authenticated_as)".to_string(), then: "true".to_string(), }]), }, } } } impl IntoValue for MtaExtensions { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(12); map.insert_unchecked(Property::Chunking, self.chunking.into_value()); map.insert_unchecked(Property::DeliverBy, self.deliver_by.into_value()); map.insert_unchecked(Property::Dsn, self.dsn.into_value()); map.insert_unchecked(Property::Expn, self.expn.into_value()); map.insert_unchecked(Property::FutureRelease, self.future_release.into_value()); map.insert_unchecked(Property::MtPriority, self.mt_priority.into_value()); map.insert_unchecked(Property::NoSoliciting, self.no_soliciting.into_value()); map.insert_unchecked(Property::Pipelining, self.pipelining.into_value()); map.insert_unchecked(Property::RequireTls, self.require_tls.into_value()); map.insert_unchecked(Property::Vrfy, self.vrfy.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaExtensions { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Chunking) => self.chunking.patch(pointer, value), Some(Property::DeliverBy) => self.deliver_by.patch(pointer, value), Some(Property::Dsn) => self.dsn.patch(pointer, value), Some(Property::Expn) => self.expn.patch(pointer, value), Some(Property::FutureRelease) => self.future_release.patch(pointer, value), Some(Property::MtPriority) => self.mt_priority.patch(pointer, value), Some(Property::NoSoliciting) => self.no_soliciting.patch(pointer, value), Some(Property::Pipelining) => self.pipelining.patch(pointer, value), Some(Property::RequireTls) => self.require_tls.patch(pointer, value), Some(Property::Vrfy) => self.vrfy.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaHook { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaHook; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.enable; value.validate(errors); let value = &self.url; if value.is_empty() { errors.push(ValidationError::required(Property::Url)); } let value = &self.http_auth; value.validate(errors); let value = &self.http_headers; for value in value.values() { if value.is_empty() { errors.push(ValidationError::required(Property::HttpHeaders)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl MtaHook { pub fn ctx_enable(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.enable, default: Some(Expression { else_: "true".to_string(), ..Default::default() }), property: Property::Enable, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_enable()] } } impl Pickle for MtaHook { fn pickle(&self, out: &mut Vec) { self.allow_invalid_certs.pickle(out); self.enable.pickle(out); self.max_response_size.pickle(out); self.temp_fail_on_error.pickle(out); self.stages.pickle(out); self.timeout.pickle(out); self.url.pickle(out); self.http_auth.pickle(out); self.http_headers.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.allow_invalid_certs = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.max_response_size = Pickle::unpickle(stream)?; this.temp_fail_on_error = Pickle::unpickle(stream)?; this.stages = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.url = Pickle::unpickle(stream)?; this.http_auth = Pickle::unpickle(stream)?; this.http_headers = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaHook { fn default() -> Self { Self { allow_invalid_certs: false, enable: Expression { else_: "true".to_string(), ..Default::default() }, max_response_size: 52428800u64, temp_fail_on_error: true, stages: Map::new(vec![MtaStage::Data]), timeout: Duration::from_millis(30000), url: Default::default(), http_auth: Default::default(), http_headers: Default::default(), } } } impl IntoValue for MtaHook { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked( Property::AllowInvalidCerts, self.allow_invalid_certs.into_value(), ); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked( Property::MaxResponseSize, self.max_response_size.into_value(), ); map.insert_unchecked( Property::TempFailOnError, self.temp_fail_on_error.into_value(), ); map.insert_unchecked(Property::Stages, self.stages.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::Url, self.url.into_value()); map.insert_unchecked(Property::HttpAuth, self.http_auth.into_value()); map.insert_unchecked(Property::HttpHeaders, self.http_headers.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaHook { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AllowInvalidCerts) => self.allow_invalid_certs.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::MaxResponseSize) => self.max_response_size.patch(pointer, value), Some(Property::TempFailOnError) => self.temp_fail_on_error.patch(pointer, value), Some(Property::Stages) => self.stages.patch(pointer, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::Url) => self .url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::HttpAuth) => self.http_auth.patch(pointer, value), Some(Property::HttpHeaders) => self .http_headers .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaInboundSession { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaInboundSession; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.max_duration; value.validate(errors); let value = &self.timeout; value.validate(errors); let value = &self.transfer_limit; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl MtaInboundSession { pub fn ctx_max_duration(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.max_duration, default: Some(Expression { else_: "10m".to_string(), ..Default::default() }), property: Property::MaxDuration, allowed_variables: MTA_CONNECTION_VARIABLE, allowed_constants: &[], } } pub fn ctx_timeout(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.timeout, default: Some(Expression { else_: "5m".to_string(), ..Default::default() }), property: Property::Timeout, allowed_variables: MTA_CONNECTION_VARIABLE, allowed_constants: &[], } } pub fn ctx_transfer_limit(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.transfer_limit, default: Some(Expression { else_: "262144000".to_string(), ..Default::default() }), property: Property::TransferLimit, allowed_variables: MTA_CONNECTION_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_max_duration(), self.ctx_timeout(), self.ctx_transfer_limit(), ] } } impl Pickle for MtaInboundSession { fn pickle(&self, out: &mut Vec) { self.max_duration.pickle(out); self.timeout.pickle(out); self.transfer_limit.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.max_duration = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.transfer_limit = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaInboundSession { fn default() -> Self { Self { max_duration: Expression { else_: "10m".to_string(), ..Default::default() }, timeout: Expression { else_: "5m".to_string(), ..Default::default() }, transfer_limit: Expression { else_: "262144000".to_string(), ..Default::default() }, } } } impl IntoValue for MtaInboundSession { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::MaxDuration, self.max_duration.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::TransferLimit, self.transfer_limit.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaInboundSession { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::MaxDuration) => self.max_duration.patch(pointer, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::TransferLimit) => self.transfer_limit.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaInboundThrottle { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaInboundThrottle; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } let value = &self.match_; value.validate(errors); let value = &self.rate; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl MtaInboundThrottle { pub fn ctx_match_(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.match_, default: Some(Expression { else_: "true".to_string(), ..Default::default() }), property: Property::Match, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_match_()] } } impl Pickle for MtaInboundThrottle { fn pickle(&self, out: &mut Vec) { self.enable.pickle(out); self.description.pickle(out); self.key.pickle(out); self.match_.pickle(out); self.rate.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.enable = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.key = Pickle::unpickle(stream)?; this.match_ = Pickle::unpickle(stream)?; this.rate = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaInboundThrottle { fn default() -> Self { Self { enable: true, description: Default::default(), key: Default::default(), match_: Expression { else_: "true".to_string(), ..Default::default() }, rate: Default::default(), } } } impl IntoValue for MtaInboundThrottle { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Key, self.key.into_value()); map.insert_unchecked(Property::Match, self.match_.into_value()); map.insert_unchecked(Property::Rate, self.rate.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaInboundThrottle { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Description) => { self.description.patch(pointer.assert_read_only()?, value) } Some(Property::Key) => self.key.patch(pointer, value), Some(Property::Match) => self.match_.patch(pointer, value), Some(Property::Rate) => self.rate.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaMilter { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaMilter; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.enable; value.validate(errors); let value = &self.hostname; if value.is_empty() { errors.push(ValidationError::required(Property::Hostname)); } let value = &self.port; if *value > 65535 { errors.push(ValidationError::max_value(Property::Port, 65535)); } if *value < 1 { errors.push(ValidationError::min_value(Property::Port, 1)); } let value = &self.stages; if value.len() < 1 { errors.push(ValidationError::min_items(Property::Stages, 1)); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl MtaMilter { pub fn ctx_enable(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.enable, default: Some(Expression { else_: "true".to_string(), ..Default::default() }), property: Property::Enable, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_enable()] } } impl Pickle for MtaMilter { fn pickle(&self, out: &mut Vec) { self.allow_invalid_certs.pickle(out); self.enable.pickle(out); self.hostname.pickle(out); self.max_response_size.pickle(out); self.temp_fail_on_error.pickle(out); self.protocol_version.pickle(out); self.port.pickle(out); self.stages.pickle(out); self.timeout_command.pickle(out); self.timeout_connect.pickle(out); self.timeout_data.pickle(out); self.use_tls.pickle(out); self.flags_action.pickle(out); self.flags_protocol.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.allow_invalid_certs = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.hostname = Pickle::unpickle(stream)?; this.max_response_size = Pickle::unpickle(stream)?; this.temp_fail_on_error = Pickle::unpickle(stream)?; this.protocol_version = Pickle::unpickle(stream)?; this.port = Pickle::unpickle(stream)?; this.stages = Pickle::unpickle(stream)?; this.timeout_command = Pickle::unpickle(stream)?; this.timeout_connect = Pickle::unpickle(stream)?; this.timeout_data = Pickle::unpickle(stream)?; this.use_tls = Pickle::unpickle(stream)?; this.flags_action = Pickle::unpickle(stream)?; this.flags_protocol = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaMilter { fn default() -> Self { Self { allow_invalid_certs: false, enable: Expression { else_: "true".to_string(), ..Default::default() }, hostname: Default::default(), max_response_size: 52428800u64, temp_fail_on_error: true, protocol_version: MilterVersion::V6, port: 11332u64, stages: Map::new(vec![MtaStage::Data]), timeout_command: Duration::from_millis(30000), timeout_connect: Duration::from_millis(30000), timeout_data: Duration::from_millis(60000), use_tls: false, flags_action: Default::default(), flags_protocol: Default::default(), } } } impl IntoValue for MtaMilter { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(16); map.insert_unchecked( Property::AllowInvalidCerts, self.allow_invalid_certs.into_value(), ); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Hostname, self.hostname.into_value()); map.insert_unchecked( Property::MaxResponseSize, self.max_response_size.into_value(), ); map.insert_unchecked( Property::TempFailOnError, self.temp_fail_on_error.into_value(), ); map.insert_unchecked( Property::ProtocolVersion, self.protocol_version.into_value(), ); map.insert_unchecked(Property::Port, self.port.into_value()); map.insert_unchecked(Property::Stages, self.stages.into_value()); map.insert_unchecked(Property::TimeoutCommand, self.timeout_command.into_value()); map.insert_unchecked(Property::TimeoutConnect, self.timeout_connect.into_value()); map.insert_unchecked(Property::TimeoutData, self.timeout_data.into_value()); map.insert_unchecked(Property::UseTls, self.use_tls.into_value()); map.insert_unchecked(Property::FlagsAction, self.flags_action.into_value()); map.insert_unchecked(Property::FlagsProtocol, self.flags_protocol.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaMilter { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AllowInvalidCerts) => self.allow_invalid_certs.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Hostname) => self .hostname .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MaxResponseSize) => self.max_response_size.patch(pointer, value), Some(Property::TempFailOnError) => self.temp_fail_on_error.patch(pointer, value), Some(Property::ProtocolVersion) => self.protocol_version.patch(pointer, value), Some(Property::Port) => self.port.patch(pointer, value), Some(Property::Stages) => self.stages.patch(pointer, value), Some(Property::TimeoutCommand) => self.timeout_command.patch(pointer, value), Some(Property::TimeoutConnect) => self.timeout_connect.patch(pointer, value), Some(Property::TimeoutData) => self.timeout_data.patch(pointer, value), Some(Property::UseTls) => self.use_tls.patch(pointer, value), Some(Property::FlagsAction) => self.flags_action.patch(pointer, value), Some(Property::FlagsProtocol) => self.flags_protocol.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaOutboundStrategy { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaOutboundStrategy; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.connection; value.validate(errors); let value = &self.route; value.validate(errors); let value = &self.schedule; value.validate(errors); let value = &self.tls; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl MtaOutboundStrategy { pub fn ctx_connection(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.connection, default: Some(Expression { else_: "'default'".to_string(), ..Default::default() }), property: Property::Connection, allowed_variables: MTA_QUEUE_HOST_VARIABLE, allowed_constants: &[], } } pub fn ctx_route(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.route, default: Some(Expression { else_: "'mx'".to_string(), match_: List::from_iter([ExpressionMatch { if_: "is_local_domain(rcpt_domain)".to_string(), then: "'local'".to_string(), }]), }), property: Property::Route, allowed_variables: MTA_QUEUE_RCPT_VARIABLE, allowed_constants: &[], } } pub fn ctx_schedule(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.schedule, default: Some(Expression { else_: "'remote'".to_string(), match_: List::from_iter([ ExpressionMatch { if_: "is_local_domain(rcpt_domain)".to_string(), then: "'local'".to_string(), }, ExpressionMatch { if_: "source == 'dsn'".to_string(), then: "'dsn'".to_string(), }, ExpressionMatch { if_: "source == 'report'".to_string(), then: "'report'".to_string(), }, ]), }), property: Property::Schedule, allowed_variables: MTA_QUEUE_RCPT_VARIABLE, allowed_constants: &[], } } pub fn ctx_tls(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.tls, default: Some(Expression { else_: "'default'".to_string(), match_: List::from_iter([ExpressionMatch { if_: "retry_num > 0 && last_error == 'tls'".to_string(), then: "'invalid-tls'".to_string(), }]), }), property: Property::Tls, allowed_variables: MTA_QUEUE_HOST_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_connection(), self.ctx_route(), self.ctx_schedule(), self.ctx_tls(), ] } } impl Pickle for MtaOutboundStrategy { fn pickle(&self, out: &mut Vec) { self.connection.pickle(out); self.route.pickle(out); self.schedule.pickle(out); self.tls.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.connection = Pickle::unpickle(stream)?; this.route = Pickle::unpickle(stream)?; this.schedule = Pickle::unpickle(stream)?; this.tls = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaOutboundStrategy { fn default() -> Self { Self { connection: Expression { else_: "'default'".to_string(), ..Default::default() }, route: Expression { else_: "'mx'".to_string(), match_: List::from_iter([ExpressionMatch { if_: "is_local_domain(rcpt_domain)".to_string(), then: "'local'".to_string(), }]), }, schedule: Expression { else_: "'remote'".to_string(), match_: List::from_iter([ ExpressionMatch { if_: "is_local_domain(rcpt_domain)".to_string(), then: "'local'".to_string(), }, ExpressionMatch { if_: "source == 'dsn'".to_string(), then: "'dsn'".to_string(), }, ExpressionMatch { if_: "source == 'report'".to_string(), then: "'report'".to_string(), }, ]), }, tls: Expression { else_: "'default'".to_string(), match_: List::from_iter([ExpressionMatch { if_: "retry_num > 0 && last_error == 'tls'".to_string(), then: "'invalid-tls'".to_string(), }]), }, } } } impl IntoValue for MtaOutboundStrategy { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Connection, self.connection.into_value()); map.insert_unchecked(Property::Route, self.route.into_value()); map.insert_unchecked(Property::Schedule, self.schedule.into_value()); map.insert_unchecked(Property::Tls, self.tls.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaOutboundStrategy { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Connection) => self.connection.patch(pointer, value), Some(Property::Route) => self.route.patch(pointer, value), Some(Property::Schedule) => self.schedule.patch(pointer, value), Some(Property::Tls) => self.tls.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaOutboundThrottle { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaOutboundThrottle; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } let value = &self.match_; value.validate(errors); let value = &self.rate; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl MtaOutboundThrottle { pub fn ctx_match_(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.match_, default: Some(Expression { else_: "true".to_string(), ..Default::default() }), property: Property::Match, allowed_variables: MTA_QUEUE_HOST_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_match_()] } } impl Pickle for MtaOutboundThrottle { fn pickle(&self, out: &mut Vec) { self.enable.pickle(out); self.description.pickle(out); self.key.pickle(out); self.match_.pickle(out); self.rate.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.enable = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.key = Pickle::unpickle(stream)?; this.match_ = Pickle::unpickle(stream)?; this.rate = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaOutboundThrottle { fn default() -> Self { Self { enable: true, description: Default::default(), key: Default::default(), match_: Expression { else_: "true".to_string(), ..Default::default() }, rate: Default::default(), } } } impl IntoValue for MtaOutboundThrottle { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Key, self.key.into_value()); map.insert_unchecked(Property::Match, self.match_.into_value()); map.insert_unchecked(Property::Rate, self.rate.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaOutboundThrottle { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Key) => self.key.patch(pointer, value), Some(Property::Match) => self.match_.patch(pointer, value), Some(Property::Rate) => self.rate.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaQueueQuota { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaQueueQuota; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.match_; if !value.match_.is_empty() || !value.else_.is_empty() { value.validate(errors); } if let Some(value) = &self.messages { if *value < 1 { errors.push(ValidationError::min_value(Property::Messages, 1)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl MtaQueueQuota { pub fn ctx_match_(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.match_, default: None, property: Property::Match, allowed_variables: MTA_QUEUE_HOST_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_match_()] } } impl Pickle for MtaQueueQuota { fn pickle(&self, out: &mut Vec) { self.enable.pickle(out); self.description.pickle(out); self.key.pickle(out); self.match_.pickle(out); self.messages.pickle(out); self.size.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.enable = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.key = Pickle::unpickle(stream)?; this.match_ = Pickle::unpickle(stream)?; this.messages = Pickle::unpickle(stream)?; this.size = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaQueueQuota { fn default() -> Self { Self { enable: true, description: Default::default(), key: Default::default(), match_: Default::default(), messages: Default::default(), size: Default::default(), } } } impl IntoValue for MtaQueueQuota { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Key, self.key.into_value()); map.insert_unchecked(Property::Match, self.match_.into_value()); map.insert_unchecked(Property::Messages, self.messages.into_value()); map.insert_unchecked(Property::Size, self.size.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaQueueQuota { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Description) => { self.description.patch(pointer.assert_read_only()?, value) } Some(Property::Key) => self.key.patch(pointer, value), Some(Property::Match) => self.match_.patch(pointer, value), Some(Property::Messages) => self.messages.patch(pointer, value), Some(Property::Size) => self.size.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaRoute { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaRoute; fn validate(&self, errors: &mut Vec) -> bool { match self { MtaRoute::Mx(inner) => inner.validate(errors), MtaRoute::Relay(inner) => inner.validate(errors), MtaRoute::Local(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { MtaRoute::Mx(object) => { object.index(i); } MtaRoute::Relay(object) => { object.index(i); } MtaRoute::Local(object) => { object.index(i); } } } } impl Default for MtaRoute { fn default() -> Self { MtaRoute::Mx(Default::default()) } } impl Pickle for MtaRoute { fn pickle(&self, out: &mut Vec) { match self { MtaRoute::Mx(inner) => { 0u16.pickle(out); inner.pickle(out); } MtaRoute::Relay(inner) => { 1u16.pickle(out); inner.pickle(out); } MtaRoute::Local(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(MtaRoute::Mx), 1 => Pickle::unpickle(stream).map(MtaRoute::Relay), 2 => Pickle::unpickle(stream).map(MtaRoute::Local), _ => None, } } } impl IntoValue for MtaRoute { fn into_value(self) -> JmapValue<'static> { match self { MtaRoute::Mx(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Mx".into())); obj } MtaRoute::Relay(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Relay".into())); obj } MtaRoute::Local(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Local".into())); obj } } } } impl RegistryJsonPatch for MtaRoute { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { MtaRouteType::Mx => *self = MtaRoute::Mx(Default::default()), MtaRouteType::Relay => *self = MtaRoute::Relay(Default::default()), MtaRouteType::Local => *self = MtaRoute::Local(Default::default()), } } match self { MtaRoute::Mx(inner) => inner.patch(pointer, value), MtaRoute::Relay(inner) => inner.patch(pointer, value), MtaRoute::Local(inner) => inner.patch(pointer, value), } } } impl MtaRoute { pub fn object_type(&self) -> MtaRouteType { match self { MtaRoute::Mx(_) => MtaRouteType::Mx, MtaRoute::Relay(_) => MtaRouteType::Relay, MtaRoute::Local(_) => MtaRouteType::Local, } } } impl MtaRouteCommon { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl Pickle for MtaRouteCommon { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.description.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaRouteCommon { fn default() -> Self { Self { name: Default::default(), description: Default::default(), } } } impl IntoValue for MtaRouteCommon { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaRouteCommon { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self.name.patch(pointer.assert_read_only()?, value), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl MtaRouteMx { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.max_multihomed; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxMultihomed, 1)); } let value = &self.max_mx_hosts; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxMxHosts, 1)); } let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl Pickle for MtaRouteMx { fn pickle(&self, out: &mut Vec) { self.ip_lookup_strategy.pickle(out); self.max_multihomed.pickle(out); self.max_mx_hosts.pickle(out); self.name.pickle(out); self.description.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.ip_lookup_strategy = Pickle::unpickle(stream)?; this.max_multihomed = Pickle::unpickle(stream)?; this.max_mx_hosts = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaRouteMx { fn default() -> Self { Self { ip_lookup_strategy: MtaIpStrategy::V4ThenV6, max_multihomed: 2u64, max_mx_hosts: 5u64, name: Default::default(), description: Default::default(), } } } impl IntoValue for MtaRouteMx { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked( Property::IpLookupStrategy, self.ip_lookup_strategy.into_value(), ); map.insert_unchecked(Property::MaxMultihomed, self.max_multihomed.into_value()); map.insert_unchecked(Property::MaxMxHosts, self.max_mx_hosts.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaRouteMx { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::IpLookupStrategy) => self.ip_lookup_strategy.patch(pointer, value), Some(Property::MaxMultihomed) => self.max_multihomed.patch(pointer, value), Some(Property::MaxMxHosts) => self.max_mx_hosts.patch(pointer, value), Some(Property::Name) => self.name.patch(pointer.assert_read_only()?, value), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl MtaRouteRelay { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.address; if value.is_empty() { errors.push(ValidationError::required(Property::Address)); } let value = &self.auth_secret; value.validate(errors); if let Some(value) = &self.auth_username { if value.is_empty() { errors.push(ValidationError::required(Property::AuthUsername)); } } let value = &self.port; if *value > 65535 { errors.push(ValidationError::max_value(Property::Port, 65535)); } if *value < 1 { errors.push(ValidationError::min_value(Property::Port, 1)); } let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl Pickle for MtaRouteRelay { fn pickle(&self, out: &mut Vec) { self.address.pickle(out); self.auth_secret.pickle(out); self.auth_username.pickle(out); self.port.pickle(out); self.protocol.pickle(out); self.allow_invalid_certs.pickle(out); self.implicit_tls.pickle(out); self.name.pickle(out); self.description.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.address = Pickle::unpickle(stream)?; this.auth_secret = Pickle::unpickle(stream)?; this.auth_username = Pickle::unpickle(stream)?; this.port = Pickle::unpickle(stream)?; this.protocol = Pickle::unpickle(stream)?; this.allow_invalid_certs = Pickle::unpickle(stream)?; this.implicit_tls = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaRouteRelay { fn default() -> Self { Self { address: Default::default(), auth_secret: Default::default(), auth_username: Default::default(), port: 25u64, protocol: MtaProtocol::Smtp, allow_invalid_certs: false, implicit_tls: false, name: Default::default(), description: Default::default(), } } } impl IntoValue for MtaRouteRelay { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::Address, self.address.into_value()); map.insert_unchecked(Property::AuthSecret, self.auth_secret.into_value()); map.insert_unchecked(Property::AuthUsername, self.auth_username.into_value()); map.insert_unchecked(Property::Port, self.port.into_value()); map.insert_unchecked(Property::Protocol, self.protocol.into_value()); map.insert_unchecked( Property::AllowInvalidCerts, self.allow_invalid_certs.into_value(), ); map.insert_unchecked(Property::ImplicitTls, self.implicit_tls.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaRouteRelay { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Address) => self .address .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AuthSecret) => self.auth_secret.patch(pointer, value), Some(Property::AuthUsername) => self.auth_username.patch(pointer, value), Some(Property::Port) => self.port.patch(pointer, value), Some(Property::Protocol) => self.protocol.patch(pointer, value), Some(Property::AllowInvalidCerts) => self.allow_invalid_certs.patch(pointer, value), Some(Property::ImplicitTls) => self.implicit_tls.patch(pointer, value), Some(Property::Name) => self.name.patch(pointer.assert_read_only()?, value), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaStageAuth { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaStageAuth; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.max_failures; value.validate(errors); let value = &self.wait_on_fail; value.validate(errors); let value = &self.sasl_mechanisms; value.validate(errors); let value = &self.must_match_sender; value.validate(errors); let value = &self.require; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl MtaStageAuth { pub fn ctx_max_failures(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.max_failures, default: Some(Expression { else_: "3".to_string(), ..Default::default() }), property: Property::MaxFailures, allowed_variables: MTA_EHLO_VARIABLE, allowed_constants: &[], } } pub fn ctx_wait_on_fail(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.wait_on_fail, default: Some(Expression { else_: "5s".to_string(), ..Default::default() }), property: Property::WaitOnFail, allowed_variables: MTA_EHLO_VARIABLE, allowed_constants: &[], } } pub fn ctx_sasl_mechanisms(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.sasl_mechanisms, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ ExpressionMatch { if_: "local_port != 25 && is_tls".to_string(), then: "[plain, login, oauthbearer, xoauth2]".to_string(), }, ExpressionMatch { if_: "local_port != 25".to_string(), then: "[oauthbearer, xoauth2]".to_string(), }, ]), }), property: Property::SaslMechanisms, allowed_variables: MTA_EHLO_VARIABLE, allowed_constants: MTA_AUTH_TYPE_CONSTANT, } } pub fn ctx_must_match_sender(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.must_match_sender, default: Some(Expression { else_: "true".to_string(), ..Default::default() }), property: Property::MustMatchSender, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_require(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.require, default: Some(Expression { else_: "local_port != 25".to_string(), ..Default::default() }), property: Property::Require, allowed_variables: MTA_EHLO_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_max_failures(), self.ctx_wait_on_fail(), self.ctx_sasl_mechanisms(), self.ctx_must_match_sender(), self.ctx_require(), ] } } impl Pickle for MtaStageAuth { fn pickle(&self, out: &mut Vec) { self.max_failures.pickle(out); self.wait_on_fail.pickle(out); self.sasl_mechanisms.pickle(out); self.must_match_sender.pickle(out); self.require.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.max_failures = Pickle::unpickle(stream)?; this.wait_on_fail = Pickle::unpickle(stream)?; this.sasl_mechanisms = Pickle::unpickle(stream)?; this.must_match_sender = Pickle::unpickle(stream)?; this.require = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaStageAuth { fn default() -> Self { Self { max_failures: Expression { else_: "3".to_string(), ..Default::default() }, wait_on_fail: Expression { else_: "5s".to_string(), ..Default::default() }, sasl_mechanisms: Expression { else_: "false".to_string(), match_: List::from_iter([ ExpressionMatch { if_: "local_port != 25 && is_tls".to_string(), then: "[plain, login, oauthbearer, xoauth2]".to_string(), }, ExpressionMatch { if_: "local_port != 25".to_string(), then: "[oauthbearer, xoauth2]".to_string(), }, ]), }, must_match_sender: Expression { else_: "true".to_string(), ..Default::default() }, require: Expression { else_: "local_port != 25".to_string(), ..Default::default() }, } } } impl IntoValue for MtaStageAuth { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::MaxFailures, self.max_failures.into_value()); map.insert_unchecked(Property::WaitOnFail, self.wait_on_fail.into_value()); map.insert_unchecked(Property::SaslMechanisms, self.sasl_mechanisms.into_value()); map.insert_unchecked( Property::MustMatchSender, self.must_match_sender.into_value(), ); map.insert_unchecked(Property::Require, self.require.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaStageAuth { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::MaxFailures) => self.max_failures.patch(pointer, value), Some(Property::WaitOnFail) => self.wait_on_fail.patch(pointer, value), Some(Property::SaslMechanisms) => self.sasl_mechanisms.patch(pointer, value), Some(Property::MustMatchSender) => self.must_match_sender.patch(pointer, value), Some(Property::Require) => self.require.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaStageConnect { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaStageConnect; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.smtp_greeting; value.validate(errors); let value = &self.hostname; value.validate(errors); let value = &self.script; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl MtaStageConnect { pub fn ctx_smtp_greeting(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.smtp_greeting, default: Some(Expression { else_: "system('hostname') + ' INBUXA ESMTP at your service'".to_string(), ..Default::default() }), property: Property::SmtpGreeting, allowed_variables: MTA_CONNECTION_VARIABLE, allowed_constants: &[], } } pub fn ctx_hostname(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.hostname, default: Some(Expression { else_: "system('hostname')".to_string(), ..Default::default() }), property: Property::Hostname, allowed_variables: MTA_CONNECTION_VARIABLE, allowed_constants: &[], } } pub fn ctx_script(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.script, default: Some(Expression { else_: "false".to_string(), ..Default::default() }), property: Property::Script, allowed_variables: MTA_CONNECTION_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_smtp_greeting(), self.ctx_hostname(), self.ctx_script(), ] } } impl Pickle for MtaStageConnect { fn pickle(&self, out: &mut Vec) { self.smtp_greeting.pickle(out); self.hostname.pickle(out); self.script.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.smtp_greeting = Pickle::unpickle(stream)?; this.hostname = Pickle::unpickle(stream)?; this.script = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaStageConnect { fn default() -> Self { Self { smtp_greeting: Expression { else_: "system('hostname') + ' INBUXA ESMTP at your service'".to_string(), ..Default::default() }, hostname: Expression { else_: "system('hostname')".to_string(), ..Default::default() }, script: Expression { else_: "false".to_string(), ..Default::default() }, } } } impl IntoValue for MtaStageConnect { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::SmtpGreeting, self.smtp_greeting.into_value()); map.insert_unchecked(Property::Hostname, self.hostname.into_value()); map.insert_unchecked(Property::Script, self.script.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaStageConnect { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::SmtpGreeting) => self.smtp_greeting.patch(pointer, value), Some(Property::Hostname) => self.hostname.patch(pointer, value), Some(Property::Script) => self.script.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaStageData { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaStageData; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.add_auth_results_header; value.validate(errors); let value = &self.add_date_header; value.validate(errors); let value = &self.add_message_id_header; value.validate(errors); let value = &self.add_received_header; value.validate(errors); let value = &self.add_received_spf_header; value.validate(errors); let value = &self.add_return_path_header; value.validate(errors); let value = &self.max_messages; value.validate(errors); let value = &self.max_received_headers; value.validate(errors); let value = &self.max_message_size; value.validate(errors); let value = &self.script; value.validate(errors); let value = &self.enable_spam_filter; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl MtaStageData { pub fn ctx_add_auth_results_header(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.add_auth_results_header, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "true".to_string(), }]), }), property: Property::AddAuthResultsHeader, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_add_date_header(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.add_date_header, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "true".to_string(), }]), }), property: Property::AddDateHeader, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_add_message_id_header(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.add_message_id_header, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "true".to_string(), }]), }), property: Property::AddMessageIdHeader, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_add_received_header(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.add_received_header, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "true".to_string(), }]), }), property: Property::AddReceivedHeader, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_add_received_spf_header(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.add_received_spf_header, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "true".to_string(), }]), }), property: Property::AddReceivedSpfHeader, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_add_return_path_header(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.add_return_path_header, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "true".to_string(), }]), }), property: Property::AddReturnPathHeader, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_max_messages(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.max_messages, default: Some(Expression { else_: "10".to_string(), ..Default::default() }), property: Property::MaxMessages, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_max_received_headers(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.max_received_headers, default: Some(Expression { else_: "50".to_string(), ..Default::default() }), property: Property::MaxReceivedHeaders, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_max_message_size(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.max_message_size, default: Some(Expression { else_: "104857600".to_string(), ..Default::default() }), property: Property::MaxMessageSize, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_script(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.script, default: Some(Expression { else_: "false".to_string(), ..Default::default() }), property: Property::Script, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_enable_spam_filter(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.enable_spam_filter, default: Some(Expression { else_: "is_empty(authenticated_as)".to_string(), ..Default::default() }), property: Property::EnableSpamFilter, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_add_auth_results_header(), self.ctx_add_date_header(), self.ctx_add_message_id_header(), self.ctx_add_received_header(), self.ctx_add_received_spf_header(), self.ctx_add_return_path_header(), self.ctx_max_messages(), self.ctx_max_received_headers(), self.ctx_max_message_size(), self.ctx_script(), self.ctx_enable_spam_filter(), ] } } impl Pickle for MtaStageData { fn pickle(&self, out: &mut Vec) { self.add_auth_results_header.pickle(out); self.add_date_header.pickle(out); self.add_delivered_to_header.pickle(out); self.add_message_id_header.pickle(out); self.add_received_header.pickle(out); self.add_received_spf_header.pickle(out); self.add_return_path_header.pickle(out); self.max_messages.pickle(out); self.max_received_headers.pickle(out); self.max_message_size.pickle(out); self.script.pickle(out); self.enable_spam_filter.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.add_auth_results_header = Pickle::unpickle(stream)?; this.add_date_header = Pickle::unpickle(stream)?; this.add_delivered_to_header = Pickle::unpickle(stream)?; this.add_message_id_header = Pickle::unpickle(stream)?; this.add_received_header = Pickle::unpickle(stream)?; this.add_received_spf_header = Pickle::unpickle(stream)?; this.add_return_path_header = Pickle::unpickle(stream)?; this.max_messages = Pickle::unpickle(stream)?; this.max_received_headers = Pickle::unpickle(stream)?; this.max_message_size = Pickle::unpickle(stream)?; this.script = Pickle::unpickle(stream)?; this.enable_spam_filter = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaStageData { fn default() -> Self { Self { add_auth_results_header: Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "true".to_string(), }]), }, add_date_header: Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "true".to_string(), }]), }, add_delivered_to_header: true, add_message_id_header: Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "true".to_string(), }]), }, add_received_header: Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "true".to_string(), }]), }, add_received_spf_header: Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "true".to_string(), }]), }, add_return_path_header: Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "true".to_string(), }]), }, max_messages: Expression { else_: "10".to_string(), ..Default::default() }, max_received_headers: Expression { else_: "50".to_string(), ..Default::default() }, max_message_size: Expression { else_: "104857600".to_string(), ..Default::default() }, script: Expression { else_: "false".to_string(), ..Default::default() }, enable_spam_filter: Expression { else_: "is_empty(authenticated_as)".to_string(), ..Default::default() }, } } } impl IntoValue for MtaStageData { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked( Property::AddAuthResultsHeader, self.add_auth_results_header.into_value(), ); map.insert_unchecked(Property::AddDateHeader, self.add_date_header.into_value()); map.insert_unchecked( Property::AddDeliveredToHeader, self.add_delivered_to_header.into_value(), ); map.insert_unchecked( Property::AddMessageIdHeader, self.add_message_id_header.into_value(), ); map.insert_unchecked( Property::AddReceivedHeader, self.add_received_header.into_value(), ); map.insert_unchecked( Property::AddReceivedSpfHeader, self.add_received_spf_header.into_value(), ); map.insert_unchecked( Property::AddReturnPathHeader, self.add_return_path_header.into_value(), ); map.insert_unchecked(Property::MaxMessages, self.max_messages.into_value()); map.insert_unchecked( Property::MaxReceivedHeaders, self.max_received_headers.into_value(), ); map.insert_unchecked(Property::MaxMessageSize, self.max_message_size.into_value()); map.insert_unchecked(Property::Script, self.script.into_value()); map.insert_unchecked( Property::EnableSpamFilter, self.enable_spam_filter.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaStageData { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AddAuthResultsHeader) => { self.add_auth_results_header.patch(pointer, value) } Some(Property::AddDateHeader) => self.add_date_header.patch(pointer, value), Some(Property::AddDeliveredToHeader) => { self.add_delivered_to_header.patch(pointer, value) } Some(Property::AddMessageIdHeader) => self.add_message_id_header.patch(pointer, value), Some(Property::AddReceivedHeader) => self.add_received_header.patch(pointer, value), Some(Property::AddReceivedSpfHeader) => { self.add_received_spf_header.patch(pointer, value) } Some(Property::AddReturnPathHeader) => { self.add_return_path_header.patch(pointer, value) } Some(Property::MaxMessages) => self.max_messages.patch(pointer, value), Some(Property::MaxReceivedHeaders) => self.max_received_headers.patch(pointer, value), Some(Property::MaxMessageSize) => self.max_message_size.patch(pointer, value), Some(Property::Script) => self.script.patch(pointer, value), Some(Property::EnableSpamFilter) => self.enable_spam_filter.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaStageEhlo { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaStageEhlo; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.reject_non_fqdn; value.validate(errors); let value = &self.require; value.validate(errors); let value = &self.script; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl MtaStageEhlo { pub fn ctx_reject_non_fqdn(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.reject_non_fqdn, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "true".to_string(), }]), }), property: Property::RejectNonFqdn, allowed_variables: MTA_CONNECTION_VARIABLE, allowed_constants: &[], } } pub fn ctx_require(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.require, default: Some(Expression { else_: "true".to_string(), ..Default::default() }), property: Property::Require, allowed_variables: MTA_CONNECTION_VARIABLE, allowed_constants: &[], } } pub fn ctx_script(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.script, default: Some(Expression { else_: "false".to_string(), ..Default::default() }), property: Property::Script, allowed_variables: MTA_CONNECTION_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_reject_non_fqdn(), self.ctx_require(), self.ctx_script(), ] } } impl Pickle for MtaStageEhlo { fn pickle(&self, out: &mut Vec) { self.reject_non_fqdn.pickle(out); self.require.pickle(out); self.script.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.reject_non_fqdn = Pickle::unpickle(stream)?; this.require = Pickle::unpickle(stream)?; this.script = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaStageEhlo { fn default() -> Self { Self { reject_non_fqdn: Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "true".to_string(), }]), }, require: Expression { else_: "true".to_string(), ..Default::default() }, script: Expression { else_: "false".to_string(), ..Default::default() }, } } } impl IntoValue for MtaStageEhlo { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::RejectNonFqdn, self.reject_non_fqdn.into_value()); map.insert_unchecked(Property::Require, self.require.into_value()); map.insert_unchecked(Property::Script, self.script.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaStageEhlo { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::RejectNonFqdn) => self.reject_non_fqdn.patch(pointer, value), Some(Property::Require) => self.require.patch(pointer, value), Some(Property::Script) => self.script.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaStageMail { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaStageMail; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.is_sender_allowed; value.validate(errors); let value = &self.rewrite; value.validate(errors); let value = &self.script; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl MtaStageMail { pub fn ctx_is_sender_allowed(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.is_sender_allowed, default: Some(Expression { else_: "!is_empty(authenticated_as) || !key_exists('spam-block', sender_domain)" .to_string(), match_: List::from_iter([]), }), property: Property::IsSenderAllowed, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_rewrite(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.rewrite, default: Some(Expression { else_: "false".to_string(), ..Default::default() }), property: Property::Rewrite, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_script(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.script, default: Some(Expression { else_: "false".to_string(), ..Default::default() }), property: Property::Script, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_is_sender_allowed(), self.ctx_rewrite(), self.ctx_script(), ] } } impl Pickle for MtaStageMail { fn pickle(&self, out: &mut Vec) { self.is_sender_allowed.pickle(out); self.rewrite.pickle(out); self.script.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.is_sender_allowed = Pickle::unpickle(stream)?; this.rewrite = Pickle::unpickle(stream)?; this.script = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaStageMail { fn default() -> Self { Self { is_sender_allowed: Expression { else_: "!is_empty(authenticated_as) || !key_exists('spam-block', sender_domain)" .to_string(), match_: List::from_iter([]), }, rewrite: Expression { else_: "false".to_string(), ..Default::default() }, script: Expression { else_: "false".to_string(), ..Default::default() }, } } } impl IntoValue for MtaStageMail { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked( Property::IsSenderAllowed, self.is_sender_allowed.into_value(), ); map.insert_unchecked(Property::Rewrite, self.rewrite.into_value()); map.insert_unchecked(Property::Script, self.script.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaStageMail { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::IsSenderAllowed) => self.is_sender_allowed.patch(pointer, value), Some(Property::Rewrite) => self.rewrite.patch(pointer, value), Some(Property::Script) => self.script.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaStageRcpt { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaStageRcpt; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.max_failures; value.validate(errors); let value = &self.wait_on_fail; value.validate(errors); let value = &self.max_recipients; value.validate(errors); let value = &self.allow_relaying; value.validate(errors); let value = &self.rewrite; value.validate(errors); let value = &self.script; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl MtaStageRcpt { pub fn ctx_max_failures(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.max_failures, default: Some(Expression { else_: "5".to_string(), ..Default::default() }), property: Property::MaxFailures, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_wait_on_fail(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.wait_on_fail, default: Some(Expression { else_: "5s".to_string(), ..Default::default() }), property: Property::WaitOnFail, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_max_recipients(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.max_recipients, default: Some(Expression { else_: "100".to_string(), ..Default::default() }), property: Property::MaxRecipients, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_allow_relaying(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.allow_relaying, default: Some(Expression { else_: "!is_empty(authenticated_as)".to_string(), ..Default::default() }), property: Property::AllowRelaying, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_rewrite(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.rewrite, default: Some(Expression { else_: "false".to_string(), ..Default::default() }), property: Property::Rewrite, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_script(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.script, default: Some(Expression { else_: "false".to_string(), ..Default::default() }), property: Property::Script, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_max_failures(), self.ctx_wait_on_fail(), self.ctx_max_recipients(), self.ctx_allow_relaying(), self.ctx_rewrite(), self.ctx_script(), ] } } impl Pickle for MtaStageRcpt { fn pickle(&self, out: &mut Vec) { self.max_failures.pickle(out); self.wait_on_fail.pickle(out); self.max_recipients.pickle(out); self.allow_relaying.pickle(out); self.rewrite.pickle(out); self.script.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.max_failures = Pickle::unpickle(stream)?; this.wait_on_fail = Pickle::unpickle(stream)?; this.max_recipients = Pickle::unpickle(stream)?; this.allow_relaying = Pickle::unpickle(stream)?; this.rewrite = Pickle::unpickle(stream)?; this.script = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaStageRcpt { fn default() -> Self { Self { max_failures: Expression { else_: "5".to_string(), ..Default::default() }, wait_on_fail: Expression { else_: "5s".to_string(), ..Default::default() }, max_recipients: Expression { else_: "100".to_string(), ..Default::default() }, allow_relaying: Expression { else_: "!is_empty(authenticated_as)".to_string(), ..Default::default() }, rewrite: Expression { else_: "false".to_string(), ..Default::default() }, script: Expression { else_: "false".to_string(), ..Default::default() }, } } } impl IntoValue for MtaStageRcpt { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::MaxFailures, self.max_failures.into_value()); map.insert_unchecked(Property::WaitOnFail, self.wait_on_fail.into_value()); map.insert_unchecked(Property::MaxRecipients, self.max_recipients.into_value()); map.insert_unchecked(Property::AllowRelaying, self.allow_relaying.into_value()); map.insert_unchecked(Property::Rewrite, self.rewrite.into_value()); map.insert_unchecked(Property::Script, self.script.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaStageRcpt { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::MaxFailures) => self.max_failures.patch(pointer, value), Some(Property::WaitOnFail) => self.wait_on_fail.patch(pointer, value), Some(Property::MaxRecipients) => self.max_recipients.patch(pointer, value), Some(Property::AllowRelaying) => self.allow_relaying.patch(pointer, value), Some(Property::Rewrite) => self.rewrite.patch(pointer, value), Some(Property::Script) => self.script.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaSts { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaSts; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.mx_hosts; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::MxHosts)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for MtaSts { fn pickle(&self, out: &mut Vec) { self.max_age.pickle(out); self.mode.pickle(out); self.mx_hosts.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.max_age = Pickle::unpickle(stream)?; this.mode = Pickle::unpickle(stream)?; this.mx_hosts = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaSts { fn default() -> Self { Self { max_age: Duration::from_millis(604800000), mode: PolicyEnforcement::Testing, mx_hosts: Default::default(), } } } impl IntoValue for MtaSts { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::MaxAge, self.max_age.into_value()); map.insert_unchecked(Property::Mode, self.mode.into_value()); map.insert_unchecked(Property::MxHosts, self.mx_hosts.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaSts { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::MaxAge) => self.max_age.patch(pointer, value), Some(Property::Mode) => self.mode.patch(pointer, value), Some(Property::MxHosts) => self .mx_hosts .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaTlsStrategy { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaTlsStrategy; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl Pickle for MtaTlsStrategy { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.allow_invalid_certs.pickle(out); self.dane.pickle(out); self.description.pickle(out); self.mta_sts.pickle(out); self.start_tls.pickle(out); self.mta_sts_timeout.pickle(out); self.tls_timeout.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.allow_invalid_certs = Pickle::unpickle(stream)?; this.dane = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.mta_sts = Pickle::unpickle(stream)?; this.start_tls = Pickle::unpickle(stream)?; this.mta_sts_timeout = Pickle::unpickle(stream)?; this.tls_timeout = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaTlsStrategy { fn default() -> Self { Self { name: Default::default(), allow_invalid_certs: false, dane: MtaRequiredOrOptional::Optional, description: Default::default(), mta_sts: MtaRequiredOrOptional::Optional, start_tls: MtaRequiredOrOptional::Optional, mta_sts_timeout: Duration::from_millis(300000), tls_timeout: Duration::from_millis(180000), } } } impl IntoValue for MtaTlsStrategy { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(10); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked( Property::AllowInvalidCerts, self.allow_invalid_certs.into_value(), ); map.insert_unchecked(Property::Dane, self.dane.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MtaSts, self.mta_sts.into_value()); map.insert_unchecked(Property::StartTls, self.start_tls.into_value()); map.insert_unchecked(Property::MtaStsTimeout, self.mta_sts_timeout.into_value()); map.insert_unchecked(Property::TlsTimeout, self.tls_timeout.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaTlsStrategy { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self.name.patch(pointer.assert_read_only()?, value), Some(Property::AllowInvalidCerts) => self.allow_invalid_certs.patch(pointer, value), Some(Property::Dane) => self.dane.patch(pointer, value), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::MtaSts) => self.mta_sts.patch(pointer, value), Some(Property::StartTls) => self.start_tls.patch(pointer, value), Some(Property::MtaStsTimeout) => self.mta_sts_timeout.patch(pointer, value), Some(Property::TlsTimeout) => self.tls_timeout.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for MtaVirtualQueue { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::MtaVirtualQueue; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if value.len() > 8 { errors.push(ValidationError::max_length(Property::Name, 8)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.threads_per_node; if *value < 1 { errors.push(ValidationError::min_value(Property::ThreadsPerNode, 1)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl Pickle for MtaVirtualQueue { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.description.pickle(out); self.threads_per_node.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.threads_per_node = Pickle::unpickle(stream)?; Some(this) } } impl Default for MtaVirtualQueue { fn default() -> Self { Self { name: Default::default(), description: Default::default(), threads_per_node: 25u64, } } } impl IntoValue for MtaVirtualQueue { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::ThreadsPerNode, self.threads_per_node.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MtaVirtualQueue { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self.name.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::Trim]), value, ), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::ThreadsPerNode) => self.threads_per_node.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl MySqlSettings { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.host; if value.is_empty() { errors.push(ValidationError::required(Property::Host)); } let value = &self.port; if *value > 65535 { errors.push(ValidationError::max_value(Property::Port, 65535)); } if *value < 1 { errors.push(ValidationError::min_value(Property::Port, 1)); } let value = &self.database; if value.is_empty() { errors.push(ValidationError::required(Property::Database)); } if let Some(value) = &self.auth_username { if value.is_empty() { errors.push(ValidationError::required(Property::AuthUsername)); } } let value = &self.auth_secret; value.validate(errors); errors.len() == neb } } impl Pickle for MySqlSettings { fn pickle(&self, out: &mut Vec) { self.host.pickle(out); self.port.pickle(out); self.database.pickle(out); self.auth_username.pickle(out); self.auth_secret.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.host = Pickle::unpickle(stream)?; this.port = Pickle::unpickle(stream)?; this.database = Pickle::unpickle(stream)?; this.auth_username = Pickle::unpickle(stream)?; this.auth_secret = Pickle::unpickle(stream)?; Some(this) } } impl Default for MySqlSettings { fn default() -> Self { Self { host: Default::default(), port: 3306u64, database: "stalwart".to_string(), auth_username: Some("stalwart".to_string()), auth_secret: Default::default(), } } } impl IntoValue for MySqlSettings { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Host, self.host.into_value()); map.insert_unchecked(Property::Port, self.port.into_value()); map.insert_unchecked(Property::Database, self.database.into_value()); map.insert_unchecked(Property::AuthUsername, self.auth_username.into_value()); map.insert_unchecked(Property::AuthSecret, self.auth_secret.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MySqlSettings { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Host) => self .host .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Port) => self.port.patch(pointer, value), Some(Property::Database) => self .database .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AuthUsername) => self .auth_username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AuthSecret) => self.auth_secret.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl MySqlStore { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.max_allowed_packet { if *value > 1073741824 { errors.push(ValidationError::max_value( Property::MaxAllowedPacket, 1073741824, )); } if *value < 1024 { errors.push(ValidationError::min_value(Property::MaxAllowedPacket, 1024)); } } if let Some(value) = &self.pool_max_connections { if *value > 8192 { errors.push(ValidationError::max_value( Property::PoolMaxConnections, 8192, )); } if *value < 1 { errors.push(ValidationError::min_value(Property::PoolMaxConnections, 1)); } } if let Some(value) = &self.pool_min_connections { if *value > 8192 { errors.push(ValidationError::max_value( Property::PoolMinConnections, 8192, )); } if *value < 1 { errors.push(ValidationError::min_value(Property::PoolMinConnections, 1)); } } let value = &self.read_replicas; for value in value.values() { value.validate(errors); } let value = &self.host; if value.is_empty() { errors.push(ValidationError::required(Property::Host)); } let value = &self.port; if *value > 65535 { errors.push(ValidationError::max_value(Property::Port, 65535)); } if *value < 1 { errors.push(ValidationError::min_value(Property::Port, 1)); } let value = &self.database; if value.is_empty() { errors.push(ValidationError::required(Property::Database)); } if let Some(value) = &self.auth_username { if value.is_empty() { errors.push(ValidationError::required(Property::AuthUsername)); } } let value = &self.auth_secret; value.validate(errors); errors.len() == neb } } impl Pickle for MySqlStore { fn pickle(&self, out: &mut Vec) { self.timeout.pickle(out); self.use_tls.pickle(out); self.allow_invalid_certs.pickle(out); self.max_allowed_packet.pickle(out); self.pool_max_connections.pickle(out); self.pool_min_connections.pickle(out); self.read_replicas.pickle(out); self.host.pickle(out); self.port.pickle(out); self.database.pickle(out); self.auth_username.pickle(out); self.auth_secret.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.timeout = Pickle::unpickle(stream)?; this.use_tls = Pickle::unpickle(stream)?; this.allow_invalid_certs = Pickle::unpickle(stream)?; this.max_allowed_packet = Pickle::unpickle(stream)?; this.pool_max_connections = Pickle::unpickle(stream)?; this.pool_min_connections = Pickle::unpickle(stream)?; this.read_replicas = Pickle::unpickle(stream)?; this.host = Pickle::unpickle(stream)?; this.port = Pickle::unpickle(stream)?; this.database = Pickle::unpickle(stream)?; this.auth_username = Pickle::unpickle(stream)?; this.auth_secret = Pickle::unpickle(stream)?; Some(this) } } impl Default for MySqlStore { fn default() -> Self { Self { timeout: Some(Duration::from_millis(15000)), use_tls: false, allow_invalid_certs: false, max_allowed_packet: Default::default(), pool_max_connections: Some(10u64), pool_min_connections: Some(5u64), read_replicas: Default::default(), host: Default::default(), port: 3306u64, database: "stalwart".to_string(), auth_username: Some("stalwart".to_string()), auth_secret: Default::default(), } } } impl IntoValue for MySqlStore { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::UseTls, self.use_tls.into_value()); map.insert_unchecked( Property::AllowInvalidCerts, self.allow_invalid_certs.into_value(), ); map.insert_unchecked( Property::MaxAllowedPacket, self.max_allowed_packet.into_value(), ); map.insert_unchecked( Property::PoolMaxConnections, self.pool_max_connections.into_value(), ); map.insert_unchecked( Property::PoolMinConnections, self.pool_min_connections.into_value(), ); map.insert_unchecked(Property::ReadReplicas, self.read_replicas.into_value()); map.insert_unchecked(Property::Host, self.host.into_value()); map.insert_unchecked(Property::Port, self.port.into_value()); map.insert_unchecked(Property::Database, self.database.into_value()); map.insert_unchecked(Property::AuthUsername, self.auth_username.into_value()); map.insert_unchecked(Property::AuthSecret, self.auth_secret.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for MySqlStore { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::UseTls) => self.use_tls.patch(pointer, value), Some(Property::AllowInvalidCerts) => self.allow_invalid_certs.patch(pointer, value), Some(Property::MaxAllowedPacket) => self.max_allowed_packet.patch(pointer, value), Some(Property::PoolMaxConnections) => self.pool_max_connections.patch(pointer, value), Some(Property::PoolMinConnections) => self.pool_min_connections.patch(pointer, value), Some(Property::ReadReplicas) => self.read_replicas.patch(pointer, value), Some(Property::Host) => self .host .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Port) => self.port.patch(pointer, value), Some(Property::Database) => self .database .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AuthUsername) => self .auth_username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AuthSecret) => self.auth_secret.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl NatsCoordinator { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.addresses; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::Addresses)); } } if value.len() < 1 { errors.push(ValidationError::min_items(Property::Addresses, 1)); } let value = &self.capacity_client; if *value < 1 { errors.push(ValidationError::min_value(Property::CapacityClient, 1)); } let value = &self.capacity_read_buffer; if *value < 1 { errors.push(ValidationError::min_value(Property::CapacityReadBuffer, 1)); } let value = &self.capacity_subscription; if *value < 1 { errors.push(ValidationError::min_value( Property::CapacitySubscription, 1, )); } let value = &self.auth_secret; value.validate(errors); if let Some(value) = &self.auth_username { if value.is_empty() { errors.push(ValidationError::required(Property::AuthUsername)); } } let value = &self.credentials; value.validate(errors); errors.len() == neb } } impl Pickle for NatsCoordinator { fn pickle(&self, out: &mut Vec) { self.addresses.pickle(out); self.max_reconnects.pickle(out); self.timeout_connection.pickle(out); self.timeout_request.pickle(out); self.ping_interval.pickle(out); self.capacity_client.pickle(out); self.capacity_read_buffer.pickle(out); self.capacity_subscription.pickle(out); self.no_echo.pickle(out); self.use_tls.pickle(out); self.auth_secret.pickle(out); self.auth_username.pickle(out); self.credentials.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.addresses = Pickle::unpickle(stream)?; this.max_reconnects = Pickle::unpickle(stream)?; this.timeout_connection = Pickle::unpickle(stream)?; this.timeout_request = Pickle::unpickle(stream)?; this.ping_interval = Pickle::unpickle(stream)?; this.capacity_client = Pickle::unpickle(stream)?; this.capacity_read_buffer = Pickle::unpickle(stream)?; this.capacity_subscription = Pickle::unpickle(stream)?; this.no_echo = Pickle::unpickle(stream)?; this.use_tls = Pickle::unpickle(stream)?; this.auth_secret = Pickle::unpickle(stream)?; this.auth_username = Pickle::unpickle(stream)?; this.credentials = Pickle::unpickle(stream)?; Some(this) } } impl Default for NatsCoordinator { fn default() -> Self { Self { addresses: Map::new(vec!["127.0.0.1:4444".to_string()]), max_reconnects: Default::default(), timeout_connection: Duration::from_millis(5000), timeout_request: Duration::from_millis(10000), ping_interval: Duration::from_millis(60000), capacity_client: 2048u64, capacity_read_buffer: 65535u64, capacity_subscription: 65536u64, no_echo: true, use_tls: false, auth_secret: Default::default(), auth_username: Some("stalwart".to_string()), credentials: Default::default(), } } } impl IntoValue for NatsCoordinator { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(15); map.insert_unchecked(Property::Addresses, self.addresses.into_value()); map.insert_unchecked(Property::MaxReconnects, self.max_reconnects.into_value()); map.insert_unchecked( Property::TimeoutConnection, self.timeout_connection.into_value(), ); map.insert_unchecked(Property::TimeoutRequest, self.timeout_request.into_value()); map.insert_unchecked(Property::PingInterval, self.ping_interval.into_value()); map.insert_unchecked(Property::CapacityClient, self.capacity_client.into_value()); map.insert_unchecked( Property::CapacityReadBuffer, self.capacity_read_buffer.into_value(), ); map.insert_unchecked( Property::CapacitySubscription, self.capacity_subscription.into_value(), ); map.insert_unchecked(Property::NoEcho, self.no_echo.into_value()); map.insert_unchecked(Property::UseTls, self.use_tls.into_value()); map.insert_unchecked(Property::AuthSecret, self.auth_secret.into_value()); map.insert_unchecked(Property::AuthUsername, self.auth_username.into_value()); map.insert_unchecked(Property::Credentials, self.credentials.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for NatsCoordinator { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Addresses) => self.addresses.patch(pointer, value), Some(Property::MaxReconnects) => self.max_reconnects.patch(pointer, value), Some(Property::TimeoutConnection) => self.timeout_connection.patch(pointer, value), Some(Property::TimeoutRequest) => self.timeout_request.patch(pointer, value), Some(Property::PingInterval) => self.ping_interval.patch(pointer, value), Some(Property::CapacityClient) => self.capacity_client.patch(pointer, value), Some(Property::CapacityReadBuffer) => self.capacity_read_buffer.patch(pointer, value), Some(Property::CapacitySubscription) => { self.capacity_subscription.patch(pointer, value) } Some(Property::NoEcho) => self.no_echo.patch(pointer, value), Some(Property::UseTls) => self.use_tls.patch(pointer, value), Some(Property::AuthSecret) => self.auth_secret.patch(pointer, value), Some(Property::AuthUsername) => self .auth_username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Credentials) => self.credentials.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for NetworkListener { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::NetworkListener; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } let value = &self.bind; for value in value.iter() { if !value.is_valid() { errors.push(ValidationError::invalid(Property::Bind, value)); } } if value.len() < 1 { errors.push(ValidationError::min_items(Property::Bind, 1)); } let value = &self.override_proxy_trusted_networks; for value in value.iter() { if !value.is_valid() { errors.push(ValidationError::invalid( Property::OverrideProxyTrustedNetworks, value, )); } } if let Some(value) = &self.socket_backlog { if *value < 1 { errors.push(ValidationError::min_value(Property::SocketBacklog, 1)); } } if let Some(value) = &self.socket_receive_buffer_size { if *value < 1 { errors.push(ValidationError::min_value( Property::SocketReceiveBufferSize, 1, )); } } if let Some(value) = &self.socket_send_buffer_size { if *value < 1 { errors.push(ValidationError::min_value( Property::SocketSendBufferSize, 1, )); } } if let Some(value) = &self.socket_tos_v4 { if *value < 1 { errors.push(ValidationError::min_value(Property::SocketTosV4, 1)); } } if let Some(value) = &self.socket_ttl { if *value < 1 { errors.push(ValidationError::min_value(Property::SocketTtl, 1)); } } if let Some(value) = &self.max_connections { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxConnections, 1)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl Pickle for NetworkListener { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.bind.pickle(out); self.protocol.pickle(out); self.override_proxy_trusted_networks.pickle(out); self.socket_backlog.pickle(out); self.socket_no_delay.pickle(out); self.socket_receive_buffer_size.pickle(out); self.socket_reuse_address.pickle(out); self.socket_reuse_port.pickle(out); self.socket_send_buffer_size.pickle(out); self.socket_tos_v4.pickle(out); self.socket_ttl.pickle(out); self.use_tls.pickle(out); self.tls_disable_cipher_suites.pickle(out); self.tls_disable_protocols.pickle(out); self.tls_ignore_client_order.pickle(out); self.tls_implicit.pickle(out); self.tls_timeout.pickle(out); self.max_connections.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.bind = Pickle::unpickle(stream)?; this.protocol = Pickle::unpickle(stream)?; this.override_proxy_trusted_networks = Pickle::unpickle(stream)?; this.socket_backlog = Pickle::unpickle(stream)?; this.socket_no_delay = Pickle::unpickle(stream)?; this.socket_receive_buffer_size = Pickle::unpickle(stream)?; this.socket_reuse_address = Pickle::unpickle(stream)?; this.socket_reuse_port = Pickle::unpickle(stream)?; this.socket_send_buffer_size = Pickle::unpickle(stream)?; this.socket_tos_v4 = Pickle::unpickle(stream)?; this.socket_ttl = Pickle::unpickle(stream)?; this.use_tls = Pickle::unpickle(stream)?; this.tls_disable_cipher_suites = Pickle::unpickle(stream)?; this.tls_disable_protocols = Pickle::unpickle(stream)?; this.tls_ignore_client_order = Pickle::unpickle(stream)?; this.tls_implicit = Pickle::unpickle(stream)?; this.tls_timeout = Pickle::unpickle(stream)?; this.max_connections = Pickle::unpickle(stream)?; Some(this) } } impl Default for NetworkListener { fn default() -> Self { Self { name: Default::default(), bind: Default::default(), protocol: NetworkListenerProtocol::Smtp, override_proxy_trusted_networks: Default::default(), socket_backlog: Some(1024u64), socket_no_delay: true, socket_receive_buffer_size: Default::default(), socket_reuse_address: true, socket_reuse_port: true, socket_send_buffer_size: Default::default(), socket_tos_v4: Default::default(), socket_ttl: Default::default(), use_tls: true, tls_disable_cipher_suites: Default::default(), tls_disable_protocols: Default::default(), tls_ignore_client_order: true, tls_implicit: false, tls_timeout: Some(Duration::from_millis(60000)), max_connections: Some(8192u64), } } } impl IntoValue for NetworkListener { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(21); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Bind, self.bind.into_value()); map.insert_unchecked(Property::Protocol, self.protocol.into_value()); map.insert_unchecked( Property::OverrideProxyTrustedNetworks, self.override_proxy_trusted_networks.into_value(), ); map.insert_unchecked(Property::SocketBacklog, self.socket_backlog.into_value()); map.insert_unchecked(Property::SocketNoDelay, self.socket_no_delay.into_value()); map.insert_unchecked( Property::SocketReceiveBufferSize, self.socket_receive_buffer_size.into_value(), ); map.insert_unchecked( Property::SocketReuseAddress, self.socket_reuse_address.into_value(), ); map.insert_unchecked( Property::SocketReusePort, self.socket_reuse_port.into_value(), ); map.insert_unchecked( Property::SocketSendBufferSize, self.socket_send_buffer_size.into_value(), ); map.insert_unchecked(Property::SocketTosV4, self.socket_tos_v4.into_value()); map.insert_unchecked(Property::SocketTtl, self.socket_ttl.into_value()); map.insert_unchecked(Property::UseTls, self.use_tls.into_value()); map.insert_unchecked( Property::TlsDisableCipherSuites, self.tls_disable_cipher_suites.into_value(), ); map.insert_unchecked( Property::TlsDisableProtocols, self.tls_disable_protocols.into_value(), ); map.insert_unchecked( Property::TlsIgnoreClientOrder, self.tls_ignore_client_order.into_value(), ); map.insert_unchecked(Property::TlsImplicit, self.tls_implicit.into_value()); map.insert_unchecked(Property::TlsTimeout, self.tls_timeout.into_value()); map.insert_unchecked(Property::MaxConnections, self.max_connections.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for NetworkListener { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self.name.patch(pointer.assert_read_only()?, value), Some(Property::Bind) => self .bind .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Protocol) => self.protocol.patch(pointer, value), Some(Property::OverrideProxyTrustedNetworks) => self .override_proxy_trusted_networks .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SocketBacklog) => self.socket_backlog.patch(pointer, value), Some(Property::SocketNoDelay) => self.socket_no_delay.patch(pointer, value), Some(Property::SocketReceiveBufferSize) => { self.socket_receive_buffer_size.patch(pointer, value) } Some(Property::SocketReuseAddress) => self.socket_reuse_address.patch(pointer, value), Some(Property::SocketReusePort) => self.socket_reuse_port.patch(pointer, value), Some(Property::SocketSendBufferSize) => { self.socket_send_buffer_size.patch(pointer, value) } Some(Property::SocketTosV4) => self.socket_tos_v4.patch(pointer, value), Some(Property::SocketTtl) => self.socket_ttl.patch(pointer, value), Some(Property::UseTls) => self.use_tls.patch(pointer, value), Some(Property::TlsDisableCipherSuites) => { self.tls_disable_cipher_suites.patch(pointer, value) } Some(Property::TlsDisableProtocols) => self.tls_disable_protocols.patch(pointer, value), Some(Property::TlsIgnoreClientOrder) => { self.tls_ignore_client_order.patch(pointer, value) } Some(Property::TlsImplicit) => self.tls_implicit.patch(pointer, value), Some(Property::TlsTimeout) => self.tls_timeout.patch(pointer, value), Some(Property::MaxConnections) => self.max_connections.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for OAuthClient { const FLAGS: u64 = OBJ_FILTER_TENANT | OBJ_SEQ_ID; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::OAuthClient; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.client_id; if value.is_empty() { errors.push(ValidationError::required(Property::ClientId)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.contacts; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::Contacts)); } } if let Some(value) = &self.secret { if value.is_empty() { errors.push(ValidationError::required(Property::Secret)); } } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } if let Some(value) = &self.expires_at { if !value.is_valid() { errors.push(ValidationError::invalid(Property::ExpiresAt, value)); } } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } let value = &self.redirect_uris; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::RedirectUris)); } } if let Some(value) = &self.logo { if value.is_empty() { errors.push(ValidationError::required(Property::Logo)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::ClientId, &self.client_id); if let Some(value) = &self.description { i.text(Property::Text, value); } for value in self.contacts.iter() { i.text(Property::Text, value); } i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for OAuthClient { fn pickle(&self, out: &mut Vec) { self.client_id.pickle(out); self.description.pickle(out); self.contacts.pickle(out); self.secret.pickle(out); self.created_at.pickle(out); self.expires_at.pickle(out); self.member_tenant_id.pickle(out); self.redirect_uris.pickle(out); self.logo.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.client_id = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.contacts = Pickle::unpickle(stream)?; this.secret = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.expires_at = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.redirect_uris = Pickle::unpickle(stream)?; this.logo = Pickle::unpickle(stream)?; Some(this) } } impl Default for OAuthClient { fn default() -> Self { Self { client_id: Default::default(), description: Default::default(), contacts: Default::default(), secret: Default::default(), created_at: Default::default(), expires_at: Default::default(), member_tenant_id: Default::default(), redirect_uris: Default::default(), logo: Default::default(), } } } impl IntoValue for OAuthClient { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::ClientId, self.client_id.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Contacts, self.contacts.into_value()); if self.secret.is_some() { map.insert_unchecked(Property::Secret, JmapValue::Str(MASKED_PASSWORD.into())); } map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::ExpiresAt, self.expires_at.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::RedirectUris, self.redirect_uris.into_value()); map.insert_unchecked(Property::Logo, self.logo.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for OAuthClient { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ClientId) => self .client_id .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Contacts) => self .contacts .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::Secret) => self.secret.patch(pointer, value), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::ExpiresAt) => self.expires_at.patch(pointer, value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::RedirectUris) => self.redirect_uris.patch(pointer, value), Some(Property::Logo) => self.logo.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl OidcDirectory { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } let value = &self.issuer_url; if value.is_empty() { errors.push(ValidationError::required(Property::IssuerUrl)); } if let Some(value) = &self.require_audience { if value.is_empty() { errors.push(ValidationError::required(Property::RequireAudience)); } } let value = &self.require_scopes; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::RequireScopes)); } } let value = &self.claim_username; if value.is_empty() { errors.push(ValidationError::required(Property::ClaimUsername)); } if let Some(value) = &self.username_domain { if value.is_empty() { errors.push(ValidationError::required(Property::UsernameDomain)); } } if let Some(value) = &self.claim_name { if value.is_empty() { errors.push(ValidationError::required(Property::ClaimName)); } } if let Some(value) = &self.claim_groups { if value.is_empty() { errors.push(ValidationError::required(Property::ClaimGroups)); } } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for OidcDirectory { fn pickle(&self, out: &mut Vec) { self.description.pickle(out); self.issuer_url.pickle(out); self.require_audience.pickle(out); self.require_scopes.pickle(out); self.claim_username.pickle(out); self.username_domain.pickle(out); self.claim_name.pickle(out); self.claim_groups.pickle(out); self.member_tenant_id.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.description = Pickle::unpickle(stream)?; this.issuer_url = Pickle::unpickle(stream)?; this.require_audience = Pickle::unpickle(stream)?; this.require_scopes = Pickle::unpickle(stream)?; this.claim_username = Pickle::unpickle(stream)?; this.username_domain = Pickle::unpickle(stream)?; this.claim_name = Pickle::unpickle(stream)?; this.claim_groups = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; Some(this) } } impl Default for OidcDirectory { fn default() -> Self { Self { description: Default::default(), issuer_url: Default::default(), require_audience: Default::default(), require_scopes: Map::new(vec!["openid".to_string(), "email".to_string()]), claim_username: "preferred_username".to_string(), username_domain: Default::default(), claim_name: Some("name".to_string()), claim_groups: Default::default(), member_tenant_id: Default::default(), } } } impl IntoValue for OidcDirectory { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::IssuerUrl, self.issuer_url.into_value()); map.insert_unchecked( Property::RequireAudience, self.require_audience.into_value(), ); map.insert_unchecked(Property::RequireScopes, self.require_scopes.into_value()); map.insert_unchecked(Property::ClaimUsername, self.claim_username.into_value()); map.insert_unchecked(Property::UsernameDomain, self.username_domain.into_value()); map.insert_unchecked(Property::ClaimName, self.claim_name.into_value()); map.insert_unchecked(Property::ClaimGroups, self.claim_groups.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for OidcDirectory { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::IssuerUrl) => self .issuer_url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::RequireAudience) => self .require_audience .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::RequireScopes) => self .require_scopes .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ClaimUsername) => self .claim_username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::UsernameDomain) => self.username_domain.patch(pointer, value), Some(Property::ClaimName) => self .claim_name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ClaimGroups) => self .claim_groups .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for OidcProvider { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::OidcProvider; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.auth_code_max_attempts; if *value < 1 { errors.push(ValidationError::min_value(Property::AuthCodeMaxAttempts, 1)); } if *value > 1000 { errors.push(ValidationError::max_value( Property::AuthCodeMaxAttempts, 1000, )); } let value = &self.encryption_key; value.validate(errors); let value = &self.signature_key; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for OidcProvider { fn pickle(&self, out: &mut Vec) { self.auth_code_max_attempts.pickle(out); self.anonymous_client_registration.pickle(out); self.require_client_registration.pickle(out); self.auth_code_expiry.pickle(out); self.refresh_token_expiry.pickle(out); self.refresh_token_renewal.pickle(out); self.access_token_expiry.pickle(out); self.user_code_expiry.pickle(out); self.id_token_expiry.pickle(out); self.encryption_key.pickle(out); self.signature_algorithm.pickle(out); self.signature_key.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.auth_code_max_attempts = Pickle::unpickle(stream)?; this.anonymous_client_registration = Pickle::unpickle(stream)?; this.require_client_registration = Pickle::unpickle(stream)?; this.auth_code_expiry = Pickle::unpickle(stream)?; this.refresh_token_expiry = Pickle::unpickle(stream)?; this.refresh_token_renewal = Pickle::unpickle(stream)?; this.access_token_expiry = Pickle::unpickle(stream)?; this.user_code_expiry = Pickle::unpickle(stream)?; this.id_token_expiry = Pickle::unpickle(stream)?; this.encryption_key = Pickle::unpickle(stream)?; this.signature_algorithm = Pickle::unpickle(stream)?; this.signature_key = Pickle::unpickle(stream)?; Some(this) } } impl Default for OidcProvider { fn default() -> Self { Self { auth_code_max_attempts: 3u64, anonymous_client_registration: true, require_client_registration: false, auth_code_expiry: Duration::from_millis(600000), refresh_token_expiry: Duration::from_millis(2592000000), refresh_token_renewal: Duration::from_millis(345600000), access_token_expiry: Duration::from_millis(3600000), user_code_expiry: Duration::from_millis(1800000), id_token_expiry: Duration::from_millis(900000), encryption_key: Default::default(), signature_algorithm: JwtSignatureAlgorithm::Hs256, signature_key: Default::default(), } } } impl IntoValue for OidcProvider { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked( Property::AuthCodeMaxAttempts, self.auth_code_max_attempts.into_value(), ); map.insert_unchecked( Property::AnonymousClientRegistration, self.anonymous_client_registration.into_value(), ); map.insert_unchecked( Property::RequireClientRegistration, self.require_client_registration.into_value(), ); map.insert_unchecked(Property::AuthCodeExpiry, self.auth_code_expiry.into_value()); map.insert_unchecked( Property::RefreshTokenExpiry, self.refresh_token_expiry.into_value(), ); map.insert_unchecked( Property::RefreshTokenRenewal, self.refresh_token_renewal.into_value(), ); map.insert_unchecked( Property::AccessTokenExpiry, self.access_token_expiry.into_value(), ); map.insert_unchecked(Property::UserCodeExpiry, self.user_code_expiry.into_value()); map.insert_unchecked(Property::IdTokenExpiry, self.id_token_expiry.into_value()); map.insert_unchecked(Property::EncryptionKey, self.encryption_key.into_value()); map.insert_unchecked( Property::SignatureAlgorithm, self.signature_algorithm.into_value(), ); map.insert_unchecked(Property::SignatureKey, self.signature_key.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for OidcProvider { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AuthCodeMaxAttempts) => { self.auth_code_max_attempts.patch(pointer, value) } Some(Property::AnonymousClientRegistration) => { self.anonymous_client_registration.patch(pointer, value) } Some(Property::RequireClientRegistration) => { self.require_client_registration.patch(pointer, value) } Some(Property::AuthCodeExpiry) => self.auth_code_expiry.patch(pointer, value), Some(Property::RefreshTokenExpiry) => self.refresh_token_expiry.patch(pointer, value), Some(Property::RefreshTokenRenewal) => self.refresh_token_renewal.patch(pointer, value), Some(Property::AccessTokenExpiry) => self.access_token_expiry.patch(pointer, value), Some(Property::UserCodeExpiry) => self.user_code_expiry.patch(pointer, value), Some(Property::IdTokenExpiry) => self.id_token_expiry.patch(pointer, value), Some(Property::EncryptionKey) => self.encryption_key.patch(pointer, value), Some(Property::SignatureAlgorithm) => self.signature_algorithm.patch(pointer, value), Some(Property::SignatureKey) => self.signature_key.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl OtpAuth { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.otp_code { if value.is_empty() { errors.push(ValidationError::required(Property::OtpCode)); } } if let Some(value) = &self.otp_url { if value.is_empty() { errors.push(ValidationError::required(Property::OtpUrl)); } } errors.len() == neb } } impl Pickle for OtpAuth { fn pickle(&self, out: &mut Vec) { self.otp_code.pickle(out); self.otp_url.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.otp_code = Pickle::unpickle(stream)?; this.otp_url = Pickle::unpickle(stream)?; Some(this) } } impl Default for OtpAuth { fn default() -> Self { Self { otp_code: Default::default(), otp_url: Default::default(), } } } impl IntoValue for OtpAuth { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); if self.otp_code.is_some() { map.insert_unchecked(Property::OtpCode, JmapValue::Str(MASKED_PASSWORD.into())); } if self.otp_url.is_some() { map.insert_unchecked(Property::OtpUrl, JmapValue::Str(MASKED_PASSWORD.into())); } JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for OtpAuth { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::OtpCode) => self.otp_code.patch(pointer, value), Some(Property::OtpUrl) => self.otp_url.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl PasswordCredential { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.credential_id; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CredentialId, value)); } let value = &self.secret; if value.is_empty() { errors.push(ValidationError::required(Property::Secret)); } if let Some(value) = &self.otp_auth { if value.is_empty() { errors.push(ValidationError::required(Property::OtpAuth)); } } if let Some(value) = &self.expires_at { if !value.is_valid() { errors.push(ValidationError::invalid(Property::ExpiresAt, value)); } } let value = &self.allowed_ips; for value in value.iter() { if !value.is_valid() { errors.push(ValidationError::invalid(Property::AllowedIps, value)); } } errors.len() == neb } } impl Pickle for PasswordCredential { fn pickle(&self, out: &mut Vec) { self.credential_id.pickle(out); self.secret.pickle(out); self.otp_auth.pickle(out); self.expires_at.pickle(out); self.allowed_ips.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.credential_id = Pickle::unpickle(stream)?; this.secret = Pickle::unpickle(stream)?; this.otp_auth = Pickle::unpickle(stream)?; this.expires_at = Pickle::unpickle(stream)?; this.allowed_ips = Pickle::unpickle(stream)?; Some(this) } } impl Default for PasswordCredential { fn default() -> Self { Self { credential_id: Default::default(), secret: Default::default(), otp_auth: Default::default(), expires_at: Default::default(), allowed_ips: Default::default(), } } } impl IntoValue for PasswordCredential { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::CredentialId, self.credential_id.into_value()); map.insert_unchecked(Property::Secret, JmapValue::Str(MASKED_PASSWORD.into())); if self.otp_auth.is_some() { map.insert_unchecked(Property::OtpAuth, JmapValue::Str(MASKED_PASSWORD.into())); } map.insert_unchecked(Property::ExpiresAt, self.expires_at.into_value()); map.insert_unchecked(Property::AllowedIps, self.allowed_ips.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for PasswordCredential { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::CredentialId) => pointer.assert_server_set(), Some(Property::Secret) => self.secret.patch(pointer, value), Some(Property::OtpAuth) => self.otp_auth.patch(pointer, value), Some(Property::ExpiresAt) => self.expires_at.patch(pointer, value), Some(Property::AllowedIps) => self.allowed_ips.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl Permissions { fn validate(&self, errors: &mut Vec) -> bool { match self { Permissions::Inherit => true, Permissions::Merge(inner) => inner.validate(errors), Permissions::Replace(inner) => inner.validate(errors), } } } impl Default for Permissions { fn default() -> Self { Permissions::Inherit } } impl Pickle for Permissions { fn pickle(&self, out: &mut Vec) { match self { Permissions::Inherit => { 0u16.pickle(out); } Permissions::Merge(inner) => { 1u16.pickle(out); inner.pickle(out); } Permissions::Replace(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(Permissions::Inherit), 1 => Pickle::unpickle(stream).map(Permissions::Merge), 2 => Pickle::unpickle(stream).map(Permissions::Replace), _ => None, } } } impl IntoValue for Permissions { fn into_value(self) -> JmapValue<'static> { match self { Permissions::Inherit => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Inherit".into())); JmapValue::Object(obj) } Permissions::Merge(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Merge".into())); obj } Permissions::Replace(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Replace".into())); obj } } } } impl RegistryJsonPatch for Permissions { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { PermissionsType::Inherit => *self = Permissions::Inherit, PermissionsType::Merge => *self = Permissions::Merge(Default::default()), PermissionsType::Replace => *self = Permissions::Replace(Default::default()), } } match self { Permissions::Inherit => pointer.assert_eof(), Permissions::Merge(inner) => inner.patch(pointer, value), Permissions::Replace(inner) => inner.patch(pointer, value), } } } impl Permissions { pub fn object_type(&self) -> PermissionsType { match self { Permissions::Inherit => PermissionsType::Inherit, Permissions::Merge(_) => PermissionsType::Merge, Permissions::Replace(_) => PermissionsType::Replace, } } } impl PermissionsList { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for PermissionsList { fn pickle(&self, out: &mut Vec) { self.enabled_permissions.pickle(out); self.disabled_permissions.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.enabled_permissions = Pickle::unpickle(stream)?; this.disabled_permissions = Pickle::unpickle(stream)?; Some(this) } } impl Default for PermissionsList { fn default() -> Self { Self { enabled_permissions: Default::default(), disabled_permissions: Default::default(), } } } impl IntoValue for PermissionsList { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked( Property::EnabledPermissions, self.enabled_permissions.into_value(), ); map.insert_unchecked( Property::DisabledPermissions, self.disabled_permissions.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for PermissionsList { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::EnabledPermissions) => self.enabled_permissions.patch(pointer, value), Some(Property::DisabledPermissions) => self.disabled_permissions.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl PostgreSqlSettings { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.host; if value.is_empty() { errors.push(ValidationError::required(Property::Host)); } let value = &self.port; if *value > 65535 { errors.push(ValidationError::max_value(Property::Port, 65535)); } if *value < 1 { errors.push(ValidationError::min_value(Property::Port, 1)); } let value = &self.database; if value.is_empty() { errors.push(ValidationError::required(Property::Database)); } if let Some(value) = &self.auth_username { if value.is_empty() { errors.push(ValidationError::required(Property::AuthUsername)); } } let value = &self.auth_secret; value.validate(errors); if let Some(value) = &self.options { if value.is_empty() { errors.push(ValidationError::required(Property::Options)); } } errors.len() == neb } } impl Pickle for PostgreSqlSettings { fn pickle(&self, out: &mut Vec) { self.host.pickle(out); self.port.pickle(out); self.database.pickle(out); self.auth_username.pickle(out); self.auth_secret.pickle(out); self.options.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.host = Pickle::unpickle(stream)?; this.port = Pickle::unpickle(stream)?; this.database = Pickle::unpickle(stream)?; this.auth_username = Pickle::unpickle(stream)?; this.auth_secret = Pickle::unpickle(stream)?; this.options = Pickle::unpickle(stream)?; Some(this) } } impl Default for PostgreSqlSettings { fn default() -> Self { Self { host: Default::default(), port: 5432u64, database: "stalwart".to_string(), auth_username: Some("stalwart".to_string()), auth_secret: Default::default(), options: Default::default(), } } } impl IntoValue for PostgreSqlSettings { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::Host, self.host.into_value()); map.insert_unchecked(Property::Port, self.port.into_value()); map.insert_unchecked(Property::Database, self.database.into_value()); map.insert_unchecked(Property::AuthUsername, self.auth_username.into_value()); map.insert_unchecked(Property::AuthSecret, self.auth_secret.into_value()); map.insert_unchecked(Property::Options, self.options.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for PostgreSqlSettings { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Host) => self .host .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Port) => self.port.patch(pointer, value), Some(Property::Database) => self .database .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AuthUsername) => self .auth_username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AuthSecret) => self.auth_secret.patch(pointer, value), Some(Property::Options) => self .options .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl PostgreSqlStore { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.pool_max_connections { if *value > 8192 { errors.push(ValidationError::max_value( Property::PoolMaxConnections, 8192, )); } if *value < 1 { errors.push(ValidationError::min_value(Property::PoolMaxConnections, 1)); } } let value = &self.read_replicas; for value in value.values() { value.validate(errors); } let value = &self.host; if value.is_empty() { errors.push(ValidationError::required(Property::Host)); } let value = &self.port; if *value > 65535 { errors.push(ValidationError::max_value(Property::Port, 65535)); } if *value < 1 { errors.push(ValidationError::min_value(Property::Port, 1)); } let value = &self.database; if value.is_empty() { errors.push(ValidationError::required(Property::Database)); } if let Some(value) = &self.auth_username { if value.is_empty() { errors.push(ValidationError::required(Property::AuthUsername)); } } let value = &self.auth_secret; value.validate(errors); if let Some(value) = &self.options { if value.is_empty() { errors.push(ValidationError::required(Property::Options)); } } errors.len() == neb } } impl Pickle for PostgreSqlStore { fn pickle(&self, out: &mut Vec) { self.timeout.pickle(out); self.use_tls.pickle(out); self.allow_invalid_certs.pickle(out); self.pool_max_connections.pickle(out); self.pool_recycling_method.pickle(out); self.read_replicas.pickle(out); self.host.pickle(out); self.port.pickle(out); self.database.pickle(out); self.auth_username.pickle(out); self.auth_secret.pickle(out); self.options.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.timeout = Pickle::unpickle(stream)?; this.use_tls = Pickle::unpickle(stream)?; this.allow_invalid_certs = Pickle::unpickle(stream)?; this.pool_max_connections = Pickle::unpickle(stream)?; this.pool_recycling_method = Pickle::unpickle(stream)?; this.read_replicas = Pickle::unpickle(stream)?; this.host = Pickle::unpickle(stream)?; this.port = Pickle::unpickle(stream)?; this.database = Pickle::unpickle(stream)?; this.auth_username = Pickle::unpickle(stream)?; this.auth_secret = Pickle::unpickle(stream)?; this.options = Pickle::unpickle(stream)?; Some(this) } } impl Default for PostgreSqlStore { fn default() -> Self { Self { timeout: Some(Duration::from_millis(15000)), use_tls: false, allow_invalid_certs: false, pool_max_connections: Some(10u64), pool_recycling_method: PostgreSqlRecyclingMethod::Fast, read_replicas: Default::default(), host: Default::default(), port: 5432u64, database: "stalwart".to_string(), auth_username: Some("stalwart".to_string()), auth_secret: Default::default(), options: Default::default(), } } } impl IntoValue for PostgreSqlStore { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::UseTls, self.use_tls.into_value()); map.insert_unchecked( Property::AllowInvalidCerts, self.allow_invalid_certs.into_value(), ); map.insert_unchecked( Property::PoolMaxConnections, self.pool_max_connections.into_value(), ); map.insert_unchecked( Property::PoolRecyclingMethod, self.pool_recycling_method.into_value(), ); map.insert_unchecked(Property::ReadReplicas, self.read_replicas.into_value()); map.insert_unchecked(Property::Host, self.host.into_value()); map.insert_unchecked(Property::Port, self.port.into_value()); map.insert_unchecked(Property::Database, self.database.into_value()); map.insert_unchecked(Property::AuthUsername, self.auth_username.into_value()); map.insert_unchecked(Property::AuthSecret, self.auth_secret.into_value()); map.insert_unchecked(Property::Options, self.options.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for PostgreSqlStore { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::UseTls) => self.use_tls.patch(pointer, value), Some(Property::AllowInvalidCerts) => self.allow_invalid_certs.patch(pointer, value), Some(Property::PoolMaxConnections) => self.pool_max_connections.patch(pointer, value), Some(Property::PoolRecyclingMethod) => self.pool_recycling_method.patch(pointer, value), Some(Property::ReadReplicas) => self.read_replicas.patch(pointer, value), Some(Property::Host) => self .host .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Port) => self.port.patch(pointer, value), Some(Property::Database) => self .database .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AuthUsername) => self .auth_username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AuthSecret) => self.auth_secret.patch(pointer, value), Some(Property::Options) => self .options .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for PublicKey { const FLAGS: u64 = OBJ_FILTER_ACCOUNT; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::PublicKey; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.account_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } let value = &self.key; if value.is_empty() { errors.push(ValidationError::required(Property::Key)); } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } if let Some(value) = &self.expires_at { if !value.is_valid() { errors.push(ValidationError::invalid(Property::ExpiresAt, value)); } } let value = &self.email_addresses; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::EmailAddresses)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id.into(), None); i.search(Property::AccountId, &self.account_id); } } impl Pickle for PublicKey { fn pickle(&self, out: &mut Vec) { self.account_id.pickle(out); self.key.pickle(out); self.description.pickle(out); self.created_at.pickle(out); self.expires_at.pickle(out); self.email_addresses.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.account_id = Pickle::unpickle(stream)?; this.key = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.expires_at = Pickle::unpickle(stream)?; this.email_addresses = Pickle::unpickle(stream)?; Some(this) } } impl Default for PublicKey { fn default() -> Self { Self { account_id: Default::default(), key: Default::default(), description: Default::default(), created_at: Default::default(), expires_at: Default::default(), email_addresses: Default::default(), } } } impl IntoValue for PublicKey { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked(Property::Key, self.key.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::ExpiresAt, self.expires_at.into_value()); map.insert_unchecked(Property::EmailAddresses, self.email_addresses.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for PublicKey { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AccountId) => self .account_id .patch(pointer.assert_read_only()?.assert_can_set_account()?, value), Some(Property::Key) => self .key .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::ExpiresAt) => self.expires_at.patch(pointer, value), Some(Property::EmailAddresses) => self .email_addresses .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl PublicStringOptional { fn validate(&self, errors: &mut Vec) -> bool { match self { PublicStringOptional::None => true, PublicStringOptional::Value(inner) => inner.validate(errors), PublicStringOptional::EnvironmentVariable(inner) => inner.validate(errors), PublicStringOptional::File(inner) => inner.validate(errors), } } } impl Default for PublicStringOptional { fn default() -> Self { PublicStringOptional::None } } impl Pickle for PublicStringOptional { fn pickle(&self, out: &mut Vec) { match self { PublicStringOptional::None => { 0u16.pickle(out); } PublicStringOptional::Value(inner) => { 1u16.pickle(out); inner.pickle(out); } PublicStringOptional::EnvironmentVariable(inner) => { 2u16.pickle(out); inner.pickle(out); } PublicStringOptional::File(inner) => { 3u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(PublicStringOptional::None), 1 => Pickle::unpickle(stream).map(PublicStringOptional::Value), 2 => Pickle::unpickle(stream).map(PublicStringOptional::EnvironmentVariable), 3 => Pickle::unpickle(stream).map(PublicStringOptional::File), _ => None, } } } impl IntoValue for PublicStringOptional { fn into_value(self) -> JmapValue<'static> { match self { PublicStringOptional::None => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("None".into())); JmapValue::Object(obj) } PublicStringOptional::Value(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Value".into())); obj } PublicStringOptional::EnvironmentVariable(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("EnvironmentVariable".into())); obj } PublicStringOptional::File(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("File".into())); obj } } } } impl RegistryJsonPatch for PublicStringOptional { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { PublicStringOptionalType::None => *self = PublicStringOptional::None, PublicStringOptionalType::Value => { *self = PublicStringOptional::Value(Default::default()) } PublicStringOptionalType::EnvironmentVariable => { *self = PublicStringOptional::EnvironmentVariable(Default::default()) } PublicStringOptionalType::File => { *self = PublicStringOptional::File(Default::default()) } } } match self { PublicStringOptional::None => pointer.assert_eof(), PublicStringOptional::Value(inner) => inner.patch(pointer, value), PublicStringOptional::EnvironmentVariable(inner) => inner.patch(pointer, value), PublicStringOptional::File(inner) => inner.patch(pointer, value), } } } impl PublicStringOptional { pub fn object_type(&self) -> PublicStringOptionalType { match self { PublicStringOptional::None => PublicStringOptionalType::None, PublicStringOptional::Value(_) => PublicStringOptionalType::Value, PublicStringOptional::EnvironmentVariable(_) => { PublicStringOptionalType::EnvironmentVariable } PublicStringOptional::File(_) => PublicStringOptionalType::File, } } } impl PublicStringValue { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.value; if value.is_empty() { errors.push(ValidationError::required(Property::Value)); } errors.len() == neb } } impl Pickle for PublicStringValue { fn pickle(&self, out: &mut Vec) { self.value.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.value = Pickle::unpickle(stream)?; Some(this) } } impl Default for PublicStringValue { fn default() -> Self { Self { value: Default::default(), } } } impl IntoValue for PublicStringValue { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Value, self.value.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for PublicStringValue { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Value) => self .value .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl PublicText { fn validate(&self, errors: &mut Vec) -> bool { match self { PublicText::Text(inner) => inner.validate(errors), PublicText::EnvironmentVariable(inner) => inner.validate(errors), PublicText::File(inner) => inner.validate(errors), } } } impl Default for PublicText { fn default() -> Self { PublicText::Text(Default::default()) } } impl Pickle for PublicText { fn pickle(&self, out: &mut Vec) { match self { PublicText::Text(inner) => { 0u16.pickle(out); inner.pickle(out); } PublicText::EnvironmentVariable(inner) => { 1u16.pickle(out); inner.pickle(out); } PublicText::File(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(PublicText::Text), 1 => Pickle::unpickle(stream).map(PublicText::EnvironmentVariable), 2 => Pickle::unpickle(stream).map(PublicText::File), _ => None, } } } impl IntoValue for PublicText { fn into_value(self) -> JmapValue<'static> { match self { PublicText::Text(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Text".into())); obj } PublicText::EnvironmentVariable(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("EnvironmentVariable".into())); obj } PublicText::File(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("File".into())); obj } } } } impl RegistryJsonPatch for PublicText { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { PublicTextType::Text => *self = PublicText::Text(Default::default()), PublicTextType::EnvironmentVariable => { *self = PublicText::EnvironmentVariable(Default::default()) } PublicTextType::File => *self = PublicText::File(Default::default()), } } match self { PublicText::Text(inner) => inner.patch(pointer, value), PublicText::EnvironmentVariable(inner) => inner.patch(pointer, value), PublicText::File(inner) => inner.patch(pointer, value), } } } impl PublicText { pub fn object_type(&self) -> PublicTextType { match self { PublicText::Text(_) => PublicTextType::Text, PublicText::EnvironmentVariable(_) => PublicTextType::EnvironmentVariable, PublicText::File(_) => PublicTextType::File, } } } impl PublicTextValue { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.value; if value.is_empty() { errors.push(ValidationError::required(Property::Value)); } errors.len() == neb } } impl Pickle for PublicTextValue { fn pickle(&self, out: &mut Vec) { self.value.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.value = Pickle::unpickle(stream)?; Some(this) } } impl Default for PublicTextValue { fn default() -> Self { Self { value: Default::default(), } } } impl IntoValue for PublicTextValue { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Value, self.value.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for PublicTextValue { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Value) => self.value.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl QueueExpiry { fn validate(&self, errors: &mut Vec) -> bool { match self { QueueExpiry::Ttl(inner) => inner.validate(errors), QueueExpiry::Attempts(inner) => inner.validate(errors), } } } impl Default for QueueExpiry { fn default() -> Self { QueueExpiry::Ttl(Default::default()) } } impl Pickle for QueueExpiry { fn pickle(&self, out: &mut Vec) { match self { QueueExpiry::Ttl(inner) => { 0u16.pickle(out); inner.pickle(out); } QueueExpiry::Attempts(inner) => { 1u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(QueueExpiry::Ttl), 1 => Pickle::unpickle(stream).map(QueueExpiry::Attempts), _ => None, } } } impl IntoValue for QueueExpiry { fn into_value(self) -> JmapValue<'static> { match self { QueueExpiry::Ttl(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ttl".into())); obj } QueueExpiry::Attempts(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Attempts".into())); obj } } } } impl RegistryJsonPatch for QueueExpiry { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { QueueExpiryType::Ttl => *self = QueueExpiry::Ttl(Default::default()), QueueExpiryType::Attempts => *self = QueueExpiry::Attempts(Default::default()), } } match self { QueueExpiry::Ttl(inner) => inner.patch(pointer, value), QueueExpiry::Attempts(inner) => inner.patch(pointer, value), } } } impl QueueExpiry { pub fn object_type(&self) -> QueueExpiryType { match self { QueueExpiry::Ttl(_) => QueueExpiryType::Ttl, QueueExpiry::Attempts(_) => QueueExpiryType::Attempts, } } } impl QueueExpiryAttempts { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for QueueExpiryAttempts { fn pickle(&self, out: &mut Vec) { self.expires_attempts.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.expires_attempts = Pickle::unpickle(stream)?; Some(this) } } impl Default for QueueExpiryAttempts { fn default() -> Self { Self { expires_attempts: 0u64, } } } impl IntoValue for QueueExpiryAttempts { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked( Property::ExpiresAttempts, self.expires_attempts.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for QueueExpiryAttempts { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ExpiresAttempts) => self.expires_attempts.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl QueueExpiryTtl { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.expires_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ExpiresAt, value)); } errors.len() == neb } } impl Pickle for QueueExpiryTtl { fn pickle(&self, out: &mut Vec) { self.expires_at.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.expires_at = Pickle::unpickle(stream)?; Some(this) } } impl Default for QueueExpiryTtl { fn default() -> Self { Self { expires_at: Default::default(), } } } impl IntoValue for QueueExpiryTtl { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::ExpiresAt, self.expires_at.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for QueueExpiryTtl { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ExpiresAt) => self.expires_at.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for QueuedMessage { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::QueuedMessage; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } if let Some(value) = &self.next_retry { if !value.is_valid() { errors.push(ValidationError::invalid(Property::NextRetry, value)); } } if let Some(value) = &self.next_notify { if !value.is_valid() { errors.push(ValidationError::invalid(Property::NextNotify, value)); } } let value = &self.blob_id; if value.is_empty() { errors.push(ValidationError::required(Property::BlobId)); } let value = &self.return_path; if value.is_empty() { errors.push(ValidationError::required(Property::ReturnPath)); } let value = &self.recipients; for value in value.values() { value.validate(errors); } let value = &self.received_from_ip; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ReceivedFromIp, value)); } let value = &self.received_via_port; if *value < 1 { errors.push(ValidationError::min_value(Property::ReceivedViaPort, 1)); } if *value > 65535 { errors.push(ValidationError::max_value(Property::ReceivedViaPort, 65535)); } if let Some(value) = &self.env_id { if value.is_empty() { errors.push(ValidationError::required(Property::EnvId)); } } let value = &self.priority; if *value < (-100) { errors.push(ValidationError::min_value(Property::Priority, -100)); } if *value > (100) { errors.push(ValidationError::max_value(Property::Priority, 100)); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for QueuedMessage { fn pickle(&self, out: &mut Vec) { self.created_at.pickle(out); self.next_retry.pickle(out); self.next_notify.pickle(out); self.blob_id.pickle(out); self.return_path.pickle(out); self.recipients.pickle(out); self.received_from_ip.pickle(out); self.received_via_port.pickle(out); self.flags.pickle(out); self.env_id.pickle(out); self.priority.pickle(out); self.size.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.created_at = Pickle::unpickle(stream)?; this.next_retry = Pickle::unpickle(stream)?; this.next_notify = Pickle::unpickle(stream)?; this.blob_id = Pickle::unpickle(stream)?; this.return_path = Pickle::unpickle(stream)?; this.recipients = Pickle::unpickle(stream)?; this.received_from_ip = Pickle::unpickle(stream)?; this.received_via_port = Pickle::unpickle(stream)?; this.flags = Pickle::unpickle(stream)?; this.env_id = Pickle::unpickle(stream)?; this.priority = Pickle::unpickle(stream)?; this.size = Pickle::unpickle(stream)?; Some(this) } } impl Default for QueuedMessage { fn default() -> Self { Self { created_at: Default::default(), next_retry: Default::default(), next_notify: Default::default(), blob_id: Default::default(), return_path: Default::default(), recipients: Default::default(), received_from_ip: Default::default(), received_via_port: 25u64, flags: Default::default(), env_id: Default::default(), priority: 0i64, size: 0u64, } } } impl IntoValue for QueuedMessage { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::NextRetry, self.next_retry.into_value()); map.insert_unchecked(Property::NextNotify, self.next_notify.into_value()); map.insert_unchecked(Property::BlobId, self.blob_id.into_value()); map.insert_unchecked(Property::ReturnPath, self.return_path.into_value()); map.insert_unchecked(Property::Recipients, self.recipients.into_value()); map.insert_unchecked(Property::ReceivedFromIp, self.received_from_ip.into_value()); map.insert_unchecked( Property::ReceivedViaPort, self.received_via_port.into_value(), ); map.insert_unchecked(Property::Flags, self.flags.into_value()); map.insert_unchecked(Property::EnvId, self.env_id.into_value()); map.insert_unchecked(Property::Priority, self.priority.into_value()); map.insert_unchecked(Property::Size, self.size.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for QueuedMessage { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::NextRetry) => self.next_retry.patch(pointer, value), Some(Property::NextNotify) => pointer.assert_server_set(), Some(Property::BlobId) => pointer.assert_server_set(), Some(Property::ReturnPath) => pointer.assert_server_set(), Some(Property::Recipients) => self.recipients.patch(pointer, value), Some(Property::ReceivedFromIp) => pointer.assert_server_set(), Some(Property::ReceivedViaPort) => pointer.assert_server_set(), Some(Property::Flags) => pointer.assert_server_set(), Some(Property::EnvId) => self.env_id.patch(pointer, value), Some(Property::Priority) => self.priority.patch(pointer, value), Some(Property::Size) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl QueuedRecipient { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.retry_due; if !value.is_valid() { errors.push(ValidationError::invalid(Property::RetryDue, value)); } let value = &self.notify_due; if !value.is_valid() { errors.push(ValidationError::invalid(Property::NotifyDue, value)); } let value = &self.expires; value.validate(errors); let value = &self.queue_name; if value.is_empty() { errors.push(ValidationError::required(Property::QueueName)); } if value.len() > 8 { errors.push(ValidationError::max_length(Property::QueueName, 8)); } let value = &self.status; value.validate(errors); if let Some(value) = &self.orcpt { if value.is_empty() { errors.push(ValidationError::required(Property::Orcpt)); } } errors.len() == neb } } impl Pickle for QueuedRecipient { fn pickle(&self, out: &mut Vec) { self.retry_count.pickle(out); self.retry_due.pickle(out); self.notify_count.pickle(out); self.notify_due.pickle(out); self.expires.pickle(out); self.queue_name.pickle(out); self.status.pickle(out); self.flags.pickle(out); self.orcpt.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.retry_count = Pickle::unpickle(stream)?; this.retry_due = Pickle::unpickle(stream)?; this.notify_count = Pickle::unpickle(stream)?; this.notify_due = Pickle::unpickle(stream)?; this.expires = Pickle::unpickle(stream)?; this.queue_name = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; this.flags = Pickle::unpickle(stream)?; this.orcpt = Pickle::unpickle(stream)?; Some(this) } } impl Default for QueuedRecipient { fn default() -> Self { Self { retry_count: 0u64, retry_due: Default::default(), notify_count: 0u64, notify_due: Default::default(), expires: Default::default(), queue_name: Default::default(), status: Default::default(), flags: Default::default(), orcpt: Default::default(), } } } impl IntoValue for QueuedRecipient { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::RetryCount, self.retry_count.into_value()); map.insert_unchecked(Property::RetryDue, self.retry_due.into_value()); map.insert_unchecked(Property::NotifyCount, self.notify_count.into_value()); map.insert_unchecked(Property::NotifyDue, self.notify_due.into_value()); map.insert_unchecked(Property::Expires, self.expires.into_value()); map.insert_unchecked(Property::QueueName, self.queue_name.into_value()); map.insert_unchecked(Property::Status, self.status.into_value()); map.insert_unchecked(Property::Flags, self.flags.into_value()); map.insert_unchecked(Property::Orcpt, self.orcpt.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for QueuedRecipient { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::RetryCount) => self.retry_count.patch(pointer, value), Some(Property::RetryDue) => self.retry_due.patch(pointer, value), Some(Property::NotifyCount) => self.notify_count.patch(pointer, value), Some(Property::NotifyDue) => self.notify_due.patch(pointer, value), Some(Property::Expires) => self.expires.patch(pointer, value), Some(Property::QueueName) => pointer.assert_server_set(), Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Flags) => pointer.assert_server_set(), Some(Property::Orcpt) => self.orcpt.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl Rate { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.count; if *value < 1 { errors.push(ValidationError::min_value(Property::Count, 1)); } if *value > 1000000 { errors.push(ValidationError::max_value(Property::Count, 1000000)); } let value = &self.period; if !value.is_valid() { errors.push(ValidationError::invalid(Property::Period, value)); } if *value < Duration::from_millis(1) { errors.push(ValidationError::min_value(Property::Period, 1)); } errors.len() == neb } } impl Pickle for Rate { fn pickle(&self, out: &mut Vec) { self.count.pickle(out); self.period.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.count = Pickle::unpickle(stream)?; this.period = Pickle::unpickle(stream)?; Some(this) } } impl Default for Rate { fn default() -> Self { Self { count: 0u64, period: Duration::from_millis(0), } } } impl IntoValue for Rate { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Count, self.count.into_value()); map.insert_unchecked(Property::Period, self.period.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Rate { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Count) => self.count.patch(pointer, value), Some(Property::Period) => self.period.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl RecipientStatus { fn validate(&self, errors: &mut Vec) -> bool { match self { RecipientStatus::Scheduled => true, RecipientStatus::Completed(inner) => inner.validate(errors), RecipientStatus::TemporaryFailure(inner) => inner.validate(errors), RecipientStatus::PermanentFailure(inner) => inner.validate(errors), } } } impl Default for RecipientStatus { fn default() -> Self { RecipientStatus::Scheduled } } impl Pickle for RecipientStatus { fn pickle(&self, out: &mut Vec) { match self { RecipientStatus::Scheduled => { 0u16.pickle(out); } RecipientStatus::Completed(inner) => { 1u16.pickle(out); inner.pickle(out); } RecipientStatus::TemporaryFailure(inner) => { 2u16.pickle(out); inner.pickle(out); } RecipientStatus::PermanentFailure(inner) => { 3u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(RecipientStatus::Scheduled), 1 => Pickle::unpickle(stream).map(RecipientStatus::Completed), 2 => Pickle::unpickle(stream).map(RecipientStatus::TemporaryFailure), 3 => Pickle::unpickle(stream).map(RecipientStatus::PermanentFailure), _ => None, } } } impl IntoValue for RecipientStatus { fn into_value(self) -> JmapValue<'static> { match self { RecipientStatus::Scheduled => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Scheduled".into())); JmapValue::Object(obj) } RecipientStatus::Completed(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Completed".into())); obj } RecipientStatus::TemporaryFailure(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("TemporaryFailure".into())); obj } RecipientStatus::PermanentFailure(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("PermanentFailure".into())); obj } } } } impl RegistryJsonPatch for RecipientStatus { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { RecipientStatusType::Scheduled => *self = RecipientStatus::Scheduled, RecipientStatusType::Completed => { *self = RecipientStatus::Completed(Default::default()) } RecipientStatusType::TemporaryFailure => { *self = RecipientStatus::TemporaryFailure(Default::default()) } RecipientStatusType::PermanentFailure => { *self = RecipientStatus::PermanentFailure(Default::default()) } } } match self { RecipientStatus::Scheduled => pointer.assert_eof(), RecipientStatus::Completed(inner) => inner.patch(pointer, value), RecipientStatus::TemporaryFailure(inner) => inner.patch(pointer, value), RecipientStatus::PermanentFailure(inner) => inner.patch(pointer, value), } } } impl RecipientStatus { pub fn object_type(&self) -> RecipientStatusType { match self { RecipientStatus::Scheduled => RecipientStatusType::Scheduled, RecipientStatus::Completed(_) => RecipientStatusType::Completed, RecipientStatus::TemporaryFailure(_) => RecipientStatusType::TemporaryFailure, RecipientStatus::PermanentFailure(_) => RecipientStatusType::PermanentFailure, } } } impl RedisClusterStore { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.urls; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::Urls)); } } if let Some(value) = &self.auth_username { if value.is_empty() { errors.push(ValidationError::required(Property::AuthUsername)); } } let value = &self.auth_secret; value.validate(errors); if let Some(value) = &self.max_retry_wait { if !value.is_valid() { errors.push(ValidationError::invalid(Property::MaxRetryWait, value)); } if *value > Duration::from_millis(1024) { errors.push(ValidationError::max_value(Property::MaxRetryWait, 1024)); } if *value < Duration::from_millis(1) { errors.push(ValidationError::min_value(Property::MaxRetryWait, 1)); } } if let Some(value) = &self.min_retry_wait { if !value.is_valid() { errors.push(ValidationError::invalid(Property::MinRetryWait, value)); } if *value > Duration::from_millis(1024) { errors.push(ValidationError::max_value(Property::MinRetryWait, 1024)); } if *value < Duration::from_millis(1) { errors.push(ValidationError::min_value(Property::MinRetryWait, 1)); } } if let Some(value) = &self.max_retries { if *value > 1024 { errors.push(ValidationError::max_value(Property::MaxRetries, 1024)); } if *value < 1 { errors.push(ValidationError::min_value(Property::MaxRetries, 1)); } } let value = &self.pool_max_connections; if *value > 8192 { errors.push(ValidationError::max_value( Property::PoolMaxConnections, 8192, )); } if *value < 1 { errors.push(ValidationError::min_value(Property::PoolMaxConnections, 1)); } errors.len() == neb } } impl Pickle for RedisClusterStore { fn pickle(&self, out: &mut Vec) { self.urls.pickle(out); self.timeout.pickle(out); self.auth_username.pickle(out); self.auth_secret.pickle(out); self.max_retry_wait.pickle(out); self.min_retry_wait.pickle(out); self.max_retries.pickle(out); self.read_from_replicas.pickle(out); self.protocol_version.pickle(out); self.pool_max_connections.pickle(out); self.pool_timeout_create.pickle(out); self.pool_timeout_wait.pickle(out); self.pool_timeout_recycle.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.urls = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.auth_username = Pickle::unpickle(stream)?; this.auth_secret = Pickle::unpickle(stream)?; this.max_retry_wait = Pickle::unpickle(stream)?; this.min_retry_wait = Pickle::unpickle(stream)?; this.max_retries = Pickle::unpickle(stream)?; this.read_from_replicas = Pickle::unpickle(stream)?; this.protocol_version = Pickle::unpickle(stream)?; this.pool_max_connections = Pickle::unpickle(stream)?; this.pool_timeout_create = Pickle::unpickle(stream)?; this.pool_timeout_wait = Pickle::unpickle(stream)?; this.pool_timeout_recycle = Pickle::unpickle(stream)?; Some(this) } } impl Default for RedisClusterStore { fn default() -> Self { Self { urls: Map::new(vec!["redis://127.0.0.1".to_string()]), timeout: Duration::from_millis(10000), auth_username: Some("stalwart".to_string()), auth_secret: Default::default(), max_retry_wait: Default::default(), min_retry_wait: Default::default(), max_retries: Default::default(), read_from_replicas: true, protocol_version: RedisProtocol::Resp2, pool_max_connections: 10u64, pool_timeout_create: Some(Duration::from_millis(30000)), pool_timeout_wait: Some(Duration::from_millis(30000)), pool_timeout_recycle: Some(Duration::from_millis(30000)), } } } impl IntoValue for RedisClusterStore { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(15); map.insert_unchecked(Property::Urls, self.urls.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::AuthUsername, self.auth_username.into_value()); map.insert_unchecked(Property::AuthSecret, self.auth_secret.into_value()); map.insert_unchecked(Property::MaxRetryWait, self.max_retry_wait.into_value()); map.insert_unchecked(Property::MinRetryWait, self.min_retry_wait.into_value()); map.insert_unchecked(Property::MaxRetries, self.max_retries.into_value()); map.insert_unchecked( Property::ReadFromReplicas, self.read_from_replicas.into_value(), ); map.insert_unchecked( Property::ProtocolVersion, self.protocol_version.into_value(), ); map.insert_unchecked( Property::PoolMaxConnections, self.pool_max_connections.into_value(), ); map.insert_unchecked( Property::PoolTimeoutCreate, self.pool_timeout_create.into_value(), ); map.insert_unchecked( Property::PoolTimeoutWait, self.pool_timeout_wait.into_value(), ); map.insert_unchecked( Property::PoolTimeoutRecycle, self.pool_timeout_recycle.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for RedisClusterStore { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Urls) => self .urls .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::AuthUsername) => self .auth_username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AuthSecret) => self.auth_secret.patch(pointer, value), Some(Property::MaxRetryWait) => self.max_retry_wait.patch(pointer, value), Some(Property::MinRetryWait) => self.min_retry_wait.patch(pointer, value), Some(Property::MaxRetries) => self.max_retries.patch(pointer, value), Some(Property::ReadFromReplicas) => self.read_from_replicas.patch(pointer, value), Some(Property::ProtocolVersion) => self.protocol_version.patch(pointer, value), Some(Property::PoolMaxConnections) => self.pool_max_connections.patch(pointer, value), Some(Property::PoolTimeoutCreate) => self.pool_timeout_create.patch(pointer, value), Some(Property::PoolTimeoutWait) => self.pool_timeout_wait.patch(pointer, value), Some(Property::PoolTimeoutRecycle) => self.pool_timeout_recycle.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl RedisSentinelStore { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.urls; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::Urls)); } } let value = &self.service_name; if value.is_empty() { errors.push(ValidationError::required(Property::ServiceName)); } if let Some(value) = &self.auth_username { if value.is_empty() { errors.push(ValidationError::required(Property::AuthUsername)); } } let value = &self.auth_secret; value.validate(errors); if let Some(value) = &self.sentinel_username { if value.is_empty() { errors.push(ValidationError::required(Property::SentinelUsername)); } } let value = &self.sentinel_secret; value.validate(errors); let value = &self.pool_max_connections; if *value > 8192 { errors.push(ValidationError::max_value( Property::PoolMaxConnections, 8192, )); } if *value < 1 { errors.push(ValidationError::min_value(Property::PoolMaxConnections, 1)); } errors.len() == neb } } impl Pickle for RedisSentinelStore { fn pickle(&self, out: &mut Vec) { self.urls.pickle(out); self.service_name.pickle(out); self.timeout.pickle(out); self.auth_username.pickle(out); self.auth_secret.pickle(out); self.sentinel_username.pickle(out); self.sentinel_secret.pickle(out); self.protocol_version.pickle(out); self.pool_max_connections.pickle(out); self.pool_timeout_create.pickle(out); self.pool_timeout_wait.pickle(out); self.pool_timeout_recycle.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.urls = Pickle::unpickle(stream)?; this.service_name = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.auth_username = Pickle::unpickle(stream)?; this.auth_secret = Pickle::unpickle(stream)?; this.sentinel_username = Pickle::unpickle(stream)?; this.sentinel_secret = Pickle::unpickle(stream)?; this.protocol_version = Pickle::unpickle(stream)?; this.pool_max_connections = Pickle::unpickle(stream)?; this.pool_timeout_create = Pickle::unpickle(stream)?; this.pool_timeout_wait = Pickle::unpickle(stream)?; this.pool_timeout_recycle = Pickle::unpickle(stream)?; Some(this) } } impl Default for RedisSentinelStore { fn default() -> Self { Self { urls: Map::new(vec!["redis://127.0.0.1:26379".to_string()]), service_name: "mymaster".to_string(), timeout: Duration::from_millis(10000), auth_username: Some("stalwart".to_string()), auth_secret: Default::default(), sentinel_username: Default::default(), sentinel_secret: Default::default(), protocol_version: RedisProtocol::Resp2, pool_max_connections: 10u64, pool_timeout_create: Some(Duration::from_millis(30000)), pool_timeout_wait: Some(Duration::from_millis(30000)), pool_timeout_recycle: Some(Duration::from_millis(30000)), } } } impl IntoValue for RedisSentinelStore { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked(Property::Urls, self.urls.into_value()); map.insert_unchecked(Property::ServiceName, self.service_name.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::AuthUsername, self.auth_username.into_value()); map.insert_unchecked(Property::AuthSecret, self.auth_secret.into_value()); map.insert_unchecked( Property::SentinelUsername, self.sentinel_username.into_value(), ); map.insert_unchecked(Property::SentinelSecret, self.sentinel_secret.into_value()); map.insert_unchecked( Property::ProtocolVersion, self.protocol_version.into_value(), ); map.insert_unchecked( Property::PoolMaxConnections, self.pool_max_connections.into_value(), ); map.insert_unchecked( Property::PoolTimeoutCreate, self.pool_timeout_create.into_value(), ); map.insert_unchecked( Property::PoolTimeoutWait, self.pool_timeout_wait.into_value(), ); map.insert_unchecked( Property::PoolTimeoutRecycle, self.pool_timeout_recycle.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for RedisSentinelStore { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Urls) => self .urls .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ServiceName) => self .service_name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::AuthUsername) => self .auth_username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AuthSecret) => self.auth_secret.patch(pointer, value), Some(Property::SentinelUsername) => self .sentinel_username .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::SentinelSecret) => self.sentinel_secret.patch(pointer, value), Some(Property::ProtocolVersion) => self.protocol_version.patch(pointer, value), Some(Property::PoolMaxConnections) => self.pool_max_connections.patch(pointer, value), Some(Property::PoolTimeoutCreate) => self.pool_timeout_create.patch(pointer, value), Some(Property::PoolTimeoutWait) => self.pool_timeout_wait.patch(pointer, value), Some(Property::PoolTimeoutRecycle) => self.pool_timeout_recycle.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl RedisStore { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.url; if value.is_empty() { errors.push(ValidationError::required(Property::Url)); } let value = &self.pool_max_connections; if *value > 8192 { errors.push(ValidationError::max_value( Property::PoolMaxConnections, 8192, )); } if *value < 1 { errors.push(ValidationError::min_value(Property::PoolMaxConnections, 1)); } errors.len() == neb } } impl Pickle for RedisStore { fn pickle(&self, out: &mut Vec) { self.url.pickle(out); self.timeout.pickle(out); self.pool_max_connections.pickle(out); self.pool_timeout_create.pickle(out); self.pool_timeout_wait.pickle(out); self.pool_timeout_recycle.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.url = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.pool_max_connections = Pickle::unpickle(stream)?; this.pool_timeout_create = Pickle::unpickle(stream)?; this.pool_timeout_wait = Pickle::unpickle(stream)?; this.pool_timeout_recycle = Pickle::unpickle(stream)?; Some(this) } } impl Default for RedisStore { fn default() -> Self { Self { url: "redis://127.0.0.1".to_string(), timeout: Duration::from_millis(10000), pool_max_connections: 10u64, pool_timeout_create: Some(Duration::from_millis(30000)), pool_timeout_wait: Some(Duration::from_millis(30000)), pool_timeout_recycle: Some(Duration::from_millis(30000)), } } } impl IntoValue for RedisStore { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::Url, self.url.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked( Property::PoolMaxConnections, self.pool_max_connections.into_value(), ); map.insert_unchecked( Property::PoolTimeoutCreate, self.pool_timeout_create.into_value(), ); map.insert_unchecked( Property::PoolTimeoutWait, self.pool_timeout_wait.into_value(), ); map.insert_unchecked( Property::PoolTimeoutRecycle, self.pool_timeout_recycle.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for RedisStore { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Url) => self .url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::PoolMaxConnections) => self.pool_max_connections.patch(pointer, value), Some(Property::PoolTimeoutCreate) => self.pool_timeout_create.patch(pointer, value), Some(Property::PoolTimeoutWait) => self.pool_timeout_wait.patch(pointer, value), Some(Property::PoolTimeoutRecycle) => self.pool_timeout_recycle.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for ReportSettings { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 1; const OBJECT: ObjectType = ObjectType::ReportSettings; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.inbound_report_addresses; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::InboundReportAddresses)); } } if let Some(value) = &self.outbound_report_domain { if value.is_empty() { errors.push(ValidationError::required(Property::OutboundReportDomain)); } } let value = &self.outbound_report_submitter; value.validate(errors); let value = &self.inbound_report_max_size; if *value < (1024) { errors.push(ValidationError::min_value( Property::InboundReportMaxSize, 1024, )); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl ReportSettings { pub fn ctx_outbound_report_submitter(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.outbound_report_submitter, default: Some(Expression { else_: "system('hostname')".to_string(), ..Default::default() }), property: Property::OutboundReportSubmitter, allowed_variables: MTA_RCPT_DOMAIN_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_outbound_report_submitter()] } } impl Pickle for ReportSettings { fn pickle(&self, out: &mut Vec) { self.inbound_report_addresses.pickle(out); self.inbound_report_forwarding.pickle(out); self.outbound_report_domain.pickle(out); self.outbound_report_submitter.pickle(out); self.inbound_report_max_size.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.inbound_report_addresses = Pickle::unpickle(stream)?; this.inbound_report_forwarding = Pickle::unpickle(stream)?; this.outbound_report_domain = Pickle::unpickle(stream)?; this.outbound_report_submitter = Pickle::unpickle(stream)?; if stream.version() >= 1 { this.inbound_report_max_size = Pickle::unpickle(stream)?; } Some(this) } } impl Default for ReportSettings { fn default() -> Self { Self { inbound_report_addresses: Map::new(vec!["postmaster@*".to_string()]), inbound_report_forwarding: true, outbound_report_domain: Default::default(), outbound_report_submitter: Expression { else_: "system('hostname')".to_string(), ..Default::default() }, inbound_report_max_size: 26214400i64, } } } impl IntoValue for ReportSettings { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked( Property::InboundReportAddresses, self.inbound_report_addresses.into_value(), ); map.insert_unchecked( Property::InboundReportForwarding, self.inbound_report_forwarding.into_value(), ); map.insert_unchecked( Property::OutboundReportDomain, self.outbound_report_domain.into_value(), ); map.insert_unchecked( Property::OutboundReportSubmitter, self.outbound_report_submitter.into_value(), ); map.insert_unchecked( Property::InboundReportMaxSize, self.inbound_report_max_size.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ReportSettings { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::InboundReportAddresses) => self .inbound_report_addresses .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::InboundReportForwarding) => { self.inbound_report_forwarding.patch(pointer, value) } Some(Property::OutboundReportDomain) => self .outbound_report_domain .patch(pointer.with_validators(&[StringValidator::Domain]), value), Some(Property::OutboundReportSubmitter) => { self.outbound_report_submitter.patch(pointer, value) } Some(Property::InboundReportMaxSize) => { self.inbound_report_max_size.patch(pointer, value) } Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl RocksDbStore { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.path; if value.is_empty() { errors.push(ValidationError::required(Property::Path)); } let value = &self.blob_size; if *value > 1048576 { errors.push(ValidationError::max_value(Property::BlobSize, 1048576)); } if *value < 1024 { errors.push(ValidationError::min_value(Property::BlobSize, 1024)); } let value = &self.buffer_size; if *value > 4294967296 { errors.push(ValidationError::max_value(Property::BufferSize, 4294967296)); } if *value < 8388608 { errors.push(ValidationError::min_value(Property::BufferSize, 8388608)); } if let Some(value) = &self.pool_workers { if *value > 64 { errors.push(ValidationError::max_value(Property::PoolWorkers, 64)); } if *value < 1 { errors.push(ValidationError::min_value(Property::PoolWorkers, 1)); } } let value = &self.cache_size; if *value > 17179869184 { errors.push(ValidationError::max_value(Property::CacheSize, 17179869184)); } if *value < 8388608 { errors.push(ValidationError::min_value(Property::CacheSize, 8388608)); } errors.len() == neb } } impl Pickle for RocksDbStore { fn pickle(&self, out: &mut Vec) { self.path.pickle(out); self.blob_size.pickle(out); self.buffer_size.pickle(out); self.pool_workers.pickle(out); self.cache_size.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.path = Pickle::unpickle(stream)?; this.blob_size = Pickle::unpickle(stream)?; this.buffer_size = Pickle::unpickle(stream)?; this.pool_workers = Pickle::unpickle(stream)?; if stream.version() >= 1 { this.cache_size = Pickle::unpickle(stream)?; } Some(this) } } impl Default for RocksDbStore { fn default() -> Self { Self { path: Default::default(), blob_size: 16834u64, buffer_size: 134217728u64, pool_workers: Default::default(), cache_size: 134217728u64, } } } impl IntoValue for RocksDbStore { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Path, self.path.into_value()); map.insert_unchecked(Property::BlobSize, self.blob_size.into_value()); map.insert_unchecked(Property::BufferSize, self.buffer_size.into_value()); map.insert_unchecked(Property::PoolWorkers, self.pool_workers.into_value()); map.insert_unchecked(Property::CacheSize, self.cache_size.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for RocksDbStore { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Path) => self .path .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::BlobSize) => self.blob_size.patch(pointer, value), Some(Property::BufferSize) => self.buffer_size.patch(pointer, value), Some(Property::PoolWorkers) => self.pool_workers.patch(pointer, value), Some(Property::CacheSize) => self.cache_size.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Role { const FLAGS: u64 = OBJ_FILTER_TENANT | OBJ_SEQ_ID; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Role; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } let value = &self.role_ids; for value in value.iter() { if !value.is_valid() { errors.push(ValidationError::required(Property::RoleIds)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.text(Property::Description, &self.description); i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } for id in self.role_ids.iter() { i.foreign_key(ObjectType::Role, Some(*id), None); } } } impl Pickle for Role { fn pickle(&self, out: &mut Vec) { self.description.pickle(out); self.member_tenant_id.pickle(out); self.role_ids.pickle(out); self.enabled_permissions.pickle(out); self.disabled_permissions.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.description = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.role_ids = Pickle::unpickle(stream)?; this.enabled_permissions = Pickle::unpickle(stream)?; this.disabled_permissions = Pickle::unpickle(stream)?; Some(this) } } impl Default for Role { fn default() -> Self { Self { description: Default::default(), member_tenant_id: Default::default(), role_ids: Default::default(), enabled_permissions: Default::default(), disabled_permissions: Default::default(), } } } impl IntoValue for Role { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::RoleIds, self.role_ids.into_value()); map.insert_unchecked( Property::EnabledPermissions, self.enabled_permissions.into_value(), ); map.insert_unchecked( Property::DisabledPermissions, self.disabled_permissions.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Role { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Description) => self.description.patch(pointer, value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::RoleIds) => self.role_ids.patch(pointer, value), Some(Property::EnabledPermissions) => self.enabled_permissions.patch(pointer, value), Some(Property::DisabledPermissions) => self.disabled_permissions.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl Roles { fn validate(&self, errors: &mut Vec) -> bool { match self { Roles::Default => true, Roles::Custom(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { Roles::Default => {} Roles::Custom(object) => { object.index(i); } } } } impl Default for Roles { fn default() -> Self { Roles::Default } } impl Pickle for Roles { fn pickle(&self, out: &mut Vec) { match self { Roles::Default => { 0u16.pickle(out); } Roles::Custom(inner) => { 1u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(Roles::Default), 1 => Pickle::unpickle(stream).map(Roles::Custom), _ => None, } } } impl IntoValue for Roles { fn into_value(self) -> JmapValue<'static> { match self { Roles::Default => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Default".into())); JmapValue::Object(obj) } Roles::Custom(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Custom".into())); obj } } } } impl RegistryJsonPatch for Roles { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { RolesType::Default => *self = Roles::Default, RolesType::Custom => *self = Roles::Custom(Default::default()), } } match self { Roles::Default => pointer.assert_eof(), Roles::Custom(inner) => inner.patch(pointer, value), } } } impl Roles { pub fn object_type(&self) -> RolesType { match self { Roles::Default => RolesType::Default, Roles::Custom(_) => RolesType::Custom, } } } impl S3Store { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.region; value.validate(errors); let value = &self.bucket; if value.is_empty() { errors.push(ValidationError::required(Property::Bucket)); } let value = &self.access_key; value.validate(errors); let value = &self.secret_key; value.validate(errors); let value = &self.security_token; value.validate(errors); let value = &self.session_token; value.validate(errors); if let Some(value) = &self.profile { if value.is_empty() { errors.push(ValidationError::required(Property::Profile)); } } let value = &self.max_retries; if *value > 10 { errors.push(ValidationError::max_value(Property::MaxRetries, 10)); } if *value < 1 { errors.push(ValidationError::min_value(Property::MaxRetries, 1)); } if let Some(value) = &self.key_prefix { if value.is_empty() { errors.push(ValidationError::required(Property::KeyPrefix)); } } errors.len() == neb } } impl Pickle for S3Store { fn pickle(&self, out: &mut Vec) { self.region.pickle(out); self.bucket.pickle(out); self.access_key.pickle(out); self.secret_key.pickle(out); self.security_token.pickle(out); self.session_token.pickle(out); self.profile.pickle(out); self.timeout.pickle(out); self.max_retries.pickle(out); self.key_prefix.pickle(out); self.allow_invalid_certs.pickle(out); self.verify_after_write.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.region = Pickle::unpickle(stream)?; this.bucket = Pickle::unpickle(stream)?; this.access_key = Pickle::unpickle(stream)?; this.secret_key = Pickle::unpickle(stream)?; this.security_token = Pickle::unpickle(stream)?; this.session_token = Pickle::unpickle(stream)?; this.profile = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.max_retries = Pickle::unpickle(stream)?; this.key_prefix = Pickle::unpickle(stream)?; this.allow_invalid_certs = Pickle::unpickle(stream)?; if stream.version() >= 1 { this.verify_after_write = Pickle::unpickle(stream)?; } Some(this) } } impl Default for S3Store { fn default() -> Self { Self { region: Default::default(), bucket: Default::default(), access_key: Default::default(), secret_key: Default::default(), security_token: Default::default(), session_token: Default::default(), profile: Default::default(), timeout: Duration::from_millis(30000), max_retries: 3u64, key_prefix: Default::default(), allow_invalid_certs: false, verify_after_write: true, } } } impl IntoValue for S3Store { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked(Property::Region, self.region.into_value()); map.insert_unchecked(Property::Bucket, self.bucket.into_value()); map.insert_unchecked(Property::AccessKey, self.access_key.into_value()); map.insert_unchecked(Property::SecretKey, self.secret_key.into_value()); map.insert_unchecked(Property::SecurityToken, self.security_token.into_value()); map.insert_unchecked(Property::SessionToken, self.session_token.into_value()); map.insert_unchecked(Property::Profile, self.profile.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::MaxRetries, self.max_retries.into_value()); map.insert_unchecked(Property::KeyPrefix, self.key_prefix.into_value()); map.insert_unchecked( Property::AllowInvalidCerts, self.allow_invalid_certs.into_value(), ); map.insert_unchecked( Property::VerifyAfterWrite, self.verify_after_write.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for S3Store { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Region) => self.region.patch(pointer, value), Some(Property::Bucket) => self .bucket .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AccessKey) => self.access_key.patch(pointer, value), Some(Property::SecretKey) => self.secret_key.patch(pointer, value), Some(Property::SecurityToken) => self.security_token.patch(pointer, value), Some(Property::SessionToken) => self.session_token.patch(pointer, value), Some(Property::Profile) => self .profile .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::MaxRetries) => self.max_retries.patch(pointer, value), Some(Property::KeyPrefix) => self .key_prefix .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::AllowInvalidCerts) => self.allow_invalid_certs.patch(pointer, value), Some(Property::VerifyAfterWrite) => self.verify_after_write.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl S3StoreCustomRegion { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.custom_endpoint; if value.is_empty() { errors.push(ValidationError::required(Property::CustomEndpoint)); } let value = &self.custom_region; if value.is_empty() { errors.push(ValidationError::required(Property::CustomRegion)); } errors.len() == neb } } impl Pickle for S3StoreCustomRegion { fn pickle(&self, out: &mut Vec) { self.custom_endpoint.pickle(out); self.custom_region.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.custom_endpoint = Pickle::unpickle(stream)?; this.custom_region = Pickle::unpickle(stream)?; Some(this) } } impl Default for S3StoreCustomRegion { fn default() -> Self { Self { custom_endpoint: Default::default(), custom_region: Default::default(), } } } impl IntoValue for S3StoreCustomRegion { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::CustomEndpoint, self.custom_endpoint.into_value()); map.insert_unchecked(Property::CustomRegion, self.custom_region.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for S3StoreCustomRegion { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::CustomEndpoint) => self .custom_endpoint .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::CustomRegion) => self .custom_region .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl S3StoreRegion { fn validate(&self, errors: &mut Vec) -> bool { match self { S3StoreRegion::UsEast1 => true, S3StoreRegion::UsEast2 => true, S3StoreRegion::UsWest1 => true, S3StoreRegion::UsWest2 => true, S3StoreRegion::CaCentral1 => true, S3StoreRegion::AfSouth1 => true, S3StoreRegion::ApEast1 => true, S3StoreRegion::ApSouth1 => true, S3StoreRegion::ApNortheast1 => true, S3StoreRegion::ApNortheast2 => true, S3StoreRegion::ApNortheast3 => true, S3StoreRegion::ApSoutheast1 => true, S3StoreRegion::ApSoutheast2 => true, S3StoreRegion::CnNorth1 => true, S3StoreRegion::CnNorthwest1 => true, S3StoreRegion::EuNorth1 => true, S3StoreRegion::EuCentral1 => true, S3StoreRegion::EuCentral2 => true, S3StoreRegion::EuWest1 => true, S3StoreRegion::EuWest2 => true, S3StoreRegion::EuWest3 => true, S3StoreRegion::IlCentral1 => true, S3StoreRegion::MeSouth1 => true, S3StoreRegion::SaEast1 => true, S3StoreRegion::DoNyc3 => true, S3StoreRegion::DoAms3 => true, S3StoreRegion::DoSgp1 => true, S3StoreRegion::DoFra1 => true, S3StoreRegion::Yandex => true, S3StoreRegion::WaUsEast1 => true, S3StoreRegion::WaUsEast2 => true, S3StoreRegion::WaUsCentral1 => true, S3StoreRegion::WaUsWest1 => true, S3StoreRegion::WaCaCentral1 => true, S3StoreRegion::WaEuCentral1 => true, S3StoreRegion::WaEuCentral2 => true, S3StoreRegion::WaEuWest1 => true, S3StoreRegion::WaEuWest2 => true, S3StoreRegion::WaApNortheast1 => true, S3StoreRegion::WaApNortheast2 => true, S3StoreRegion::WaApSoutheast1 => true, S3StoreRegion::WaApSoutheast2 => true, S3StoreRegion::Custom(inner) => inner.validate(errors), } } } impl Default for S3StoreRegion { fn default() -> Self { S3StoreRegion::UsEast1 } } impl Pickle for S3StoreRegion { fn pickle(&self, out: &mut Vec) { match self { S3StoreRegion::UsEast1 => { 0u16.pickle(out); } S3StoreRegion::UsEast2 => { 1u16.pickle(out); } S3StoreRegion::UsWest1 => { 2u16.pickle(out); } S3StoreRegion::UsWest2 => { 3u16.pickle(out); } S3StoreRegion::CaCentral1 => { 4u16.pickle(out); } S3StoreRegion::AfSouth1 => { 5u16.pickle(out); } S3StoreRegion::ApEast1 => { 6u16.pickle(out); } S3StoreRegion::ApSouth1 => { 7u16.pickle(out); } S3StoreRegion::ApNortheast1 => { 8u16.pickle(out); } S3StoreRegion::ApNortheast2 => { 9u16.pickle(out); } S3StoreRegion::ApNortheast3 => { 10u16.pickle(out); } S3StoreRegion::ApSoutheast1 => { 11u16.pickle(out); } S3StoreRegion::ApSoutheast2 => { 12u16.pickle(out); } S3StoreRegion::CnNorth1 => { 13u16.pickle(out); } S3StoreRegion::CnNorthwest1 => { 14u16.pickle(out); } S3StoreRegion::EuNorth1 => { 15u16.pickle(out); } S3StoreRegion::EuCentral1 => { 16u16.pickle(out); } S3StoreRegion::EuCentral2 => { 17u16.pickle(out); } S3StoreRegion::EuWest1 => { 18u16.pickle(out); } S3StoreRegion::EuWest2 => { 19u16.pickle(out); } S3StoreRegion::EuWest3 => { 20u16.pickle(out); } S3StoreRegion::IlCentral1 => { 21u16.pickle(out); } S3StoreRegion::MeSouth1 => { 22u16.pickle(out); } S3StoreRegion::SaEast1 => { 23u16.pickle(out); } S3StoreRegion::DoNyc3 => { 24u16.pickle(out); } S3StoreRegion::DoAms3 => { 25u16.pickle(out); } S3StoreRegion::DoSgp1 => { 26u16.pickle(out); } S3StoreRegion::DoFra1 => { 27u16.pickle(out); } S3StoreRegion::Yandex => { 28u16.pickle(out); } S3StoreRegion::WaUsEast1 => { 29u16.pickle(out); } S3StoreRegion::WaUsEast2 => { 30u16.pickle(out); } S3StoreRegion::WaUsCentral1 => { 31u16.pickle(out); } S3StoreRegion::WaUsWest1 => { 32u16.pickle(out); } S3StoreRegion::WaCaCentral1 => { 33u16.pickle(out); } S3StoreRegion::WaEuCentral1 => { 34u16.pickle(out); } S3StoreRegion::WaEuCentral2 => { 35u16.pickle(out); } S3StoreRegion::WaEuWest1 => { 36u16.pickle(out); } S3StoreRegion::WaEuWest2 => { 37u16.pickle(out); } S3StoreRegion::WaApNortheast1 => { 38u16.pickle(out); } S3StoreRegion::WaApNortheast2 => { 39u16.pickle(out); } S3StoreRegion::WaApSoutheast1 => { 40u16.pickle(out); } S3StoreRegion::WaApSoutheast2 => { 41u16.pickle(out); } S3StoreRegion::Custom(inner) => { 42u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(S3StoreRegion::UsEast1), 1 => Some(S3StoreRegion::UsEast2), 2 => Some(S3StoreRegion::UsWest1), 3 => Some(S3StoreRegion::UsWest2), 4 => Some(S3StoreRegion::CaCentral1), 5 => Some(S3StoreRegion::AfSouth1), 6 => Some(S3StoreRegion::ApEast1), 7 => Some(S3StoreRegion::ApSouth1), 8 => Some(S3StoreRegion::ApNortheast1), 9 => Some(S3StoreRegion::ApNortheast2), 10 => Some(S3StoreRegion::ApNortheast3), 11 => Some(S3StoreRegion::ApSoutheast1), 12 => Some(S3StoreRegion::ApSoutheast2), 13 => Some(S3StoreRegion::CnNorth1), 14 => Some(S3StoreRegion::CnNorthwest1), 15 => Some(S3StoreRegion::EuNorth1), 16 => Some(S3StoreRegion::EuCentral1), 17 => Some(S3StoreRegion::EuCentral2), 18 => Some(S3StoreRegion::EuWest1), 19 => Some(S3StoreRegion::EuWest2), 20 => Some(S3StoreRegion::EuWest3), 21 => Some(S3StoreRegion::IlCentral1), 22 => Some(S3StoreRegion::MeSouth1), 23 => Some(S3StoreRegion::SaEast1), 24 => Some(S3StoreRegion::DoNyc3), 25 => Some(S3StoreRegion::DoAms3), 26 => Some(S3StoreRegion::DoSgp1), 27 => Some(S3StoreRegion::DoFra1), 28 => Some(S3StoreRegion::Yandex), 29 => Some(S3StoreRegion::WaUsEast1), 30 => Some(S3StoreRegion::WaUsEast2), 31 => Some(S3StoreRegion::WaUsCentral1), 32 => Some(S3StoreRegion::WaUsWest1), 33 => Some(S3StoreRegion::WaCaCentral1), 34 => Some(S3StoreRegion::WaEuCentral1), 35 => Some(S3StoreRegion::WaEuCentral2), 36 => Some(S3StoreRegion::WaEuWest1), 37 => Some(S3StoreRegion::WaEuWest2), 38 => Some(S3StoreRegion::WaApNortheast1), 39 => Some(S3StoreRegion::WaApNortheast2), 40 => Some(S3StoreRegion::WaApSoutheast1), 41 => Some(S3StoreRegion::WaApSoutheast2), 42 => Pickle::unpickle(stream).map(S3StoreRegion::Custom), _ => None, } } } impl IntoValue for S3StoreRegion { fn into_value(self) -> JmapValue<'static> { match self { S3StoreRegion::UsEast1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("UsEast1".into())); JmapValue::Object(obj) } S3StoreRegion::UsEast2 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("UsEast2".into())); JmapValue::Object(obj) } S3StoreRegion::UsWest1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("UsWest1".into())); JmapValue::Object(obj) } S3StoreRegion::UsWest2 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("UsWest2".into())); JmapValue::Object(obj) } S3StoreRegion::CaCentral1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("CaCentral1".into())); JmapValue::Object(obj) } S3StoreRegion::AfSouth1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("AfSouth1".into())); JmapValue::Object(obj) } S3StoreRegion::ApEast1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("ApEast1".into())); JmapValue::Object(obj) } S3StoreRegion::ApSouth1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("ApSouth1".into())); JmapValue::Object(obj) } S3StoreRegion::ApNortheast1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("ApNortheast1".into())); JmapValue::Object(obj) } S3StoreRegion::ApNortheast2 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("ApNortheast2".into())); JmapValue::Object(obj) } S3StoreRegion::ApNortheast3 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("ApNortheast3".into())); JmapValue::Object(obj) } S3StoreRegion::ApSoutheast1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("ApSoutheast1".into())); JmapValue::Object(obj) } S3StoreRegion::ApSoutheast2 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("ApSoutheast2".into())); JmapValue::Object(obj) } S3StoreRegion::CnNorth1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("CnNorth1".into())); JmapValue::Object(obj) } S3StoreRegion::CnNorthwest1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("CnNorthwest1".into())); JmapValue::Object(obj) } S3StoreRegion::EuNorth1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("EuNorth1".into())); JmapValue::Object(obj) } S3StoreRegion::EuCentral1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("EuCentral1".into())); JmapValue::Object(obj) } S3StoreRegion::EuCentral2 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("EuCentral2".into())); JmapValue::Object(obj) } S3StoreRegion::EuWest1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("EuWest1".into())); JmapValue::Object(obj) } S3StoreRegion::EuWest2 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("EuWest2".into())); JmapValue::Object(obj) } S3StoreRegion::EuWest3 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("EuWest3".into())); JmapValue::Object(obj) } S3StoreRegion::IlCentral1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("IlCentral1".into())); JmapValue::Object(obj) } S3StoreRegion::MeSouth1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("MeSouth1".into())); JmapValue::Object(obj) } S3StoreRegion::SaEast1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("SaEast1".into())); JmapValue::Object(obj) } S3StoreRegion::DoNyc3 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("DoNyc3".into())); JmapValue::Object(obj) } S3StoreRegion::DoAms3 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("DoAms3".into())); JmapValue::Object(obj) } S3StoreRegion::DoSgp1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("DoSgp1".into())); JmapValue::Object(obj) } S3StoreRegion::DoFra1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("DoFra1".into())); JmapValue::Object(obj) } S3StoreRegion::Yandex => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Yandex".into())); JmapValue::Object(obj) } S3StoreRegion::WaUsEast1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("WaUsEast1".into())); JmapValue::Object(obj) } S3StoreRegion::WaUsEast2 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("WaUsEast2".into())); JmapValue::Object(obj) } S3StoreRegion::WaUsCentral1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("WaUsCentral1".into())); JmapValue::Object(obj) } S3StoreRegion::WaUsWest1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("WaUsWest1".into())); JmapValue::Object(obj) } S3StoreRegion::WaCaCentral1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("WaCaCentral1".into())); JmapValue::Object(obj) } S3StoreRegion::WaEuCentral1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("WaEuCentral1".into())); JmapValue::Object(obj) } S3StoreRegion::WaEuCentral2 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("WaEuCentral2".into())); JmapValue::Object(obj) } S3StoreRegion::WaEuWest1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("WaEuWest1".into())); JmapValue::Object(obj) } S3StoreRegion::WaEuWest2 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("WaEuWest2".into())); JmapValue::Object(obj) } S3StoreRegion::WaApNortheast1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("WaApNortheast1".into())); JmapValue::Object(obj) } S3StoreRegion::WaApNortheast2 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("WaApNortheast2".into())); JmapValue::Object(obj) } S3StoreRegion::WaApSoutheast1 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("WaApSoutheast1".into())); JmapValue::Object(obj) } S3StoreRegion::WaApSoutheast2 => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("WaApSoutheast2".into())); JmapValue::Object(obj) } S3StoreRegion::Custom(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Custom".into())); obj } } } } impl RegistryJsonPatch for S3StoreRegion { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { S3StoreRegionType::UsEast1 => *self = S3StoreRegion::UsEast1, S3StoreRegionType::UsEast2 => *self = S3StoreRegion::UsEast2, S3StoreRegionType::UsWest1 => *self = S3StoreRegion::UsWest1, S3StoreRegionType::UsWest2 => *self = S3StoreRegion::UsWest2, S3StoreRegionType::CaCentral1 => *self = S3StoreRegion::CaCentral1, S3StoreRegionType::AfSouth1 => *self = S3StoreRegion::AfSouth1, S3StoreRegionType::ApEast1 => *self = S3StoreRegion::ApEast1, S3StoreRegionType::ApSouth1 => *self = S3StoreRegion::ApSouth1, S3StoreRegionType::ApNortheast1 => *self = S3StoreRegion::ApNortheast1, S3StoreRegionType::ApNortheast2 => *self = S3StoreRegion::ApNortheast2, S3StoreRegionType::ApNortheast3 => *self = S3StoreRegion::ApNortheast3, S3StoreRegionType::ApSoutheast1 => *self = S3StoreRegion::ApSoutheast1, S3StoreRegionType::ApSoutheast2 => *self = S3StoreRegion::ApSoutheast2, S3StoreRegionType::CnNorth1 => *self = S3StoreRegion::CnNorth1, S3StoreRegionType::CnNorthwest1 => *self = S3StoreRegion::CnNorthwest1, S3StoreRegionType::EuNorth1 => *self = S3StoreRegion::EuNorth1, S3StoreRegionType::EuCentral1 => *self = S3StoreRegion::EuCentral1, S3StoreRegionType::EuCentral2 => *self = S3StoreRegion::EuCentral2, S3StoreRegionType::EuWest1 => *self = S3StoreRegion::EuWest1, S3StoreRegionType::EuWest2 => *self = S3StoreRegion::EuWest2, S3StoreRegionType::EuWest3 => *self = S3StoreRegion::EuWest3, S3StoreRegionType::IlCentral1 => *self = S3StoreRegion::IlCentral1, S3StoreRegionType::MeSouth1 => *self = S3StoreRegion::MeSouth1, S3StoreRegionType::SaEast1 => *self = S3StoreRegion::SaEast1, S3StoreRegionType::DoNyc3 => *self = S3StoreRegion::DoNyc3, S3StoreRegionType::DoAms3 => *self = S3StoreRegion::DoAms3, S3StoreRegionType::DoSgp1 => *self = S3StoreRegion::DoSgp1, S3StoreRegionType::DoFra1 => *self = S3StoreRegion::DoFra1, S3StoreRegionType::Yandex => *self = S3StoreRegion::Yandex, S3StoreRegionType::WaUsEast1 => *self = S3StoreRegion::WaUsEast1, S3StoreRegionType::WaUsEast2 => *self = S3StoreRegion::WaUsEast2, S3StoreRegionType::WaUsCentral1 => *self = S3StoreRegion::WaUsCentral1, S3StoreRegionType::WaUsWest1 => *self = S3StoreRegion::WaUsWest1, S3StoreRegionType::WaCaCentral1 => *self = S3StoreRegion::WaCaCentral1, S3StoreRegionType::WaEuCentral1 => *self = S3StoreRegion::WaEuCentral1, S3StoreRegionType::WaEuCentral2 => *self = S3StoreRegion::WaEuCentral2, S3StoreRegionType::WaEuWest1 => *self = S3StoreRegion::WaEuWest1, S3StoreRegionType::WaEuWest2 => *self = S3StoreRegion::WaEuWest2, S3StoreRegionType::WaApNortheast1 => *self = S3StoreRegion::WaApNortheast1, S3StoreRegionType::WaApNortheast2 => *self = S3StoreRegion::WaApNortheast2, S3StoreRegionType::WaApSoutheast1 => *self = S3StoreRegion::WaApSoutheast1, S3StoreRegionType::WaApSoutheast2 => *self = S3StoreRegion::WaApSoutheast2, S3StoreRegionType::Custom => *self = S3StoreRegion::Custom(Default::default()), } } match self { S3StoreRegion::UsEast1 => pointer.assert_eof(), S3StoreRegion::UsEast2 => pointer.assert_eof(), S3StoreRegion::UsWest1 => pointer.assert_eof(), S3StoreRegion::UsWest2 => pointer.assert_eof(), S3StoreRegion::CaCentral1 => pointer.assert_eof(), S3StoreRegion::AfSouth1 => pointer.assert_eof(), S3StoreRegion::ApEast1 => pointer.assert_eof(), S3StoreRegion::ApSouth1 => pointer.assert_eof(), S3StoreRegion::ApNortheast1 => pointer.assert_eof(), S3StoreRegion::ApNortheast2 => pointer.assert_eof(), S3StoreRegion::ApNortheast3 => pointer.assert_eof(), S3StoreRegion::ApSoutheast1 => pointer.assert_eof(), S3StoreRegion::ApSoutheast2 => pointer.assert_eof(), S3StoreRegion::CnNorth1 => pointer.assert_eof(), S3StoreRegion::CnNorthwest1 => pointer.assert_eof(), S3StoreRegion::EuNorth1 => pointer.assert_eof(), S3StoreRegion::EuCentral1 => pointer.assert_eof(), S3StoreRegion::EuCentral2 => pointer.assert_eof(), S3StoreRegion::EuWest1 => pointer.assert_eof(), S3StoreRegion::EuWest2 => pointer.assert_eof(), S3StoreRegion::EuWest3 => pointer.assert_eof(), S3StoreRegion::IlCentral1 => pointer.assert_eof(), S3StoreRegion::MeSouth1 => pointer.assert_eof(), S3StoreRegion::SaEast1 => pointer.assert_eof(), S3StoreRegion::DoNyc3 => pointer.assert_eof(), S3StoreRegion::DoAms3 => pointer.assert_eof(), S3StoreRegion::DoSgp1 => pointer.assert_eof(), S3StoreRegion::DoFra1 => pointer.assert_eof(), S3StoreRegion::Yandex => pointer.assert_eof(), S3StoreRegion::WaUsEast1 => pointer.assert_eof(), S3StoreRegion::WaUsEast2 => pointer.assert_eof(), S3StoreRegion::WaUsCentral1 => pointer.assert_eof(), S3StoreRegion::WaUsWest1 => pointer.assert_eof(), S3StoreRegion::WaCaCentral1 => pointer.assert_eof(), S3StoreRegion::WaEuCentral1 => pointer.assert_eof(), S3StoreRegion::WaEuCentral2 => pointer.assert_eof(), S3StoreRegion::WaEuWest1 => pointer.assert_eof(), S3StoreRegion::WaEuWest2 => pointer.assert_eof(), S3StoreRegion::WaApNortheast1 => pointer.assert_eof(), S3StoreRegion::WaApNortheast2 => pointer.assert_eof(), S3StoreRegion::WaApSoutheast1 => pointer.assert_eof(), S3StoreRegion::WaApSoutheast2 => pointer.assert_eof(), S3StoreRegion::Custom(inner) => inner.patch(pointer, value), } } } impl S3StoreRegion { pub fn object_type(&self) -> S3StoreRegionType { match self { S3StoreRegion::UsEast1 => S3StoreRegionType::UsEast1, S3StoreRegion::UsEast2 => S3StoreRegionType::UsEast2, S3StoreRegion::UsWest1 => S3StoreRegionType::UsWest1, S3StoreRegion::UsWest2 => S3StoreRegionType::UsWest2, S3StoreRegion::CaCentral1 => S3StoreRegionType::CaCentral1, S3StoreRegion::AfSouth1 => S3StoreRegionType::AfSouth1, S3StoreRegion::ApEast1 => S3StoreRegionType::ApEast1, S3StoreRegion::ApSouth1 => S3StoreRegionType::ApSouth1, S3StoreRegion::ApNortheast1 => S3StoreRegionType::ApNortheast1, S3StoreRegion::ApNortheast2 => S3StoreRegionType::ApNortheast2, S3StoreRegion::ApNortheast3 => S3StoreRegionType::ApNortheast3, S3StoreRegion::ApSoutheast1 => S3StoreRegionType::ApSoutheast1, S3StoreRegion::ApSoutheast2 => S3StoreRegionType::ApSoutheast2, S3StoreRegion::CnNorth1 => S3StoreRegionType::CnNorth1, S3StoreRegion::CnNorthwest1 => S3StoreRegionType::CnNorthwest1, S3StoreRegion::EuNorth1 => S3StoreRegionType::EuNorth1, S3StoreRegion::EuCentral1 => S3StoreRegionType::EuCentral1, S3StoreRegion::EuCentral2 => S3StoreRegionType::EuCentral2, S3StoreRegion::EuWest1 => S3StoreRegionType::EuWest1, S3StoreRegion::EuWest2 => S3StoreRegionType::EuWest2, S3StoreRegion::EuWest3 => S3StoreRegionType::EuWest3, S3StoreRegion::IlCentral1 => S3StoreRegionType::IlCentral1, S3StoreRegion::MeSouth1 => S3StoreRegionType::MeSouth1, S3StoreRegion::SaEast1 => S3StoreRegionType::SaEast1, S3StoreRegion::DoNyc3 => S3StoreRegionType::DoNyc3, S3StoreRegion::DoAms3 => S3StoreRegionType::DoAms3, S3StoreRegion::DoSgp1 => S3StoreRegionType::DoSgp1, S3StoreRegion::DoFra1 => S3StoreRegionType::DoFra1, S3StoreRegion::Yandex => S3StoreRegionType::Yandex, S3StoreRegion::WaUsEast1 => S3StoreRegionType::WaUsEast1, S3StoreRegion::WaUsEast2 => S3StoreRegionType::WaUsEast2, S3StoreRegion::WaUsCentral1 => S3StoreRegionType::WaUsCentral1, S3StoreRegion::WaUsWest1 => S3StoreRegionType::WaUsWest1, S3StoreRegion::WaCaCentral1 => S3StoreRegionType::WaCaCentral1, S3StoreRegion::WaEuCentral1 => S3StoreRegionType::WaEuCentral1, S3StoreRegion::WaEuCentral2 => S3StoreRegionType::WaEuCentral2, S3StoreRegion::WaEuWest1 => S3StoreRegionType::WaEuWest1, S3StoreRegion::WaEuWest2 => S3StoreRegionType::WaEuWest2, S3StoreRegion::WaApNortheast1 => S3StoreRegionType::WaApNortheast1, S3StoreRegion::WaApNortheast2 => S3StoreRegionType::WaApNortheast2, S3StoreRegion::WaApSoutheast1 => S3StoreRegionType::WaApSoutheast1, S3StoreRegion::WaApSoutheast2 => S3StoreRegionType::WaApSoutheast2, S3StoreRegion::Custom(_) => S3StoreRegionType::Custom, } } } impl ObjectImpl for Search { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Search; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.index_batch_size; if *value < 1 { errors.push(ValidationError::min_value(Property::IndexBatchSize, 1)); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for Search { fn pickle(&self, out: &mut Vec) { self.index_batch_size.pickle(out); self.default_language.pickle(out); self.supported_languages.pickle(out); self.index_calendar.pickle(out); self.index_calendar_fields.pickle(out); self.index_contacts.pickle(out); self.index_contact_fields.pickle(out); self.index_email.pickle(out); self.index_email_fields.pickle(out); self.index_telemetry.pickle(out); self.index_tracing_fields.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.index_batch_size = Pickle::unpickle(stream)?; this.default_language = Pickle::unpickle(stream)?; this.supported_languages = Pickle::unpickle(stream)?; this.index_calendar = Pickle::unpickle(stream)?; this.index_calendar_fields = Pickle::unpickle(stream)?; this.index_contacts = Pickle::unpickle(stream)?; this.index_contact_fields = Pickle::unpickle(stream)?; this.index_email = Pickle::unpickle(stream)?; this.index_email_fields = Pickle::unpickle(stream)?; this.index_telemetry = Pickle::unpickle(stream)?; this.index_tracing_fields = Pickle::unpickle(stream)?; Some(this) } } impl Default for Search { fn default() -> Self { Self { index_batch_size: 100u64, default_language: Locale::EnUS, supported_languages: Map::new(vec![Locale::EnUS]), index_calendar: true, index_calendar_fields: Map::new(vec![ SearchCalendarField::Title, SearchCalendarField::Description, SearchCalendarField::Location, SearchCalendarField::Owner, SearchCalendarField::Attendee, SearchCalendarField::Start, SearchCalendarField::Uid, ]), index_contacts: true, index_contact_fields: Map::new(vec![ SearchContactField::Member, SearchContactField::Kind, SearchContactField::Name, SearchContactField::Nickname, SearchContactField::Organization, SearchContactField::Email, SearchContactField::Phone, SearchContactField::OnlineService, SearchContactField::Address, SearchContactField::Note, SearchContactField::Uid, ]), index_email: true, index_email_fields: Map::new(vec![ SearchEmailField::From, SearchEmailField::To, SearchEmailField::Cc, SearchEmailField::Bcc, SearchEmailField::Subject, SearchEmailField::Body, SearchEmailField::Attachment, SearchEmailField::ReceivedAt, SearchEmailField::SentAt, SearchEmailField::Size, SearchEmailField::HasAttachment, ]), index_telemetry: true, index_tracing_fields: Map::new(vec![ SearchTracingField::EventType, SearchTracingField::QueueId, SearchTracingField::Keywords, ]), } } } impl IntoValue for Search { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(13); map.insert_unchecked(Property::IndexBatchSize, self.index_batch_size.into_value()); map.insert_unchecked( Property::DefaultLanguage, self.default_language.into_value(), ); map.insert_unchecked( Property::SupportedLanguages, self.supported_languages.into_value(), ); map.insert_unchecked(Property::IndexCalendar, self.index_calendar.into_value()); map.insert_unchecked( Property::IndexCalendarFields, self.index_calendar_fields.into_value(), ); map.insert_unchecked(Property::IndexContacts, self.index_contacts.into_value()); map.insert_unchecked( Property::IndexContactFields, self.index_contact_fields.into_value(), ); map.insert_unchecked(Property::IndexEmail, self.index_email.into_value()); map.insert_unchecked( Property::IndexEmailFields, self.index_email_fields.into_value(), ); map.insert_unchecked(Property::IndexTelemetry, self.index_telemetry.into_value()); map.insert_unchecked( Property::IndexTracingFields, self.index_tracing_fields.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Search { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::IndexBatchSize) => self.index_batch_size.patch(pointer, value), Some(Property::DefaultLanguage) => self.default_language.patch(pointer, value), Some(Property::SupportedLanguages) => self.supported_languages.patch(pointer, value), Some(Property::IndexCalendar) => self.index_calendar.patch(pointer, value), Some(Property::IndexCalendarFields) => self.index_calendar_fields.patch(pointer, value), Some(Property::IndexContacts) => self.index_contacts.patch(pointer, value), Some(Property::IndexContactFields) => self.index_contact_fields.patch(pointer, value), Some(Property::IndexEmail) => self.index_email.patch(pointer, value), Some(Property::IndexEmailFields) => self.index_email_fields.patch(pointer, value), Some(Property::IndexTelemetry) => self.index_telemetry.patch(pointer, value), Some(Property::IndexTracingFields) => self.index_tracing_fields.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SearchStore { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SearchStore; fn validate(&self, errors: &mut Vec) -> bool { match self { SearchStore::Default => true, SearchStore::ElasticSearch(inner) => inner.validate(errors), SearchStore::Meilisearch(inner) => inner.validate(errors), SearchStore::FoundationDb(inner) => inner.validate(errors), SearchStore::PostgreSql(inner) => inner.validate(errors), SearchStore::MySql(inner) => inner.validate(errors), } } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Default for SearchStore { fn default() -> Self { SearchStore::Default } } impl Pickle for SearchStore { fn pickle(&self, out: &mut Vec) { match self { SearchStore::Default => { 0u16.pickle(out); } SearchStore::ElasticSearch(inner) => { 1u16.pickle(out); inner.pickle(out); } SearchStore::Meilisearch(inner) => { 2u16.pickle(out); inner.pickle(out); } SearchStore::FoundationDb(inner) => { 3u16.pickle(out); inner.pickle(out); } SearchStore::PostgreSql(inner) => { 4u16.pickle(out); inner.pickle(out); } SearchStore::MySql(inner) => { 5u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(SearchStore::Default), 1 => Pickle::unpickle(stream).map(SearchStore::ElasticSearch), 2 => Pickle::unpickle(stream).map(SearchStore::Meilisearch), 3 => Pickle::unpickle(stream).map(SearchStore::FoundationDb), 4 => Pickle::unpickle(stream).map(SearchStore::PostgreSql), 5 => Pickle::unpickle(stream).map(SearchStore::MySql), _ => None, } } } impl IntoValue for SearchStore { fn into_value(self) -> JmapValue<'static> { match self { SearchStore::Default => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Default".into())); JmapValue::Object(obj) } SearchStore::ElasticSearch(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("ElasticSearch".into())); obj } SearchStore::Meilisearch(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Meilisearch".into())); obj } SearchStore::FoundationDb(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("FoundationDb".into())); obj } SearchStore::PostgreSql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("PostgreSql".into())); obj } SearchStore::MySql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("MySql".into())); obj } } } } impl RegistryJsonPatch for SearchStore { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { SearchStoreType::Default => *self = SearchStore::Default, SearchStoreType::ElasticSearch => { *self = SearchStore::ElasticSearch(Default::default()) } SearchStoreType::Meilisearch => { *self = SearchStore::Meilisearch(Default::default()) } SearchStoreType::FoundationDb => { *self = SearchStore::FoundationDb(Default::default()) } SearchStoreType::PostgreSql => *self = SearchStore::PostgreSql(Default::default()), SearchStoreType::MySql => *self = SearchStore::MySql(Default::default()), } } match self { SearchStore::Default => pointer.assert_eof(), SearchStore::ElasticSearch(inner) => inner.patch(pointer, value), SearchStore::Meilisearch(inner) => inner.patch(pointer, value), SearchStore::FoundationDb(inner) => inner.patch(pointer, value), SearchStore::PostgreSql(inner) => inner.patch(pointer, value), SearchStore::MySql(inner) => inner.patch(pointer, value), } } } impl SearchStore { pub fn object_type(&self) -> SearchStoreType { match self { SearchStore::Default => SearchStoreType::Default, SearchStore::ElasticSearch(_) => SearchStoreType::ElasticSearch, SearchStore::Meilisearch(_) => SearchStoreType::Meilisearch, SearchStore::FoundationDb(_) => SearchStoreType::FoundationDb, SearchStore::PostgreSql(_) => SearchStoreType::PostgreSql, SearchStore::MySql(_) => SearchStoreType::MySql, } } } impl SecondaryCredential { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.credential_id; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CredentialId, value)); } let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } let value = &self.secret; if value.is_empty() { errors.push(ValidationError::required(Property::Secret)); } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } if let Some(value) = &self.expires_at { if !value.is_valid() { errors.push(ValidationError::invalid(Property::ExpiresAt, value)); } } let value = &self.permissions; value.validate(errors); let value = &self.allowed_ips; for value in value.iter() { if !value.is_valid() { errors.push(ValidationError::invalid(Property::AllowedIps, value)); } } errors.len() == neb } } impl Pickle for SecondaryCredential { fn pickle(&self, out: &mut Vec) { self.credential_id.pickle(out); self.description.pickle(out); self.secret.pickle(out); self.created_at.pickle(out); self.expires_at.pickle(out); self.permissions.pickle(out); self.allowed_ips.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.credential_id = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.secret = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.expires_at = Pickle::unpickle(stream)?; this.permissions = Pickle::unpickle(stream)?; this.allowed_ips = Pickle::unpickle(stream)?; Some(this) } } impl Default for SecondaryCredential { fn default() -> Self { Self { credential_id: Default::default(), description: Default::default(), secret: Default::default(), created_at: Default::default(), expires_at: Default::default(), permissions: Default::default(), allowed_ips: Default::default(), } } } impl IntoValue for SecondaryCredential { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked(Property::CredentialId, self.credential_id.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Secret, JmapValue::Str(MASKED_PASSWORD.into())); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::ExpiresAt, self.expires_at.into_value()); map.insert_unchecked(Property::Permissions, self.permissions.into_value()); map.insert_unchecked(Property::AllowedIps, self.allowed_ips.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SecondaryCredential { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::CredentialId) => pointer.assert_server_set(), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Secret) => pointer.assert_server_set(), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::ExpiresAt) => self.expires_at.patch(pointer, value), Some(Property::Permissions) => self.permissions.patch(pointer, value), Some(Property::AllowedIps) => self.allowed_ips.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SecretKey { fn validate(&self, errors: &mut Vec) -> bool { match self { SecretKey::Value(inner) => inner.validate(errors), SecretKey::EnvironmentVariable(inner) => inner.validate(errors), SecretKey::File(inner) => inner.validate(errors), } } } impl Default for SecretKey { fn default() -> Self { SecretKey::Value(Default::default()) } } impl Pickle for SecretKey { fn pickle(&self, out: &mut Vec) { match self { SecretKey::Value(inner) => { 0u16.pickle(out); inner.pickle(out); } SecretKey::EnvironmentVariable(inner) => { 1u16.pickle(out); inner.pickle(out); } SecretKey::File(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(SecretKey::Value), 1 => Pickle::unpickle(stream).map(SecretKey::EnvironmentVariable), 2 => Pickle::unpickle(stream).map(SecretKey::File), _ => None, } } } impl IntoValue for SecretKey { fn into_value(self) -> JmapValue<'static> { match self { SecretKey::Value(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Value".into())); obj } SecretKey::EnvironmentVariable(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("EnvironmentVariable".into())); obj } SecretKey::File(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("File".into())); obj } } } } impl RegistryJsonPatch for SecretKey { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { SecretKeyType::Value => *self = SecretKey::Value(Default::default()), SecretKeyType::EnvironmentVariable => { *self = SecretKey::EnvironmentVariable(Default::default()) } SecretKeyType::File => *self = SecretKey::File(Default::default()), } } match self { SecretKey::Value(inner) => inner.patch(pointer, value), SecretKey::EnvironmentVariable(inner) => inner.patch(pointer, value), SecretKey::File(inner) => inner.patch(pointer, value), } } } impl SecretKey { pub fn object_type(&self) -> SecretKeyType { match self { SecretKey::Value(_) => SecretKeyType::Value, SecretKey::EnvironmentVariable(_) => SecretKeyType::EnvironmentVariable, SecretKey::File(_) => SecretKeyType::File, } } } impl SecretKeyEnvironmentVariable { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.variable_name; if value.is_empty() { errors.push(ValidationError::required(Property::VariableName)); } errors.len() == neb } } impl Pickle for SecretKeyEnvironmentVariable { fn pickle(&self, out: &mut Vec) { self.variable_name.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.variable_name = Pickle::unpickle(stream)?; Some(this) } } impl Default for SecretKeyEnvironmentVariable { fn default() -> Self { Self { variable_name: Default::default(), } } } impl IntoValue for SecretKeyEnvironmentVariable { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::VariableName, self.variable_name.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SecretKeyEnvironmentVariable { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::VariableName) => self.variable_name.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SecretKeyFile { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.file_path; if value.is_empty() { errors.push(ValidationError::required(Property::FilePath)); } errors.len() == neb } } impl Pickle for SecretKeyFile { fn pickle(&self, out: &mut Vec) { self.file_path.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.file_path = Pickle::unpickle(stream)?; Some(this) } } impl Default for SecretKeyFile { fn default() -> Self { Self { file_path: Default::default(), } } } impl IntoValue for SecretKeyFile { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::FilePath, self.file_path.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SecretKeyFile { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::FilePath) => self.file_path.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SecretKeyOptional { fn validate(&self, errors: &mut Vec) -> bool { match self { SecretKeyOptional::None => true, SecretKeyOptional::Value(inner) => inner.validate(errors), SecretKeyOptional::EnvironmentVariable(inner) => inner.validate(errors), SecretKeyOptional::File(inner) => inner.validate(errors), } } } impl Default for SecretKeyOptional { fn default() -> Self { SecretKeyOptional::None } } impl Pickle for SecretKeyOptional { fn pickle(&self, out: &mut Vec) { match self { SecretKeyOptional::None => { 0u16.pickle(out); } SecretKeyOptional::Value(inner) => { 1u16.pickle(out); inner.pickle(out); } SecretKeyOptional::EnvironmentVariable(inner) => { 2u16.pickle(out); inner.pickle(out); } SecretKeyOptional::File(inner) => { 3u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(SecretKeyOptional::None), 1 => Pickle::unpickle(stream).map(SecretKeyOptional::Value), 2 => Pickle::unpickle(stream).map(SecretKeyOptional::EnvironmentVariable), 3 => Pickle::unpickle(stream).map(SecretKeyOptional::File), _ => None, } } } impl IntoValue for SecretKeyOptional { fn into_value(self) -> JmapValue<'static> { match self { SecretKeyOptional::None => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("None".into())); JmapValue::Object(obj) } SecretKeyOptional::Value(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Value".into())); obj } SecretKeyOptional::EnvironmentVariable(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("EnvironmentVariable".into())); obj } SecretKeyOptional::File(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("File".into())); obj } } } } impl RegistryJsonPatch for SecretKeyOptional { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { SecretKeyOptionalType::None => *self = SecretKeyOptional::None, SecretKeyOptionalType::Value => { *self = SecretKeyOptional::Value(Default::default()) } SecretKeyOptionalType::EnvironmentVariable => { *self = SecretKeyOptional::EnvironmentVariable(Default::default()) } SecretKeyOptionalType::File => *self = SecretKeyOptional::File(Default::default()), } } match self { SecretKeyOptional::None => pointer.assert_eof(), SecretKeyOptional::Value(inner) => inner.patch(pointer, value), SecretKeyOptional::EnvironmentVariable(inner) => inner.patch(pointer, value), SecretKeyOptional::File(inner) => inner.patch(pointer, value), } } } impl SecretKeyOptional { pub fn object_type(&self) -> SecretKeyOptionalType { match self { SecretKeyOptional::None => SecretKeyOptionalType::None, SecretKeyOptional::Value(_) => SecretKeyOptionalType::Value, SecretKeyOptional::EnvironmentVariable(_) => SecretKeyOptionalType::EnvironmentVariable, SecretKeyOptional::File(_) => SecretKeyOptionalType::File, } } } impl SecretKeyValue { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.secret; if value.is_empty() { errors.push(ValidationError::required(Property::Secret)); } errors.len() == neb } } impl Pickle for SecretKeyValue { fn pickle(&self, out: &mut Vec) { self.secret.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.secret = Pickle::unpickle(stream)?; Some(this) } } impl Default for SecretKeyValue { fn default() -> Self { Self { secret: Default::default(), } } } impl IntoValue for SecretKeyValue { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Secret, JmapValue::Str(MASKED_PASSWORD.into())); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SecretKeyValue { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Secret) => self.secret.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SecretText { fn validate(&self, errors: &mut Vec) -> bool { match self { SecretText::Text(inner) => inner.validate(errors), SecretText::EnvironmentVariable(inner) => inner.validate(errors), SecretText::File(inner) => inner.validate(errors), } } } impl Default for SecretText { fn default() -> Self { SecretText::Text(Default::default()) } } impl Pickle for SecretText { fn pickle(&self, out: &mut Vec) { match self { SecretText::Text(inner) => { 0u16.pickle(out); inner.pickle(out); } SecretText::EnvironmentVariable(inner) => { 1u16.pickle(out); inner.pickle(out); } SecretText::File(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(SecretText::Text), 1 => Pickle::unpickle(stream).map(SecretText::EnvironmentVariable), 2 => Pickle::unpickle(stream).map(SecretText::File), _ => None, } } } impl IntoValue for SecretText { fn into_value(self) -> JmapValue<'static> { match self { SecretText::Text(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Text".into())); obj } SecretText::EnvironmentVariable(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("EnvironmentVariable".into())); obj } SecretText::File(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("File".into())); obj } } } } impl RegistryJsonPatch for SecretText { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { SecretTextType::Text => *self = SecretText::Text(Default::default()), SecretTextType::EnvironmentVariable => { *self = SecretText::EnvironmentVariable(Default::default()) } SecretTextType::File => *self = SecretText::File(Default::default()), } } match self { SecretText::Text(inner) => inner.patch(pointer, value), SecretText::EnvironmentVariable(inner) => inner.patch(pointer, value), SecretText::File(inner) => inner.patch(pointer, value), } } } impl SecretText { pub fn object_type(&self) -> SecretTextType { match self { SecretText::Text(_) => SecretTextType::Text, SecretText::EnvironmentVariable(_) => SecretTextType::EnvironmentVariable, SecretText::File(_) => SecretTextType::File, } } } impl SecretTextOptional { fn validate(&self, errors: &mut Vec) -> bool { match self { SecretTextOptional::None => true, SecretTextOptional::Text(inner) => inner.validate(errors), SecretTextOptional::EnvironmentVariable(inner) => inner.validate(errors), SecretTextOptional::File(inner) => inner.validate(errors), } } } impl Default for SecretTextOptional { fn default() -> Self { SecretTextOptional::None } } impl Pickle for SecretTextOptional { fn pickle(&self, out: &mut Vec) { match self { SecretTextOptional::None => { 0u16.pickle(out); } SecretTextOptional::Text(inner) => { 1u16.pickle(out); inner.pickle(out); } SecretTextOptional::EnvironmentVariable(inner) => { 2u16.pickle(out); inner.pickle(out); } SecretTextOptional::File(inner) => { 3u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(SecretTextOptional::None), 1 => Pickle::unpickle(stream).map(SecretTextOptional::Text), 2 => Pickle::unpickle(stream).map(SecretTextOptional::EnvironmentVariable), 3 => Pickle::unpickle(stream).map(SecretTextOptional::File), _ => None, } } } impl IntoValue for SecretTextOptional { fn into_value(self) -> JmapValue<'static> { match self { SecretTextOptional::None => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("None".into())); JmapValue::Object(obj) } SecretTextOptional::Text(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Text".into())); obj } SecretTextOptional::EnvironmentVariable(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("EnvironmentVariable".into())); obj } SecretTextOptional::File(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("File".into())); obj } } } } impl RegistryJsonPatch for SecretTextOptional { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { SecretTextOptionalType::None => *self = SecretTextOptional::None, SecretTextOptionalType::Text => { *self = SecretTextOptional::Text(Default::default()) } SecretTextOptionalType::EnvironmentVariable => { *self = SecretTextOptional::EnvironmentVariable(Default::default()) } SecretTextOptionalType::File => { *self = SecretTextOptional::File(Default::default()) } } } match self { SecretTextOptional::None => pointer.assert_eof(), SecretTextOptional::Text(inner) => inner.patch(pointer, value), SecretTextOptional::EnvironmentVariable(inner) => inner.patch(pointer, value), SecretTextOptional::File(inner) => inner.patch(pointer, value), } } } impl SecretTextOptional { pub fn object_type(&self) -> SecretTextOptionalType { match self { SecretTextOptional::None => SecretTextOptionalType::None, SecretTextOptional::Text(_) => SecretTextOptionalType::Text, SecretTextOptional::EnvironmentVariable(_) => { SecretTextOptionalType::EnvironmentVariable } SecretTextOptional::File(_) => SecretTextOptionalType::File, } } } impl SecretTextValue { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.secret; if value.is_empty() { errors.push(ValidationError::required(Property::Secret)); } errors.len() == neb } } impl Pickle for SecretTextValue { fn pickle(&self, out: &mut Vec) { self.secret.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.secret = Pickle::unpickle(stream)?; Some(this) } } impl Default for SecretTextValue { fn default() -> Self { Self { secret: Default::default(), } } } impl IntoValue for SecretTextValue { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Secret, JmapValue::Str(MASKED_PASSWORD.into())); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SecretTextValue { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Secret) => self.secret.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Security { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Security; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.abuse_ban_rate { value.validate(errors); } if let Some(value) = &self.auth_ban_rate { value.validate(errors); } if let Some(value) = &self.loiter_ban_rate { value.validate(errors); } let value = &self.scan_ban_paths; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::ScanBanPaths)); } } if let Some(value) = &self.scan_ban_rate { value.validate(errors); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for Security { fn pickle(&self, out: &mut Vec) { self.abuse_ban_rate.pickle(out); self.abuse_ban_period.pickle(out); self.auth_ban_rate.pickle(out); self.auth_ban_period.pickle(out); self.loiter_ban_rate.pickle(out); self.loiter_ban_period.pickle(out); self.scan_ban_paths.pickle(out); self.scan_ban_rate.pickle(out); self.scan_ban_period.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.abuse_ban_rate = Pickle::unpickle(stream)?; this.abuse_ban_period = Pickle::unpickle(stream)?; this.auth_ban_rate = Pickle::unpickle(stream)?; this.auth_ban_period = Pickle::unpickle(stream)?; this.loiter_ban_rate = Pickle::unpickle(stream)?; this.loiter_ban_period = Pickle::unpickle(stream)?; this.scan_ban_paths = Pickle::unpickle(stream)?; this.scan_ban_rate = Pickle::unpickle(stream)?; this.scan_ban_period = Pickle::unpickle(stream)?; Some(this) } } impl Default for Security { fn default() -> Self { Self { abuse_ban_rate: Some(Rate { count: 35u64, period: Duration::from_millis(86400000), }), abuse_ban_period: Default::default(), auth_ban_rate: Some(Rate { count: 100u64, period: Duration::from_millis(86400000), }), auth_ban_period: Default::default(), loiter_ban_rate: Some(Rate { count: 150u64, period: Duration::from_millis(86400000), }), loiter_ban_period: Default::default(), scan_ban_paths: Map::new(vec![ "*.php*".to_string(), "*.cgi*".to_string(), "*.asp*".to_string(), "*/wp-*".to_string(), "*/php*".to_string(), "*/cgi-bin*".to_string(), "*xmlrpc*".to_string(), "*../*".to_string(), "*/..*".to_string(), "*joomla*".to_string(), "*wordpress*".to_string(), "*drupal*".to_string(), ]), scan_ban_rate: Some(Rate { count: 30u64, period: Duration::from_millis(86400000), }), scan_ban_period: Default::default(), } } } impl IntoValue for Security { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::AbuseBanRate, self.abuse_ban_rate.into_value()); map.insert_unchecked(Property::AbuseBanPeriod, self.abuse_ban_period.into_value()); map.insert_unchecked(Property::AuthBanRate, self.auth_ban_rate.into_value()); map.insert_unchecked(Property::AuthBanPeriod, self.auth_ban_period.into_value()); map.insert_unchecked(Property::LoiterBanRate, self.loiter_ban_rate.into_value()); map.insert_unchecked( Property::LoiterBanPeriod, self.loiter_ban_period.into_value(), ); map.insert_unchecked(Property::ScanBanPaths, self.scan_ban_paths.into_value()); map.insert_unchecked(Property::ScanBanRate, self.scan_ban_rate.into_value()); map.insert_unchecked(Property::ScanBanPeriod, self.scan_ban_period.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Security { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AbuseBanRate) => self.abuse_ban_rate.patch(pointer, value), Some(Property::AbuseBanPeriod) => self.abuse_ban_period.patch(pointer, value), Some(Property::AuthBanRate) => self.auth_ban_rate.patch(pointer, value), Some(Property::AuthBanPeriod) => self.auth_ban_period.patch(pointer, value), Some(Property::LoiterBanRate) => self.loiter_ban_rate.patch(pointer, value), Some(Property::LoiterBanPeriod) => self.loiter_ban_period.patch(pointer, value), Some(Property::ScanBanPaths) => self .scan_ban_paths .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ScanBanRate) => self.scan_ban_rate.patch(pointer, value), Some(Property::ScanBanPeriod) => self.scan_ban_period.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SenderAuth { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SenderAuth; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.dkim_sign_domain; value.validate(errors); let value = &self.dkim_verify; value.validate(errors); let value = &self.spf_ehlo_verify; value.validate(errors); let value = &self.spf_from_verify; value.validate(errors); let value = &self.arc_verify; value.validate(errors); let value = &self.dmarc_verify; value.validate(errors); let value = &self.reverse_ip_verify; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl SenderAuth { pub fn ctx_dkim_sign_domain(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.dkim_sign_domain, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "is_local_domain(sender_domain) && !is_empty(authenticated_as)" .to_string(), then: "sender_domain".to_string(), }]), }), property: Property::DkimSignDomain, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_dkim_verify(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.dkim_verify, default: Some(Expression { else_: "relaxed".to_string(), match_: List::from_iter([]), }), property: Property::DkimVerify, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: MTA_VERIFY_CONSTANT, } } pub fn ctx_spf_ehlo_verify(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.spf_ehlo_verify, default: Some(Expression { else_: "disable".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "relaxed".to_string(), }]), }), property: Property::SpfEhloVerify, allowed_variables: MTA_CONNECTION_VARIABLE, allowed_constants: MTA_VERIFY_CONSTANT, } } pub fn ctx_spf_from_verify(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.spf_from_verify, default: Some(Expression { else_: "disable".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "relaxed".to_string(), }]), }), property: Property::SpfFromVerify, allowed_variables: MTA_CONNECTION_VARIABLE, allowed_constants: MTA_VERIFY_CONSTANT, } } pub fn ctx_arc_verify(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.arc_verify, default: Some(Expression { else_: "disable".to_string(), match_: List::from_iter([]), }), property: Property::ArcVerify, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: MTA_VERIFY_CONSTANT, } } pub fn ctx_dmarc_verify(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.dmarc_verify, default: Some(Expression { else_: "disable".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "relaxed".to_string(), }]), }), property: Property::DmarcVerify, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: MTA_VERIFY_CONSTANT, } } pub fn ctx_reverse_ip_verify(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.reverse_ip_verify, default: Some(Expression { else_: "disable".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "relaxed".to_string(), }]), }), property: Property::ReverseIpVerify, allowed_variables: MTA_CONNECTION_VARIABLE, allowed_constants: MTA_VERIFY_CONSTANT, } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_dkim_sign_domain(), self.ctx_dkim_verify(), self.ctx_spf_ehlo_verify(), self.ctx_spf_from_verify(), self.ctx_arc_verify(), self.ctx_dmarc_verify(), self.ctx_reverse_ip_verify(), ] } } impl Pickle for SenderAuth { fn pickle(&self, out: &mut Vec) { self.dkim_sign_domain.pickle(out); self.dkim_strict.pickle(out); self.dkim_verify.pickle(out); self.spf_ehlo_verify.pickle(out); self.spf_from_verify.pickle(out); self.arc_verify.pickle(out); self.dmarc_verify.pickle(out); self.reverse_ip_verify.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.dkim_sign_domain = Pickle::unpickle(stream)?; this.dkim_strict = Pickle::unpickle(stream)?; this.dkim_verify = Pickle::unpickle(stream)?; this.spf_ehlo_verify = Pickle::unpickle(stream)?; this.spf_from_verify = Pickle::unpickle(stream)?; this.arc_verify = Pickle::unpickle(stream)?; this.dmarc_verify = Pickle::unpickle(stream)?; this.reverse_ip_verify = Pickle::unpickle(stream)?; Some(this) } } impl Default for SenderAuth { fn default() -> Self { Self { dkim_sign_domain: Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "is_local_domain(sender_domain) && !is_empty(authenticated_as)" .to_string(), then: "sender_domain".to_string(), }]), }, dkim_strict: true, dkim_verify: Expression { else_: "relaxed".to_string(), match_: List::from_iter([]), }, spf_ehlo_verify: Expression { else_: "disable".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "relaxed".to_string(), }]), }, spf_from_verify: Expression { else_: "disable".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "relaxed".to_string(), }]), }, arc_verify: Expression { else_: "disable".to_string(), match_: List::from_iter([]), }, dmarc_verify: Expression { else_: "disable".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "relaxed".to_string(), }]), }, reverse_ip_verify: Expression { else_: "disable".to_string(), match_: List::from_iter([ExpressionMatch { if_: "local_port == 25".to_string(), then: "relaxed".to_string(), }]), }, } } } impl IntoValue for SenderAuth { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(10); map.insert_unchecked(Property::DkimSignDomain, self.dkim_sign_domain.into_value()); map.insert_unchecked(Property::DkimStrict, self.dkim_strict.into_value()); map.insert_unchecked(Property::DkimVerify, self.dkim_verify.into_value()); map.insert_unchecked(Property::SpfEhloVerify, self.spf_ehlo_verify.into_value()); map.insert_unchecked(Property::SpfFromVerify, self.spf_from_verify.into_value()); map.insert_unchecked(Property::ArcVerify, self.arc_verify.into_value()); map.insert_unchecked(Property::DmarcVerify, self.dmarc_verify.into_value()); map.insert_unchecked( Property::ReverseIpVerify, self.reverse_ip_verify.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SenderAuth { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::DkimSignDomain) => self.dkim_sign_domain.patch(pointer, value), Some(Property::DkimStrict) => self.dkim_strict.patch(pointer, value), Some(Property::DkimVerify) => self.dkim_verify.patch(pointer, value), Some(Property::SpfEhloVerify) => self.spf_ehlo_verify.patch(pointer, value), Some(Property::SpfFromVerify) => self.spf_from_verify.patch(pointer, value), Some(Property::ArcVerify) => self.arc_verify.patch(pointer, value), Some(Property::DmarcVerify) => self.dmarc_verify.patch(pointer, value), Some(Property::ReverseIpVerify) => self.reverse_ip_verify.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ServerResponse { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.response_hostname { if value.is_empty() { errors.push(ValidationError::required(Property::ResponseHostname)); } } if let Some(value) = &self.response_code { if *value < 100 { errors.push(ValidationError::min_value(Property::ResponseCode, 100)); } if *value > 599 { errors.push(ValidationError::max_value(Property::ResponseCode, 599)); } } if let Some(value) = &self.response_enhanced { if value.is_empty() { errors.push(ValidationError::required(Property::ResponseEnhanced)); } } if let Some(value) = &self.response_message { if value.is_empty() { errors.push(ValidationError::required(Property::ResponseMessage)); } } errors.len() == neb } } impl Pickle for ServerResponse { fn pickle(&self, out: &mut Vec) { self.response_hostname.pickle(out); self.response_code.pickle(out); self.response_enhanced.pickle(out); self.response_message.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.response_hostname = Pickle::unpickle(stream)?; this.response_code = Pickle::unpickle(stream)?; this.response_enhanced = Pickle::unpickle(stream)?; this.response_message = Pickle::unpickle(stream)?; Some(this) } } impl Default for ServerResponse { fn default() -> Self { Self { response_hostname: Default::default(), response_code: Default::default(), response_enhanced: Default::default(), response_message: Default::default(), } } } impl IntoValue for ServerResponse { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked( Property::ResponseHostname, self.response_hostname.into_value(), ); map.insert_unchecked(Property::ResponseCode, self.response_code.into_value()); map.insert_unchecked( Property::ResponseEnhanced, self.response_enhanced.into_value(), ); map.insert_unchecked( Property::ResponseMessage, self.response_message.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ServerResponse { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ResponseHostname) => self.response_hostname.patch(pointer, value), Some(Property::ResponseCode) => self.response_code.patch(pointer, value), Some(Property::ResponseEnhanced) => self.response_enhanced.patch(pointer, value), Some(Property::ResponseMessage) => self.response_message.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl Service { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.hostname { if value.is_empty() { errors.push(ValidationError::required(Property::Hostname)); } } errors.len() == neb } } impl Pickle for Service { fn pickle(&self, out: &mut Vec) { self.hostname.pickle(out); self.cleartext.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.hostname = Pickle::unpickle(stream)?; this.cleartext = Pickle::unpickle(stream)?; Some(this) } } impl Default for Service { fn default() -> Self { Self { hostname: Default::default(), cleartext: false, } } } impl IntoValue for Service { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Hostname, self.hostname.into_value()); map.insert_unchecked(Property::Cleartext, self.cleartext.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Service { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Hostname) => self .hostname .patch(pointer.with_validators(&[StringValidator::Hostname]), value), Some(Property::Cleartext) => self.cleartext.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ShardedBlobStore { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.stores; for value in value.values() { value.validate(errors); } if value.len() < 2 { errors.push(ValidationError::min_items(Property::Stores, 2)); } errors.len() == neb } } impl Pickle for ShardedBlobStore { fn pickle(&self, out: &mut Vec) { self.stores.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.stores = Pickle::unpickle(stream)?; Some(this) } } impl Default for ShardedBlobStore { fn default() -> Self { Self { stores: Default::default(), } } } impl IntoValue for ShardedBlobStore { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Stores, self.stores.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ShardedBlobStore { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Stores) => self.stores.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ShardedInMemoryStore { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.stores; for value in value.values() { value.validate(errors); } if value.len() < 2 { errors.push(ValidationError::min_items(Property::Stores, 2)); } errors.len() == neb } } impl Pickle for ShardedInMemoryStore { fn pickle(&self, out: &mut Vec) { self.stores.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.stores = Pickle::unpickle(stream)?; Some(this) } } impl Default for ShardedInMemoryStore { fn default() -> Self { Self { stores: Default::default(), } } } impl IntoValue for ShardedInMemoryStore { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Stores, self.stores.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ShardedInMemoryStore { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Stores) => self.stores.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Sharing { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Sharing; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.max_shares; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxShares, 1)); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for Sharing { fn pickle(&self, out: &mut Vec) { self.allow_directory_queries.pickle(out); self.max_shares.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.allow_directory_queries = Pickle::unpickle(stream)?; this.max_shares = Pickle::unpickle(stream)?; Some(this) } } impl Default for Sharing { fn default() -> Self { Self { allow_directory_queries: false, max_shares: 10u64, } } } impl IntoValue for Sharing { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked( Property::AllowDirectoryQueries, self.allow_directory_queries.into_value(), ); map.insert_unchecked(Property::MaxShares, self.max_shares.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Sharing { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AllowDirectoryQueries) => { self.allow_directory_queries.patch(pointer, value) } Some(Property::MaxShares) => self.max_shares.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SieveSystemInterpreter { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SieveSystemInterpreter; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.default_from_address; value.validate(errors); let value = &self.default_from_name; value.validate(errors); if let Some(value) = &self.message_id_hostname { if value.is_empty() { errors.push(ValidationError::required(Property::MessageIdHostname)); } } let value = &self.default_return_path; if !value.match_.is_empty() || !value.else_.is_empty() { value.validate(errors); } let value = &self.dkim_sign_domain; value.validate(errors); let value = &self.max_cpu_cycles; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxCpuCycles, 1)); } let value = &self.max_nested_includes; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxNestedIncludes, 1)); } let value = &self.max_received_headers; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxReceivedHeaders, 1)); } let value = &self.max_var_size; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxVarSize, 1)); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl SieveSystemInterpreter { pub fn ctx_default_from_address(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.default_from_address, default: Some(Expression { else_: "'MAILER-DAEMON@' + system('domain')".to_string(), ..Default::default() }), property: Property::DefaultFromAddress, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_default_from_name(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.default_from_name, default: Some(Expression { else_: "'Automated Message'".to_string(), ..Default::default() }), property: Property::DefaultFromName, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_default_return_path(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.default_return_path, default: None, property: Property::DefaultReturnPath, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn ctx_dkim_sign_domain(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.dkim_sign_domain, default: Some(Expression { else_: "system('domain')".to_string(), ..Default::default() }), property: Property::DkimSignDomain, allowed_variables: MTA_RCPT_TO_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_default_from_address(), self.ctx_default_from_name(), self.ctx_default_return_path(), self.ctx_dkim_sign_domain(), ] } } impl Pickle for SieveSystemInterpreter { fn pickle(&self, out: &mut Vec) { self.default_from_address.pickle(out); self.default_from_name.pickle(out); self.message_id_hostname.pickle(out); self.duplicate_expiry.pickle(out); self.no_capability_check.pickle(out); self.default_return_path.pickle(out); self.dkim_sign_domain.pickle(out); self.max_cpu_cycles.pickle(out); self.max_nested_includes.pickle(out); self.max_out_messages.pickle(out); self.max_received_headers.pickle(out); self.max_redirects.pickle(out); self.max_var_size.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.default_from_address = Pickle::unpickle(stream)?; this.default_from_name = Pickle::unpickle(stream)?; this.message_id_hostname = Pickle::unpickle(stream)?; this.duplicate_expiry = Pickle::unpickle(stream)?; this.no_capability_check = Pickle::unpickle(stream)?; this.default_return_path = Pickle::unpickle(stream)?; this.dkim_sign_domain = Pickle::unpickle(stream)?; this.max_cpu_cycles = Pickle::unpickle(stream)?; this.max_nested_includes = Pickle::unpickle(stream)?; this.max_out_messages = Pickle::unpickle(stream)?; this.max_received_headers = Pickle::unpickle(stream)?; this.max_redirects = Pickle::unpickle(stream)?; this.max_var_size = Pickle::unpickle(stream)?; Some(this) } } impl Default for SieveSystemInterpreter { fn default() -> Self { Self { default_from_address: Expression { else_: "'MAILER-DAEMON@' + system('domain')".to_string(), ..Default::default() }, default_from_name: Expression { else_: "'Automated Message'".to_string(), ..Default::default() }, message_id_hostname: Default::default(), duplicate_expiry: Duration::from_millis(604800000), no_capability_check: true, default_return_path: Default::default(), dkim_sign_domain: Expression { else_: "system('domain')".to_string(), ..Default::default() }, max_cpu_cycles: 1048576u64, max_nested_includes: 5u64, max_out_messages: 5u64, max_received_headers: 50u64, max_redirects: 3u64, max_var_size: 52428800u64, } } } impl IntoValue for SieveSystemInterpreter { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(15); map.insert_unchecked( Property::DefaultFromAddress, self.default_from_address.into_value(), ); map.insert_unchecked( Property::DefaultFromName, self.default_from_name.into_value(), ); map.insert_unchecked( Property::MessageIdHostname, self.message_id_hostname.into_value(), ); map.insert_unchecked( Property::DuplicateExpiry, self.duplicate_expiry.into_value(), ); map.insert_unchecked( Property::NoCapabilityCheck, self.no_capability_check.into_value(), ); map.insert_unchecked( Property::DefaultReturnPath, self.default_return_path.into_value(), ); map.insert_unchecked(Property::DkimSignDomain, self.dkim_sign_domain.into_value()); map.insert_unchecked(Property::MaxCpuCycles, self.max_cpu_cycles.into_value()); map.insert_unchecked( Property::MaxNestedIncludes, self.max_nested_includes.into_value(), ); map.insert_unchecked(Property::MaxOutMessages, self.max_out_messages.into_value()); map.insert_unchecked( Property::MaxReceivedHeaders, self.max_received_headers.into_value(), ); map.insert_unchecked(Property::MaxRedirects, self.max_redirects.into_value()); map.insert_unchecked(Property::MaxVarSize, self.max_var_size.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SieveSystemInterpreter { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::DefaultFromAddress) => self.default_from_address.patch(pointer, value), Some(Property::DefaultFromName) => self.default_from_name.patch(pointer, value), Some(Property::MessageIdHostname) => self .message_id_hostname .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::DuplicateExpiry) => self.duplicate_expiry.patch(pointer, value), Some(Property::NoCapabilityCheck) => self.no_capability_check.patch(pointer, value), Some(Property::DefaultReturnPath) => self.default_return_path.patch(pointer, value), Some(Property::DkimSignDomain) => self.dkim_sign_domain.patch(pointer, value), Some(Property::MaxCpuCycles) => self.max_cpu_cycles.patch(pointer, value), Some(Property::MaxNestedIncludes) => self.max_nested_includes.patch(pointer, value), Some(Property::MaxOutMessages) => self.max_out_messages.patch(pointer, value), Some(Property::MaxReceivedHeaders) => self.max_received_headers.patch(pointer, value), Some(Property::MaxRedirects) => self.max_redirects.patch(pointer, value), Some(Property::MaxVarSize) => self.max_var_size.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SieveSystemScript { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SieveSystemScript; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.contents; if value.is_empty() { errors.push(ValidationError::required(Property::Contents)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl Pickle for SieveSystemScript { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.description.pickle(out); self.is_active.pickle(out); self.contents.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.is_active = Pickle::unpickle(stream)?; this.contents = Pickle::unpickle(stream)?; Some(this) } } impl Default for SieveSystemScript { fn default() -> Self { Self { name: Default::default(), description: Default::default(), is_active: false, contents: Default::default(), } } } impl IntoValue for SieveSystemScript { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::IsActive, self.is_active.into_value()); map.insert_unchecked(Property::Contents, self.contents.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SieveSystemScript { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self .name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::IsActive) => self.is_active.patch(pointer, value), Some(Property::Contents) => self .contents .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SieveUserInterpreter { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 1; const OBJECT: ObjectType = ObjectType::SieveUserInterpreter; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.allowed_notify_uris; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::AllowedNotifyUris)); } } let value = &self.protected_headers; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::ProtectedHeaders)); } } let value = &self.default_subject; if value.is_empty() { errors.push(ValidationError::required(Property::DefaultSubject)); } let value = &self.default_subject_prefix; if value.is_empty() { errors.push(ValidationError::required(Property::DefaultSubjectPrefix)); } let value = &self.max_cpu_cycles; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxCpuCycles, 1)); } let value = &self.max_header_size; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxHeaderSize, 1)); } let value = &self.max_includes; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxIncludes, 1)); } let value = &self.max_local_vars; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxLocalVars, 1)); } let value = &self.max_match_vars; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxMatchVars, 1)); } let value = &self.max_script_name_length; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxScriptNameLength, 1)); } let value = &self.max_nested_blocks; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxNestedBlocks, 1)); } let value = &self.max_nested_for_every; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxNestedForEvery, 1)); } let value = &self.max_nested_includes; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxNestedIncludes, 1)); } let value = &self.max_nested_tests; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxNestedTests, 1)); } let value = &self.max_received_headers; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxReceivedHeaders, 1)); } let value = &self.max_script_size; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxScriptSize, 1)); } let value = &self.max_string_length; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxStringLength, 1)); } let value = &self.max_var_name_length; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxVarNameLength, 1)); } let value = &self.max_var_size; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxVarSize, 1)); } if let Some(value) = &self.max_scripts { if *value < 1 { errors.push(ValidationError::min_value(Property::MaxScripts, 1)); } } let value = &self.dkim_sign_domain; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl SieveUserInterpreter { pub fn ctx_dkim_sign_domain(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.dkim_sign_domain, default: Some(Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "is_local_domain(sender_domain)".to_string(), then: "sender_domain".to_string(), }]), }), property: Property::DkimSignDomain, allowed_variables: MTA_QUEUE_SENDER_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_dkim_sign_domain()] } } impl Pickle for SieveUserInterpreter { fn pickle(&self, out: &mut Vec) { self.default_expiry_duplicate.pickle(out); self.default_expiry_vacation.pickle(out); self.disable_capabilities.pickle(out); self.allowed_notify_uris.pickle(out); self.protected_headers.pickle(out); self.default_subject.pickle(out); self.default_subject_prefix.pickle(out); self.max_cpu_cycles.pickle(out); self.max_header_size.pickle(out); self.max_includes.pickle(out); self.max_local_vars.pickle(out); self.max_match_vars.pickle(out); self.max_script_name_length.pickle(out); self.max_nested_blocks.pickle(out); self.max_nested_for_every.pickle(out); self.max_nested_includes.pickle(out); self.max_nested_tests.pickle(out); self.max_out_messages.pickle(out); self.max_received_headers.pickle(out); self.max_redirects.pickle(out); self.max_script_size.pickle(out); self.max_string_length.pickle(out); self.max_var_name_length.pickle(out); self.max_var_size.pickle(out); self.max_scripts.pickle(out); self.dkim_sign_domain.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.default_expiry_duplicate = Pickle::unpickle(stream)?; this.default_expiry_vacation = Pickle::unpickle(stream)?; this.disable_capabilities = Pickle::unpickle(stream)?; this.allowed_notify_uris = Pickle::unpickle(stream)?; this.protected_headers = Pickle::unpickle(stream)?; this.default_subject = Pickle::unpickle(stream)?; this.default_subject_prefix = Pickle::unpickle(stream)?; this.max_cpu_cycles = Pickle::unpickle(stream)?; this.max_header_size = Pickle::unpickle(stream)?; this.max_includes = Pickle::unpickle(stream)?; this.max_local_vars = Pickle::unpickle(stream)?; this.max_match_vars = Pickle::unpickle(stream)?; this.max_script_name_length = Pickle::unpickle(stream)?; this.max_nested_blocks = Pickle::unpickle(stream)?; this.max_nested_for_every = Pickle::unpickle(stream)?; this.max_nested_includes = Pickle::unpickle(stream)?; this.max_nested_tests = Pickle::unpickle(stream)?; this.max_out_messages = Pickle::unpickle(stream)?; this.max_received_headers = Pickle::unpickle(stream)?; this.max_redirects = Pickle::unpickle(stream)?; this.max_script_size = Pickle::unpickle(stream)?; this.max_string_length = Pickle::unpickle(stream)?; this.max_var_name_length = Pickle::unpickle(stream)?; this.max_var_size = Pickle::unpickle(stream)?; this.max_scripts = Pickle::unpickle(stream)?; if stream.version() >= 1 { this.dkim_sign_domain = Pickle::unpickle(stream)?; } Some(this) } } impl Default for SieveUserInterpreter { fn default() -> Self { Self { default_expiry_duplicate: Duration::from_millis(604800000), default_expiry_vacation: Duration::from_millis(2592000000), disable_capabilities: Default::default(), allowed_notify_uris: Map::new(vec!["mailto".to_string()]), protected_headers: Map::new(vec![ "Original-Subject".to_string(), "Original-From".to_string(), "Received".to_string(), "Auto-Submitted".to_string(), ]), default_subject: "Automated reply".to_string(), default_subject_prefix: "Auto: ".to_string(), max_cpu_cycles: 5000u64, max_header_size: 1024u64, max_includes: 3u64, max_local_vars: 128u64, max_match_vars: 30u64, max_script_name_length: 512u64, max_nested_blocks: 15u64, max_nested_for_every: 3u64, max_nested_includes: 3u64, max_nested_tests: 15u64, max_out_messages: 3u64, max_received_headers: 50u64, max_redirects: 1u64, max_script_size: 102400, max_string_length: 4096u64, max_var_name_length: 32u64, max_var_size: 4096u64, max_scripts: Some(100u64), dkim_sign_domain: Expression { else_: "false".to_string(), match_: List::from_iter([ExpressionMatch { if_: "is_local_domain(sender_domain)".to_string(), then: "sender_domain".to_string(), }]), }, } } } impl IntoValue for SieveUserInterpreter { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(28); map.insert_unchecked( Property::DefaultExpiryDuplicate, self.default_expiry_duplicate.into_value(), ); map.insert_unchecked( Property::DefaultExpiryVacation, self.default_expiry_vacation.into_value(), ); map.insert_unchecked( Property::DisableCapabilities, self.disable_capabilities.into_value(), ); map.insert_unchecked( Property::AllowedNotifyUris, self.allowed_notify_uris.into_value(), ); map.insert_unchecked( Property::ProtectedHeaders, self.protected_headers.into_value(), ); map.insert_unchecked(Property::DefaultSubject, self.default_subject.into_value()); map.insert_unchecked( Property::DefaultSubjectPrefix, self.default_subject_prefix.into_value(), ); map.insert_unchecked(Property::MaxCpuCycles, self.max_cpu_cycles.into_value()); map.insert_unchecked(Property::MaxHeaderSize, self.max_header_size.into_value()); map.insert_unchecked(Property::MaxIncludes, self.max_includes.into_value()); map.insert_unchecked(Property::MaxLocalVars, self.max_local_vars.into_value()); map.insert_unchecked(Property::MaxMatchVars, self.max_match_vars.into_value()); map.insert_unchecked( Property::MaxScriptNameLength, self.max_script_name_length.into_value(), ); map.insert_unchecked( Property::MaxNestedBlocks, self.max_nested_blocks.into_value(), ); map.insert_unchecked( Property::MaxNestedForEvery, self.max_nested_for_every.into_value(), ); map.insert_unchecked( Property::MaxNestedIncludes, self.max_nested_includes.into_value(), ); map.insert_unchecked(Property::MaxNestedTests, self.max_nested_tests.into_value()); map.insert_unchecked(Property::MaxOutMessages, self.max_out_messages.into_value()); map.insert_unchecked( Property::MaxReceivedHeaders, self.max_received_headers.into_value(), ); map.insert_unchecked(Property::MaxRedirects, self.max_redirects.into_value()); map.insert_unchecked(Property::MaxScriptSize, self.max_script_size.into_value()); map.insert_unchecked( Property::MaxStringLength, self.max_string_length.into_value(), ); map.insert_unchecked( Property::MaxVarNameLength, self.max_var_name_length.into_value(), ); map.insert_unchecked(Property::MaxVarSize, self.max_var_size.into_value()); map.insert_unchecked(Property::MaxScripts, self.max_scripts.into_value()); map.insert_unchecked(Property::DkimSignDomain, self.dkim_sign_domain.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SieveUserInterpreter { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::DefaultExpiryDuplicate) => { self.default_expiry_duplicate.patch(pointer, value) } Some(Property::DefaultExpiryVacation) => { self.default_expiry_vacation.patch(pointer, value) } Some(Property::DisableCapabilities) => self.disable_capabilities.patch(pointer, value), Some(Property::AllowedNotifyUris) => self .allowed_notify_uris .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ProtectedHeaders) => self .protected_headers .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::DefaultSubject) => self .default_subject .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::DefaultSubjectPrefix) => { self.default_subject_prefix.patch(pointer, value) } Some(Property::MaxCpuCycles) => self.max_cpu_cycles.patch(pointer, value), Some(Property::MaxHeaderSize) => self.max_header_size.patch(pointer, value), Some(Property::MaxIncludes) => self.max_includes.patch(pointer, value), Some(Property::MaxLocalVars) => self.max_local_vars.patch(pointer, value), Some(Property::MaxMatchVars) => self.max_match_vars.patch(pointer, value), Some(Property::MaxScriptNameLength) => { self.max_script_name_length.patch(pointer, value) } Some(Property::MaxNestedBlocks) => self.max_nested_blocks.patch(pointer, value), Some(Property::MaxNestedForEvery) => self.max_nested_for_every.patch(pointer, value), Some(Property::MaxNestedIncludes) => self.max_nested_includes.patch(pointer, value), Some(Property::MaxNestedTests) => self.max_nested_tests.patch(pointer, value), Some(Property::MaxOutMessages) => self.max_out_messages.patch(pointer, value), Some(Property::MaxReceivedHeaders) => self.max_received_headers.patch(pointer, value), Some(Property::MaxRedirects) => self.max_redirects.patch(pointer, value), Some(Property::MaxScriptSize) => self.max_script_size.patch(pointer, value), Some(Property::MaxStringLength) => self.max_string_length.patch(pointer, value), Some(Property::MaxVarNameLength) => self.max_var_name_length.patch(pointer, value), Some(Property::MaxVarSize) => self.max_var_size.patch(pointer, value), Some(Property::MaxScripts) => self.max_scripts.patch(pointer, value), Some(Property::DkimSignDomain) => self.dkim_sign_domain.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SieveUserScript { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SieveUserScript; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.contents; if value.is_empty() { errors.push(ValidationError::required(Property::Contents)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl Pickle for SieveUserScript { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.description.pickle(out); self.is_active.pickle(out); self.contents.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.is_active = Pickle::unpickle(stream)?; this.contents = Pickle::unpickle(stream)?; Some(this) } } impl Default for SieveUserScript { fn default() -> Self { Self { name: Default::default(), description: Default::default(), is_active: false, contents: Default::default(), } } } impl IntoValue for SieveUserScript { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::IsActive, self.is_active.into_value()); map.insert_unchecked(Property::Contents, self.contents.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SieveUserScript { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self .name .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::IsActive) => self.is_active.patch(pointer, value), Some(Property::Contents) => self .contents .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SpamClassifier { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SpamClassifier; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.model; value.validate(errors); let value = &self.learn_spam_from_rbl_hits; if *value > 100 { errors.push(ValidationError::max_value( Property::LearnSpamFromRblHits, 100, )); } let value = &self.min_ham_samples; if *value > 10000 { errors.push(ValidationError::max_value(Property::MinHamSamples, 10000)); } if *value < 1 { errors.push(ValidationError::min_value(Property::MinHamSamples, 1)); } let value = &self.min_spam_samples; if *value > 10000 { errors.push(ValidationError::max_value(Property::MinSpamSamples, 10000)); } if *value < 1 { errors.push(ValidationError::min_value(Property::MinSpamSamples, 1)); } let value = &self.reservoir_capacity; if *value > 100000 { errors.push(ValidationError::max_value( Property::ReservoirCapacity, 100000, )); } if *value < 100 { errors.push(ValidationError::min_value(Property::ReservoirCapacity, 100)); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for SpamClassifier { fn pickle(&self, out: &mut Vec) { self.model.pickle(out); self.learn_ham_from_card.pickle(out); self.learn_spam_from_rbl_hits.pickle(out); self.learn_spam_from_traps.pickle(out); self.hold_samples_for.pickle(out); self.min_ham_samples.pickle(out); self.min_spam_samples.pickle(out); self.reservoir_capacity.pickle(out); self.train_frequency.pickle(out); self.learn_ham_from_reply.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.model = Pickle::unpickle(stream)?; this.learn_ham_from_card = Pickle::unpickle(stream)?; this.learn_spam_from_rbl_hits = Pickle::unpickle(stream)?; this.learn_spam_from_traps = Pickle::unpickle(stream)?; this.hold_samples_for = Pickle::unpickle(stream)?; this.min_ham_samples = Pickle::unpickle(stream)?; this.min_spam_samples = Pickle::unpickle(stream)?; this.reservoir_capacity = Pickle::unpickle(stream)?; this.train_frequency = Pickle::unpickle(stream)?; this.learn_ham_from_reply = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamClassifier { fn default() -> Self { Self { model: Default::default(), learn_ham_from_card: true, learn_spam_from_rbl_hits: 2u64, learn_spam_from_traps: true, hold_samples_for: Duration::from_millis(15552000000), min_ham_samples: 100u64, min_spam_samples: 100u64, reservoir_capacity: 1024u64, train_frequency: Some(Duration::from_millis(43200000)), learn_ham_from_reply: true, } } } impl IntoValue for SpamClassifier { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(12); map.insert_unchecked(Property::Model, self.model.into_value()); map.insert_unchecked( Property::LearnHamFromCard, self.learn_ham_from_card.into_value(), ); map.insert_unchecked( Property::LearnSpamFromRblHits, self.learn_spam_from_rbl_hits.into_value(), ); map.insert_unchecked( Property::LearnSpamFromTraps, self.learn_spam_from_traps.into_value(), ); map.insert_unchecked(Property::HoldSamplesFor, self.hold_samples_for.into_value()); map.insert_unchecked(Property::MinHamSamples, self.min_ham_samples.into_value()); map.insert_unchecked(Property::MinSpamSamples, self.min_spam_samples.into_value()); map.insert_unchecked( Property::ReservoirCapacity, self.reservoir_capacity.into_value(), ); map.insert_unchecked(Property::TrainFrequency, self.train_frequency.into_value()); map.insert_unchecked( Property::LearnHamFromReply, self.learn_ham_from_reply.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamClassifier { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Model) => self.model.patch(pointer, value), Some(Property::LearnHamFromCard) => self.learn_ham_from_card.patch(pointer, value), Some(Property::LearnSpamFromRblHits) => { self.learn_spam_from_rbl_hits.patch(pointer, value) } Some(Property::LearnSpamFromTraps) => self.learn_spam_from_traps.patch(pointer, value), Some(Property::HoldSamplesFor) => self.hold_samples_for.patch(pointer, value), Some(Property::MinHamSamples) => self.min_ham_samples.patch(pointer, value), Some(Property::MinSpamSamples) => self.min_spam_samples.patch(pointer, value), Some(Property::ReservoirCapacity) => self.reservoir_capacity.patch(pointer, value), Some(Property::TrainFrequency) => self.train_frequency.patch(pointer, value), Some(Property::LearnHamFromReply) => self.learn_ham_from_reply.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamClassifierFtrlCcfh { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.indicator_parameters; value.validate(errors); let value = &self.parameters; value.validate(errors); errors.len() == neb } } impl Pickle for SpamClassifierFtrlCcfh { fn pickle(&self, out: &mut Vec) { self.indicator_parameters.pickle(out); self.parameters.pickle(out); self.feature_l2_normalize.pickle(out); self.feature_log_scale.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.indicator_parameters = Pickle::unpickle(stream)?; this.parameters = Pickle::unpickle(stream)?; this.feature_l2_normalize = Pickle::unpickle(stream)?; this.feature_log_scale = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamClassifierFtrlCcfh { fn default() -> Self { Self { indicator_parameters: FtrlParameters { num_features: ModelSize::V18, ..Default::default() }, parameters: FtrlParameters { num_features: ModelSize::V20, ..Default::default() }, feature_l2_normalize: true, feature_log_scale: true, } } } impl IntoValue for SpamClassifierFtrlCcfh { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked( Property::IndicatorParameters, self.indicator_parameters.into_value(), ); map.insert_unchecked(Property::Parameters, self.parameters.into_value()); map.insert_unchecked( Property::FeatureL2Normalize, self.feature_l2_normalize.into_value(), ); map.insert_unchecked( Property::FeatureLogScale, self.feature_log_scale.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamClassifierFtrlCcfh { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::IndicatorParameters) => self.indicator_parameters.patch(pointer, value), Some(Property::Parameters) => self.parameters.patch(pointer, value), Some(Property::FeatureL2Normalize) => self.feature_l2_normalize.patch(pointer, value), Some(Property::FeatureLogScale) => self.feature_log_scale.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamClassifierFtrlFh { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.parameters; value.validate(errors); errors.len() == neb } } impl Pickle for SpamClassifierFtrlFh { fn pickle(&self, out: &mut Vec) { self.parameters.pickle(out); self.feature_l2_normalize.pickle(out); self.feature_log_scale.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.parameters = Pickle::unpickle(stream)?; this.feature_l2_normalize = Pickle::unpickle(stream)?; this.feature_log_scale = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamClassifierFtrlFh { fn default() -> Self { Self { parameters: FtrlParameters { num_features: ModelSize::V20, ..Default::default() }, feature_l2_normalize: true, feature_log_scale: true, } } } impl IntoValue for SpamClassifierFtrlFh { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::Parameters, self.parameters.into_value()); map.insert_unchecked( Property::FeatureL2Normalize, self.feature_l2_normalize.into_value(), ); map.insert_unchecked( Property::FeatureLogScale, self.feature_log_scale.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamClassifierFtrlFh { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Parameters) => self.parameters.patch(pointer, value), Some(Property::FeatureL2Normalize) => self.feature_l2_normalize.patch(pointer, value), Some(Property::FeatureLogScale) => self.feature_log_scale.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamClassifierModel { fn validate(&self, errors: &mut Vec) -> bool { match self { SpamClassifierModel::FtrlFh(inner) => inner.validate(errors), SpamClassifierModel::FtrlCcfh(inner) => inner.validate(errors), SpamClassifierModel::Disabled => true, } } } impl Default for SpamClassifierModel { fn default() -> Self { SpamClassifierModel::FtrlFh(Default::default()) } } impl Pickle for SpamClassifierModel { fn pickle(&self, out: &mut Vec) { match self { SpamClassifierModel::FtrlFh(inner) => { 0u16.pickle(out); inner.pickle(out); } SpamClassifierModel::FtrlCcfh(inner) => { 1u16.pickle(out); inner.pickle(out); } SpamClassifierModel::Disabled => { 2u16.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(SpamClassifierModel::FtrlFh), 1 => Pickle::unpickle(stream).map(SpamClassifierModel::FtrlCcfh), 2 => Some(SpamClassifierModel::Disabled), _ => None, } } } impl IntoValue for SpamClassifierModel { fn into_value(self) -> JmapValue<'static> { match self { SpamClassifierModel::FtrlFh(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("FtrlFh".into())); obj } SpamClassifierModel::FtrlCcfh(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("FtrlCcfh".into())); obj } SpamClassifierModel::Disabled => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Disabled".into())); JmapValue::Object(obj) } } } } impl RegistryJsonPatch for SpamClassifierModel { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { SpamClassifierModelType::FtrlFh => { *self = SpamClassifierModel::FtrlFh(Default::default()) } SpamClassifierModelType::FtrlCcfh => { *self = SpamClassifierModel::FtrlCcfh(Default::default()) } SpamClassifierModelType::Disabled => *self = SpamClassifierModel::Disabled, } } match self { SpamClassifierModel::FtrlFh(inner) => inner.patch(pointer, value), SpamClassifierModel::FtrlCcfh(inner) => inner.patch(pointer, value), SpamClassifierModel::Disabled => pointer.assert_eof(), } } } impl SpamClassifierModel { pub fn object_type(&self) -> SpamClassifierModelType { match self { SpamClassifierModel::FtrlFh(_) => SpamClassifierModelType::FtrlFh, SpamClassifierModel::FtrlCcfh(_) => SpamClassifierModelType::FtrlCcfh, SpamClassifierModel::Disabled => SpamClassifierModelType::Disabled, } } } impl SpamClassify { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.message; if value.is_empty() { errors.push(ValidationError::required(Property::Message)); } let value = &self.remote_ip; if !value.is_valid() { errors.push(ValidationError::invalid(Property::RemoteIp, value)); } let value = &self.ehlo_domain; if value.is_empty() { errors.push(ValidationError::required(Property::EhloDomain)); } if let Some(value) = &self.authenticated_as { if value.is_empty() { errors.push(ValidationError::required(Property::AuthenticatedAs)); } } let value = &self.env_from; if value.is_empty() { errors.push(ValidationError::required(Property::EnvFrom)); } let value = &self.env_rcpt_to; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::EnvRcptTo)); } } let value = &self.tags; for value in value.values() { value.validate(errors); } errors.len() == neb } } impl Pickle for SpamClassify { fn pickle(&self, out: &mut Vec) { self.message.pickle(out); self.remote_ip.pickle(out); self.ehlo_domain.pickle(out); self.authenticated_as.pickle(out); self.is_tls.pickle(out); self.env_from.pickle(out); self.env_from_parameters.pickle(out); self.env_rcpt_to.pickle(out); self.score.pickle(out); self.tags.pickle(out); self.result.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.message = Pickle::unpickle(stream)?; this.remote_ip = Pickle::unpickle(stream)?; this.ehlo_domain = Pickle::unpickle(stream)?; this.authenticated_as = Pickle::unpickle(stream)?; this.is_tls = Pickle::unpickle(stream)?; this.env_from = Pickle::unpickle(stream)?; this.env_from_parameters = Pickle::unpickle(stream)?; this.env_rcpt_to = Pickle::unpickle(stream)?; this.score = Pickle::unpickle(stream)?; this.tags = Pickle::unpickle(stream)?; this.result = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamClassify { fn default() -> Self { Self { message: Default::default(), remote_ip: Default::default(), ehlo_domain: Default::default(), authenticated_as: Default::default(), is_tls: true, env_from: Default::default(), env_from_parameters: Default::default(), env_rcpt_to: Default::default(), score: Float::new(0.0f64), tags: Default::default(), result: Default::default(), } } } impl IntoValue for SpamClassify { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(13); map.insert_unchecked(Property::Message, self.message.into_value()); map.insert_unchecked(Property::RemoteIp, self.remote_ip.into_value()); map.insert_unchecked(Property::EhloDomain, self.ehlo_domain.into_value()); map.insert_unchecked( Property::AuthenticatedAs, self.authenticated_as.into_value(), ); map.insert_unchecked(Property::IsTls, self.is_tls.into_value()); map.insert_unchecked(Property::EnvFrom, self.env_from.into_value()); map.insert_unchecked( Property::EnvFromParameters, self.env_from_parameters.into_value(), ); map.insert_unchecked(Property::EnvRcptTo, self.env_rcpt_to.into_value()); map.insert_unchecked(Property::Score, self.score.into_value()); map.insert_unchecked(Property::Tags, self.tags.into_value()); map.insert_unchecked(Property::Result, self.result.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamClassify { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Message) => self.message.patch(pointer, value), Some(Property::RemoteIp) => self.remote_ip.patch(pointer, value), Some(Property::EhloDomain) => self.ehlo_domain.patch(pointer, value), Some(Property::AuthenticatedAs) => self.authenticated_as.patch(pointer, value), Some(Property::IsTls) => self.is_tls.patch(pointer, value), Some(Property::EnvFrom) => self .env_from .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::EnvFromParameters) => self.env_from_parameters.patch(pointer, value), Some(Property::EnvRcptTo) => self .env_rcpt_to .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::Score) => pointer.assert_server_set(), Some(Property::Tags) => pointer.assert_server_set(), Some(Property::Result) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamClassifyTag { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for SpamClassifyTag { fn pickle(&self, out: &mut Vec) { self.score.pickle(out); self.disposition.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.score = Pickle::unpickle(stream)?; this.disposition = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamClassifyTag { fn default() -> Self { Self { score: Float::new(0.0f64), disposition: Default::default(), } } } impl IntoValue for SpamClassifyTag { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Score, self.score.into_value()); map.insert_unchecked(Property::Disposition, self.disposition.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamClassifyTag { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Score) => pointer.assert_server_set(), Some(Property::Disposition) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SpamDnsblServer { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SpamDnsblServer; fn validate(&self, errors: &mut Vec) -> bool { match self { SpamDnsblServer::Any(inner) => inner.validate(errors), SpamDnsblServer::Url(inner) => inner.validate(errors), SpamDnsblServer::Domain(inner) => inner.validate(errors), SpamDnsblServer::Email(inner) => inner.validate(errors), SpamDnsblServer::Ip(inner) => inner.validate(errors), SpamDnsblServer::Header(inner) => inner.validate(errors), SpamDnsblServer::Body(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { SpamDnsblServer::Any(object) => { object.index(i); } SpamDnsblServer::Url(object) => { object.index(i); } SpamDnsblServer::Domain(object) => { object.index(i); } SpamDnsblServer::Email(object) => { object.index(i); } SpamDnsblServer::Ip(object) => { object.index(i); } SpamDnsblServer::Header(object) => { object.index(i); } SpamDnsblServer::Body(object) => { object.index(i); } } } } impl Default for SpamDnsblServer { fn default() -> Self { SpamDnsblServer::Any(Default::default()) } } impl Pickle for SpamDnsblServer { fn pickle(&self, out: &mut Vec) { match self { SpamDnsblServer::Any(inner) => { 0u16.pickle(out); inner.pickle(out); } SpamDnsblServer::Url(inner) => { 1u16.pickle(out); inner.pickle(out); } SpamDnsblServer::Domain(inner) => { 2u16.pickle(out); inner.pickle(out); } SpamDnsblServer::Email(inner) => { 3u16.pickle(out); inner.pickle(out); } SpamDnsblServer::Ip(inner) => { 4u16.pickle(out); inner.pickle(out); } SpamDnsblServer::Header(inner) => { 5u16.pickle(out); inner.pickle(out); } SpamDnsblServer::Body(inner) => { 6u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(SpamDnsblServer::Any), 1 => Pickle::unpickle(stream).map(SpamDnsblServer::Url), 2 => Pickle::unpickle(stream).map(SpamDnsblServer::Domain), 3 => Pickle::unpickle(stream).map(SpamDnsblServer::Email), 4 => Pickle::unpickle(stream).map(SpamDnsblServer::Ip), 5 => Pickle::unpickle(stream).map(SpamDnsblServer::Header), 6 => Pickle::unpickle(stream).map(SpamDnsblServer::Body), _ => None, } } } impl IntoValue for SpamDnsblServer { fn into_value(self) -> JmapValue<'static> { match self { SpamDnsblServer::Any(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Any".into())); obj } SpamDnsblServer::Url(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Url".into())); obj } SpamDnsblServer::Domain(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Domain".into())); obj } SpamDnsblServer::Email(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Email".into())); obj } SpamDnsblServer::Ip(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ip".into())); obj } SpamDnsblServer::Header(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Header".into())); obj } SpamDnsblServer::Body(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Body".into())); obj } } } } impl RegistryJsonPatch for SpamDnsblServer { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { SpamDnsblServerType::Any => *self = SpamDnsblServer::Any(Default::default()), SpamDnsblServerType::Url => *self = SpamDnsblServer::Url(Default::default()), SpamDnsblServerType::Domain => *self = SpamDnsblServer::Domain(Default::default()), SpamDnsblServerType::Email => *self = SpamDnsblServer::Email(Default::default()), SpamDnsblServerType::Ip => *self = SpamDnsblServer::Ip(Default::default()), SpamDnsblServerType::Header => *self = SpamDnsblServer::Header(Default::default()), SpamDnsblServerType::Body => *self = SpamDnsblServer::Body(Default::default()), } } match self { SpamDnsblServer::Any(inner) => inner.patch(pointer, value), SpamDnsblServer::Url(inner) => inner.patch(pointer, value), SpamDnsblServer::Domain(inner) => inner.patch(pointer, value), SpamDnsblServer::Email(inner) => inner.patch(pointer, value), SpamDnsblServer::Ip(inner) => inner.patch(pointer, value), SpamDnsblServer::Header(inner) => inner.patch(pointer, value), SpamDnsblServer::Body(inner) => inner.patch(pointer, value), } } } impl SpamDnsblServer { pub fn object_type(&self) -> SpamDnsblServerType { match self { SpamDnsblServer::Any(_) => SpamDnsblServerType::Any, SpamDnsblServer::Url(_) => SpamDnsblServerType::Url, SpamDnsblServer::Domain(_) => SpamDnsblServerType::Domain, SpamDnsblServer::Email(_) => SpamDnsblServerType::Email, SpamDnsblServer::Ip(_) => SpamDnsblServerType::Ip, SpamDnsblServer::Header(_) => SpamDnsblServerType::Header, SpamDnsblServer::Body(_) => SpamDnsblServerType::Body, } } pub fn expression_ctxs(&self) -> Vec> { match self { SpamDnsblServer::Any(obj) => obj.expression_ctxs(), SpamDnsblServer::Url(obj) => obj.expression_ctxs(), SpamDnsblServer::Domain(obj) => obj.expression_ctxs(), SpamDnsblServer::Email(obj) => obj.expression_ctxs(), SpamDnsblServer::Ip(obj) => obj.expression_ctxs(), SpamDnsblServer::Header(obj) => obj.expression_ctxs(), SpamDnsblServer::Body(obj) => obj.expression_ctxs(), } } } impl SpamDnsblServerAny { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.tag; value.validate(errors); let value = &self.zone; value.validate(errors); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl SpamDnsblServerAny { pub fn ctx_tag(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.tag, default: None, property: Property::Tag, allowed_variables: SPAM_IP_VARIABLE, allowed_constants: &[], } } pub fn ctx_zone(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.zone, default: None, property: Property::Zone, allowed_variables: SPAM_GENERIC_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_tag(), self.ctx_zone()] } } impl Pickle for SpamDnsblServerAny { fn pickle(&self, out: &mut Vec) { self.tag.pickle(out); self.zone.pickle(out); self.name.pickle(out); self.description.pickle(out); self.enable.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.tag = Pickle::unpickle(stream)?; this.zone = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamDnsblServerAny { fn default() -> Self { Self { tag: Default::default(), zone: Default::default(), name: Default::default(), description: Default::default(), enable: true, } } } impl IntoValue for SpamDnsblServerAny { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Tag, self.tag.into_value()); map.insert_unchecked(Property::Zone, self.zone.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamDnsblServerAny { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Tag) => self.tag.patch(pointer, value), Some(Property::Zone) => self.zone.patch(pointer, value), Some(Property::Name) => self.name.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::RemoveSpaces, StringValidator::Uppercase]), value, ), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamDnsblServerBody { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.tag; value.validate(errors); let value = &self.zone; value.validate(errors); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl SpamDnsblServerBody { pub fn ctx_tag(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.tag, default: None, property: Property::Tag, allowed_variables: SPAM_IP_VARIABLE, allowed_constants: &[], } } pub fn ctx_zone(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.zone, default: None, property: Property::Zone, allowed_variables: SPAM_GENERIC_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_tag(), self.ctx_zone()] } } impl Pickle for SpamDnsblServerBody { fn pickle(&self, out: &mut Vec) { self.tag.pickle(out); self.zone.pickle(out); self.name.pickle(out); self.description.pickle(out); self.enable.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.tag = Pickle::unpickle(stream)?; this.zone = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamDnsblServerBody { fn default() -> Self { Self { tag: Default::default(), zone: Default::default(), name: Default::default(), description: Default::default(), enable: true, } } } impl IntoValue for SpamDnsblServerBody { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Tag, self.tag.into_value()); map.insert_unchecked(Property::Zone, self.zone.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamDnsblServerBody { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Tag) => self.tag.patch(pointer, value), Some(Property::Zone) => self.zone.patch(pointer, value), Some(Property::Name) => self.name.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::RemoveSpaces, StringValidator::Uppercase]), value, ), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamDnsblServerDomain { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.tag; value.validate(errors); let value = &self.zone; value.validate(errors); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl SpamDnsblServerDomain { pub fn ctx_tag(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.tag, default: None, property: Property::Tag, allowed_variables: SPAM_IP_VARIABLE, allowed_constants: &[], } } pub fn ctx_zone(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.zone, default: None, property: Property::Zone, allowed_variables: SPAM_GENERIC_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_tag(), self.ctx_zone()] } } impl Pickle for SpamDnsblServerDomain { fn pickle(&self, out: &mut Vec) { self.tag.pickle(out); self.zone.pickle(out); self.name.pickle(out); self.description.pickle(out); self.enable.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.tag = Pickle::unpickle(stream)?; this.zone = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamDnsblServerDomain { fn default() -> Self { Self { tag: Default::default(), zone: Default::default(), name: Default::default(), description: Default::default(), enable: true, } } } impl IntoValue for SpamDnsblServerDomain { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Tag, self.tag.into_value()); map.insert_unchecked(Property::Zone, self.zone.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamDnsblServerDomain { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Tag) => self.tag.patch(pointer, value), Some(Property::Zone) => self.zone.patch(pointer, value), Some(Property::Name) => self.name.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::RemoveSpaces, StringValidator::Uppercase]), value, ), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamDnsblServerEmail { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.tag; value.validate(errors); let value = &self.zone; value.validate(errors); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl SpamDnsblServerEmail { pub fn ctx_tag(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.tag, default: None, property: Property::Tag, allowed_variables: SPAM_IP_VARIABLE, allowed_constants: &[], } } pub fn ctx_zone(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.zone, default: None, property: Property::Zone, allowed_variables: SPAM_EMAIL_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_tag(), self.ctx_zone()] } } impl Pickle for SpamDnsblServerEmail { fn pickle(&self, out: &mut Vec) { self.tag.pickle(out); self.zone.pickle(out); self.name.pickle(out); self.description.pickle(out); self.enable.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.tag = Pickle::unpickle(stream)?; this.zone = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamDnsblServerEmail { fn default() -> Self { Self { tag: Default::default(), zone: Default::default(), name: Default::default(), description: Default::default(), enable: true, } } } impl IntoValue for SpamDnsblServerEmail { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Tag, self.tag.into_value()); map.insert_unchecked(Property::Zone, self.zone.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamDnsblServerEmail { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Tag) => self.tag.patch(pointer, value), Some(Property::Zone) => self.zone.patch(pointer, value), Some(Property::Name) => self.name.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::RemoveSpaces, StringValidator::Uppercase]), value, ), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamDnsblServerHeader { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.tag; value.validate(errors); let value = &self.zone; value.validate(errors); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl SpamDnsblServerHeader { pub fn ctx_tag(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.tag, default: None, property: Property::Tag, allowed_variables: SPAM_IP_VARIABLE, allowed_constants: &[], } } pub fn ctx_zone(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.zone, default: None, property: Property::Zone, allowed_variables: SPAM_HEADER_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_tag(), self.ctx_zone()] } } impl Pickle for SpamDnsblServerHeader { fn pickle(&self, out: &mut Vec) { self.tag.pickle(out); self.zone.pickle(out); self.name.pickle(out); self.description.pickle(out); self.enable.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.tag = Pickle::unpickle(stream)?; this.zone = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamDnsblServerHeader { fn default() -> Self { Self { tag: Default::default(), zone: Default::default(), name: Default::default(), description: Default::default(), enable: true, } } } impl IntoValue for SpamDnsblServerHeader { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Tag, self.tag.into_value()); map.insert_unchecked(Property::Zone, self.zone.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamDnsblServerHeader { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Tag) => self.tag.patch(pointer, value), Some(Property::Zone) => self.zone.patch(pointer, value), Some(Property::Name) => self.name.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::RemoveSpaces, StringValidator::Uppercase]), value, ), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamDnsblServerIp { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.tag; value.validate(errors); let value = &self.zone; value.validate(errors); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl SpamDnsblServerIp { pub fn ctx_tag(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.tag, default: None, property: Property::Tag, allowed_variables: SPAM_IP_VARIABLE, allowed_constants: &[], } } pub fn ctx_zone(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.zone, default: None, property: Property::Zone, allowed_variables: SPAM_IP_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_tag(), self.ctx_zone()] } } impl Pickle for SpamDnsblServerIp { fn pickle(&self, out: &mut Vec) { self.tag.pickle(out); self.zone.pickle(out); self.name.pickle(out); self.description.pickle(out); self.enable.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.tag = Pickle::unpickle(stream)?; this.zone = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamDnsblServerIp { fn default() -> Self { Self { tag: Default::default(), zone: Default::default(), name: Default::default(), description: Default::default(), enable: true, } } } impl IntoValue for SpamDnsblServerIp { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Tag, self.tag.into_value()); map.insert_unchecked(Property::Zone, self.zone.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamDnsblServerIp { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Tag) => self.tag.patch(pointer, value), Some(Property::Zone) => self.zone.patch(pointer, value), Some(Property::Name) => self.name.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::RemoveSpaces, StringValidator::Uppercase]), value, ), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamDnsblServerUrl { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.tag; value.validate(errors); let value = &self.zone; value.validate(errors); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl SpamDnsblServerUrl { pub fn ctx_tag(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.tag, default: None, property: Property::Tag, allowed_variables: SPAM_IP_VARIABLE, allowed_constants: &[], } } pub fn ctx_zone(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.zone, default: None, property: Property::Zone, allowed_variables: SPAM_URL_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_tag(), self.ctx_zone()] } } impl Pickle for SpamDnsblServerUrl { fn pickle(&self, out: &mut Vec) { self.tag.pickle(out); self.zone.pickle(out); self.name.pickle(out); self.description.pickle(out); self.enable.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.tag = Pickle::unpickle(stream)?; this.zone = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamDnsblServerUrl { fn default() -> Self { Self { tag: Default::default(), zone: Default::default(), name: Default::default(), description: Default::default(), enable: true, } } } impl IntoValue for SpamDnsblServerUrl { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Tag, self.tag.into_value()); map.insert_unchecked(Property::Zone, self.zone.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamDnsblServerUrl { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Tag) => self.tag.patch(pointer, value), Some(Property::Zone) => self.zone.patch(pointer, value), Some(Property::Name) => self.name.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::RemoveSpaces, StringValidator::Uppercase]), value, ), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SpamDnsblSettings { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SpamDnsblSettings; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.domain_limit; if *value < 1 { errors.push(ValidationError::min_value(Property::DomainLimit, 1)); } let value = &self.email_limit; if *value < 1 { errors.push(ValidationError::min_value(Property::EmailLimit, 1)); } let value = &self.ip_limit; if *value < 1 { errors.push(ValidationError::min_value(Property::IpLimit, 1)); } let value = &self.url_limit; if *value < 1 { errors.push(ValidationError::min_value(Property::UrlLimit, 1)); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for SpamDnsblSettings { fn pickle(&self, out: &mut Vec) { self.domain_limit.pickle(out); self.email_limit.pickle(out); self.ip_limit.pickle(out); self.url_limit.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.domain_limit = Pickle::unpickle(stream)?; this.email_limit = Pickle::unpickle(stream)?; this.ip_limit = Pickle::unpickle(stream)?; this.url_limit = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamDnsblSettings { fn default() -> Self { Self { domain_limit: 50u64, email_limit: 50u64, ip_limit: 50u64, url_limit: 50u64, } } } impl IntoValue for SpamDnsblSettings { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::DomainLimit, self.domain_limit.into_value()); map.insert_unchecked(Property::EmailLimit, self.email_limit.into_value()); map.insert_unchecked(Property::IpLimit, self.ip_limit.into_value()); map.insert_unchecked(Property::UrlLimit, self.url_limit.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamDnsblSettings { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::DomainLimit) => self.domain_limit.patch(pointer, value), Some(Property::EmailLimit) => self.email_limit.patch(pointer, value), Some(Property::IpLimit) => self.ip_limit.patch(pointer, value), Some(Property::UrlLimit) => self.url_limit.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SpamFileExtension { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SpamFileExtension; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.extension; if value.is_empty() { errors.push(ValidationError::required(Property::Extension)); } let value = &self.content_types; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::ContentTypes)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Extension, &self.extension); } } impl Pickle for SpamFileExtension { fn pickle(&self, out: &mut Vec) { self.extension.pickle(out); self.is_archive.pickle(out); self.is_bad.pickle(out); self.is_nz.pickle(out); self.content_types.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.extension = Pickle::unpickle(stream)?; this.is_archive = Pickle::unpickle(stream)?; this.is_bad = Pickle::unpickle(stream)?; this.is_nz = Pickle::unpickle(stream)?; this.content_types = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamFileExtension { fn default() -> Self { Self { extension: Default::default(), is_archive: false, is_bad: false, is_nz: false, content_types: Default::default(), } } } impl IntoValue for SpamFileExtension { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Extension, self.extension.into_value()); map.insert_unchecked(Property::IsArchive, self.is_archive.into_value()); map.insert_unchecked(Property::IsBad, self.is_bad.into_value()); map.insert_unchecked(Property::IsNz, self.is_nz.into_value()); map.insert_unchecked(Property::ContentTypes, self.content_types.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamFileExtension { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Extension) => self.extension.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::RemoveSpaces, StringValidator::Lowercase]), value, ), Some(Property::IsArchive) => self.is_archive.patch(pointer, value), Some(Property::IsBad) => self.is_bad.patch(pointer, value), Some(Property::IsNz) => self.is_nz.patch(pointer, value), Some(Property::ContentTypes) => self .content_types .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SpamLlm { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SpamLlm; fn validate(&self, errors: &mut Vec) -> bool { match self { SpamLlm::Disable => true, SpamLlm::Enable(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { SpamLlm::Disable => {} SpamLlm::Enable(object) => { object.index(i); } } } } impl Default for SpamLlm { fn default() -> Self { SpamLlm::Disable } } impl Pickle for SpamLlm { fn pickle(&self, out: &mut Vec) { match self { SpamLlm::Disable => { 0u16.pickle(out); } SpamLlm::Enable(inner) => { 1u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(SpamLlm::Disable), 1 => Pickle::unpickle(stream).map(SpamLlm::Enable), _ => None, } } } impl IntoValue for SpamLlm { fn into_value(self) -> JmapValue<'static> { match self { SpamLlm::Disable => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Disable".into())); JmapValue::Object(obj) } SpamLlm::Enable(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Enable".into())); obj } } } } impl RegistryJsonPatch for SpamLlm { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { SpamLlmType::Disable => *self = SpamLlm::Disable, SpamLlmType::Enable => *self = SpamLlm::Enable(Default::default()), } } match self { SpamLlm::Disable => pointer.assert_eof(), SpamLlm::Enable(inner) => inner.patch(pointer, value), } } } impl SpamLlm { pub fn object_type(&self) -> SpamLlmType { match self { SpamLlm::Disable => SpamLlmType::Disable, SpamLlm::Enable(_) => SpamLlmType::Enable, } } } impl SpamLlmProperties { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.categories; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::Categories)); } } if value.len() < 2 { errors.push(ValidationError::min_items(Property::Categories, 2)); } let value = &self.confidence; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::Confidence)); } } let value = &self.model_id; if !value.is_valid() { errors.push(ValidationError::required(Property::ModelId)); } let value = &self.prompt; if value.is_empty() { errors.push(ValidationError::required(Property::Prompt)); } let value = &self.separator; if value.is_empty() { errors.push(ValidationError::required(Property::Separator)); } let value = &self.temperature; if *value > Float::new(1.0) { errors.push(ValidationError::max_value(Property::Temperature, 1)); } if *value < Float::new(0.0) { errors.push(ValidationError::min_value(Property::Temperature, 0)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::AiModel, self.model_id.into(), None); } } impl Pickle for SpamLlmProperties { fn pickle(&self, out: &mut Vec) { self.categories.pickle(out); self.confidence.pickle(out); self.response_pos_category.pickle(out); self.response_pos_confidence.pickle(out); self.response_pos_explanation.pickle(out); self.model_id.pickle(out); self.prompt.pickle(out); self.separator.pickle(out); self.temperature.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.categories = Pickle::unpickle(stream)?; this.confidence = Pickle::unpickle(stream)?; this.response_pos_category = Pickle::unpickle(stream)?; this.response_pos_confidence = Pickle::unpickle(stream)?; this.response_pos_explanation = Pickle::unpickle(stream)?; this.model_id = Pickle::unpickle(stream)?; this.prompt = Pickle::unpickle(stream)?; this.separator = Pickle::unpickle(stream)?; this.temperature = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamLlmProperties { fn default() -> Self { Self { categories: Map::new(vec![ "Unsolicited".to_string(), "Commercial".to_string(), "Harmful".to_string(), "Legitimate".to_string(), ]), confidence: Map::new(vec![ "High".to_string(), "Medium".to_string(), "Low".to_string(), ]), response_pos_category: 0u64, response_pos_confidence: Some(1u64), response_pos_explanation: Some(2u64), model_id: Default::default(), prompt: Default::default(), separator: ",".to_string(), temperature: Float::new(0.5f64), } } } impl IntoValue for SpamLlmProperties { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::Categories, self.categories.into_value()); map.insert_unchecked(Property::Confidence, self.confidence.into_value()); map.insert_unchecked( Property::ResponsePosCategory, self.response_pos_category.into_value(), ); map.insert_unchecked( Property::ResponsePosConfidence, self.response_pos_confidence.into_value(), ); map.insert_unchecked( Property::ResponsePosExplanation, self.response_pos_explanation.into_value(), ); map.insert_unchecked(Property::ModelId, self.model_id.into_value()); map.insert_unchecked(Property::Prompt, self.prompt.into_value()); map.insert_unchecked(Property::Separator, self.separator.into_value()); map.insert_unchecked(Property::Temperature, self.temperature.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamLlmProperties { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Categories) => self.categories.patch(pointer, value), Some(Property::Confidence) => self.confidence.patch(pointer, value), Some(Property::ResponsePosCategory) => self.response_pos_category.patch(pointer, value), Some(Property::ResponsePosConfidence) => { self.response_pos_confidence.patch(pointer, value) } Some(Property::ResponsePosExplanation) => { self.response_pos_explanation.patch(pointer, value) } Some(Property::ModelId) => self.model_id.patch(pointer, value), Some(Property::Prompt) => self.prompt.patch(pointer, value), Some(Property::Separator) => self .separator .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Temperature) => self.temperature.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SpamPyzor { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SpamPyzor; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.block_count; if *value > 1000 { errors.push(ValidationError::max_value(Property::BlockCount, 1000)); } if *value < 1 { errors.push(ValidationError::min_value(Property::BlockCount, 1)); } let value = &self.host; if value.is_empty() { errors.push(ValidationError::required(Property::Host)); } let value = &self.port; if *value > 65535 { errors.push(ValidationError::max_value(Property::Port, 65535)); } if *value < 100 { errors.push(ValidationError::min_value(Property::Port, 100)); } let value = &self.ratio; if *value > Float::new(1.0) { errors.push(ValidationError::max_value(Property::Ratio, 1)); } if *value < Float::new(0.0) { errors.push(ValidationError::min_value(Property::Ratio, 0)); } let value = &self.allow_count; if *value > 1000 { errors.push(ValidationError::max_value(Property::AllowCount, 1000)); } if *value < 1 { errors.push(ValidationError::min_value(Property::AllowCount, 1)); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for SpamPyzor { fn pickle(&self, out: &mut Vec) { self.block_count.pickle(out); self.enable.pickle(out); self.host.pickle(out); self.port.pickle(out); self.ratio.pickle(out); self.timeout.pickle(out); self.allow_count.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.block_count = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.host = Pickle::unpickle(stream)?; this.port = Pickle::unpickle(stream)?; this.ratio = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.allow_count = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamPyzor { fn default() -> Self { Self { block_count: 5u64, enable: true, host: "public.pyzor.org".to_string(), port: 24441u64, ratio: Float::new(0.2f64), timeout: Duration::from_millis(5000), allow_count: 10u64, } } } impl IntoValue for SpamPyzor { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked(Property::BlockCount, self.block_count.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Host, self.host.into_value()); map.insert_unchecked(Property::Port, self.port.into_value()); map.insert_unchecked(Property::Ratio, self.ratio.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::AllowCount, self.allow_count.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamPyzor { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::BlockCount) => self.block_count.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Host) => self .host .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Port) => self.port.patch(pointer, value), Some(Property::Ratio) => self.ratio.patch(pointer, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::AllowCount) => self.allow_count.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SpamRule { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SpamRule; fn validate(&self, errors: &mut Vec) -> bool { match self { SpamRule::Any(inner) => inner.validate(errors), SpamRule::Url(inner) => inner.validate(errors), SpamRule::Domain(inner) => inner.validate(errors), SpamRule::Email(inner) => inner.validate(errors), SpamRule::Ip(inner) => inner.validate(errors), SpamRule::Header(inner) => inner.validate(errors), SpamRule::Body(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { SpamRule::Any(object) => { object.index(i); } SpamRule::Url(object) => { object.index(i); } SpamRule::Domain(object) => { object.index(i); } SpamRule::Email(object) => { object.index(i); } SpamRule::Ip(object) => { object.index(i); } SpamRule::Header(object) => { object.index(i); } SpamRule::Body(object) => { object.index(i); } } } } impl Default for SpamRule { fn default() -> Self { SpamRule::Any(Default::default()) } } impl Pickle for SpamRule { fn pickle(&self, out: &mut Vec) { match self { SpamRule::Any(inner) => { 0u16.pickle(out); inner.pickle(out); } SpamRule::Url(inner) => { 1u16.pickle(out); inner.pickle(out); } SpamRule::Domain(inner) => { 2u16.pickle(out); inner.pickle(out); } SpamRule::Email(inner) => { 3u16.pickle(out); inner.pickle(out); } SpamRule::Ip(inner) => { 4u16.pickle(out); inner.pickle(out); } SpamRule::Header(inner) => { 5u16.pickle(out); inner.pickle(out); } SpamRule::Body(inner) => { 6u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(SpamRule::Any), 1 => Pickle::unpickle(stream).map(SpamRule::Url), 2 => Pickle::unpickle(stream).map(SpamRule::Domain), 3 => Pickle::unpickle(stream).map(SpamRule::Email), 4 => Pickle::unpickle(stream).map(SpamRule::Ip), 5 => Pickle::unpickle(stream).map(SpamRule::Header), 6 => Pickle::unpickle(stream).map(SpamRule::Body), _ => None, } } } impl IntoValue for SpamRule { fn into_value(self) -> JmapValue<'static> { match self { SpamRule::Any(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Any".into())); obj } SpamRule::Url(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Url".into())); obj } SpamRule::Domain(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Domain".into())); obj } SpamRule::Email(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Email".into())); obj } SpamRule::Ip(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Ip".into())); obj } SpamRule::Header(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Header".into())); obj } SpamRule::Body(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Body".into())); obj } } } } impl RegistryJsonPatch for SpamRule { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { SpamRuleType::Any => *self = SpamRule::Any(Default::default()), SpamRuleType::Url => *self = SpamRule::Url(Default::default()), SpamRuleType::Domain => *self = SpamRule::Domain(Default::default()), SpamRuleType::Email => *self = SpamRule::Email(Default::default()), SpamRuleType::Ip => *self = SpamRule::Ip(Default::default()), SpamRuleType::Header => *self = SpamRule::Header(Default::default()), SpamRuleType::Body => *self = SpamRule::Body(Default::default()), } } match self { SpamRule::Any(inner) => inner.patch(pointer, value), SpamRule::Url(inner) => inner.patch(pointer, value), SpamRule::Domain(inner) => inner.patch(pointer, value), SpamRule::Email(inner) => inner.patch(pointer, value), SpamRule::Ip(inner) => inner.patch(pointer, value), SpamRule::Header(inner) => inner.patch(pointer, value), SpamRule::Body(inner) => inner.patch(pointer, value), } } } impl SpamRule { pub fn object_type(&self) -> SpamRuleType { match self { SpamRule::Any(_) => SpamRuleType::Any, SpamRule::Url(_) => SpamRuleType::Url, SpamRule::Domain(_) => SpamRuleType::Domain, SpamRule::Email(_) => SpamRuleType::Email, SpamRule::Ip(_) => SpamRuleType::Ip, SpamRule::Header(_) => SpamRuleType::Header, SpamRule::Body(_) => SpamRuleType::Body, } } pub fn expression_ctxs(&self) -> Vec> { match self { SpamRule::Any(obj) => obj.expression_ctxs(), SpamRule::Url(obj) => obj.expression_ctxs(), SpamRule::Domain(obj) => obj.expression_ctxs(), SpamRule::Email(obj) => obj.expression_ctxs(), SpamRule::Ip(obj) => obj.expression_ctxs(), SpamRule::Header(obj) => obj.expression_ctxs(), SpamRule::Body(obj) => obj.expression_ctxs(), } } } impl SpamRuleAny { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.condition; value.validate(errors); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.priority; if *value > (99999) { errors.push(ValidationError::max_value(Property::Priority, 99999)); } if *value < (-99999) { errors.push(ValidationError::min_value(Property::Priority, -99999)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl SpamRuleAny { pub fn ctx_condition(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.condition, default: None, property: Property::Condition, allowed_variables: SPAM_GENERIC_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_condition()] } } impl Pickle for SpamRuleAny { fn pickle(&self, out: &mut Vec) { self.condition.pickle(out); self.name.pickle(out); self.description.pickle(out); self.enable.pickle(out); self.priority.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.condition = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.priority = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamRuleAny { fn default() -> Self { Self { condition: Default::default(), name: Default::default(), description: Default::default(), enable: true, priority: 500i64, } } } impl IntoValue for SpamRuleAny { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Condition, self.condition.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Priority, self.priority.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamRuleAny { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Condition) => self.condition.patch(pointer, value), Some(Property::Name) => self.name.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::Uppercase, StringValidator::RemoveSpaces]), value, ), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Priority) => self.priority.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamRuleBody { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.condition; value.validate(errors); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.priority; if *value > (99999) { errors.push(ValidationError::max_value(Property::Priority, 99999)); } if *value < (-99999) { errors.push(ValidationError::min_value(Property::Priority, -99999)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl SpamRuleBody { pub fn ctx_condition(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.condition, default: None, property: Property::Condition, allowed_variables: SPAM_GENERIC_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_condition()] } } impl Pickle for SpamRuleBody { fn pickle(&self, out: &mut Vec) { self.condition.pickle(out); self.name.pickle(out); self.description.pickle(out); self.enable.pickle(out); self.priority.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.condition = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.priority = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamRuleBody { fn default() -> Self { Self { condition: Default::default(), name: Default::default(), description: Default::default(), enable: true, priority: 500i64, } } } impl IntoValue for SpamRuleBody { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Condition, self.condition.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Priority, self.priority.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamRuleBody { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Condition) => self.condition.patch(pointer, value), Some(Property::Name) => self.name.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::Uppercase, StringValidator::RemoveSpaces]), value, ), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Priority) => self.priority.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamRuleDomain { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.condition; value.validate(errors); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.priority; if *value > (99999) { errors.push(ValidationError::max_value(Property::Priority, 99999)); } if *value < (-99999) { errors.push(ValidationError::min_value(Property::Priority, -99999)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl SpamRuleDomain { pub fn ctx_condition(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.condition, default: None, property: Property::Condition, allowed_variables: SPAM_GENERIC_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_condition()] } } impl Pickle for SpamRuleDomain { fn pickle(&self, out: &mut Vec) { self.condition.pickle(out); self.name.pickle(out); self.description.pickle(out); self.enable.pickle(out); self.priority.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.condition = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.priority = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamRuleDomain { fn default() -> Self { Self { condition: Default::default(), name: Default::default(), description: Default::default(), enable: true, priority: 500i64, } } } impl IntoValue for SpamRuleDomain { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Condition, self.condition.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Priority, self.priority.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamRuleDomain { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Condition) => self.condition.patch(pointer, value), Some(Property::Name) => self.name.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::Uppercase, StringValidator::RemoveSpaces]), value, ), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Priority) => self.priority.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamRuleEmail { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.condition; value.validate(errors); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.priority; if *value > (99999) { errors.push(ValidationError::max_value(Property::Priority, 99999)); } if *value < (-99999) { errors.push(ValidationError::min_value(Property::Priority, -99999)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl SpamRuleEmail { pub fn ctx_condition(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.condition, default: None, property: Property::Condition, allowed_variables: SPAM_EMAIL_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_condition()] } } impl Pickle for SpamRuleEmail { fn pickle(&self, out: &mut Vec) { self.condition.pickle(out); self.name.pickle(out); self.description.pickle(out); self.enable.pickle(out); self.priority.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.condition = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.priority = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamRuleEmail { fn default() -> Self { Self { condition: Default::default(), name: Default::default(), description: Default::default(), enable: true, priority: 500i64, } } } impl IntoValue for SpamRuleEmail { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Condition, self.condition.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Priority, self.priority.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamRuleEmail { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Condition) => self.condition.patch(pointer, value), Some(Property::Name) => self.name.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::Uppercase, StringValidator::RemoveSpaces]), value, ), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Priority) => self.priority.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamRuleHeader { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.condition; value.validate(errors); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.priority; if *value > (99999) { errors.push(ValidationError::max_value(Property::Priority, 99999)); } if *value < (-99999) { errors.push(ValidationError::min_value(Property::Priority, -99999)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl SpamRuleHeader { pub fn ctx_condition(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.condition, default: None, property: Property::Condition, allowed_variables: SPAM_HEADER_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_condition()] } } impl Pickle for SpamRuleHeader { fn pickle(&self, out: &mut Vec) { self.condition.pickle(out); self.name.pickle(out); self.description.pickle(out); self.enable.pickle(out); self.priority.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.condition = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.priority = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamRuleHeader { fn default() -> Self { Self { condition: Default::default(), name: Default::default(), description: Default::default(), enable: true, priority: 500i64, } } } impl IntoValue for SpamRuleHeader { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Condition, self.condition.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Priority, self.priority.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamRuleHeader { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Condition) => self.condition.patch(pointer, value), Some(Property::Name) => self.name.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::Uppercase, StringValidator::RemoveSpaces]), value, ), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Priority) => self.priority.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamRuleIp { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.condition; value.validate(errors); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.priority; if *value > (99999) { errors.push(ValidationError::max_value(Property::Priority, 99999)); } if *value < (-99999) { errors.push(ValidationError::min_value(Property::Priority, -99999)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl SpamRuleIp { pub fn ctx_condition(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.condition, default: None, property: Property::Condition, allowed_variables: SPAM_IP_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_condition()] } } impl Pickle for SpamRuleIp { fn pickle(&self, out: &mut Vec) { self.condition.pickle(out); self.name.pickle(out); self.description.pickle(out); self.enable.pickle(out); self.priority.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.condition = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.priority = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamRuleIp { fn default() -> Self { Self { condition: Default::default(), name: Default::default(), description: Default::default(), enable: true, priority: 500i64, } } } impl IntoValue for SpamRuleIp { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Condition, self.condition.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Priority, self.priority.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamRuleIp { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Condition) => self.condition.patch(pointer, value), Some(Property::Name) => self.name.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::Uppercase, StringValidator::RemoveSpaces]), value, ), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Priority) => self.priority.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamRuleUrl { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.condition; value.validate(errors); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.priority; if *value > (99999) { errors.push(ValidationError::max_value(Property::Priority, 99999)); } if *value < (-99999) { errors.push(ValidationError::min_value(Property::Priority, -99999)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Name, &self.name); } } impl SpamRuleUrl { pub fn ctx_condition(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.condition, default: None, property: Property::Condition, allowed_variables: SPAM_URL_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_condition()] } } impl Pickle for SpamRuleUrl { fn pickle(&self, out: &mut Vec) { self.condition.pickle(out); self.name.pickle(out); self.description.pickle(out); self.enable.pickle(out); self.priority.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.condition = Pickle::unpickle(stream)?; this.name = Pickle::unpickle(stream)?; this.description = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.priority = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamRuleUrl { fn default() -> Self { Self { condition: Default::default(), name: Default::default(), description: Default::default(), enable: true, priority: 500i64, } } } impl IntoValue for SpamRuleUrl { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Condition, self.condition.into_value()); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Priority, self.priority.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamRuleUrl { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Condition) => self.condition.patch(pointer, value), Some(Property::Name) => self.name.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::Uppercase, StringValidator::RemoveSpaces]), value, ), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Priority) => self.priority.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SpamSettings { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SpamSettings; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.score_discard; if *value > Float::new(100.0) { errors.push(ValidationError::max_value(Property::ScoreDiscard, 100)); } if *value < Float::new(-100.0) { errors.push(ValidationError::min_value(Property::ScoreDiscard, -100)); } let value = &self.score_reject; if *value > Float::new(100.0) { errors.push(ValidationError::max_value(Property::ScoreReject, 100)); } if *value < Float::new(-100.0) { errors.push(ValidationError::min_value(Property::ScoreReject, -100)); } let value = &self.score_spam; if *value > Float::new(100.0) { errors.push(ValidationError::max_value(Property::ScoreSpam, 100)); } if *value < Float::new(-100.0) { errors.push(ValidationError::min_value(Property::ScoreSpam, -100)); } if let Some(value) = &self.spam_filter_rules_url { if value.is_empty() { errors.push(ValidationError::required(Property::SpamFilterRulesUrl)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for SpamSettings { fn pickle(&self, out: &mut Vec) { self.trust_contacts.pickle(out); self.enable.pickle(out); self.greylist_for.pickle(out); self.score_discard.pickle(out); self.score_reject.pickle(out); self.score_spam.pickle(out); self.trust_replies.pickle(out); self.spam_filter_rules_url.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.trust_contacts = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.greylist_for = Pickle::unpickle(stream)?; this.score_discard = Pickle::unpickle(stream)?; this.score_reject = Pickle::unpickle(stream)?; this.score_spam = Pickle::unpickle(stream)?; this.trust_replies = Pickle::unpickle(stream)?; this.spam_filter_rules_url = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamSettings { fn default() -> Self { Self { trust_contacts: true, enable: true, greylist_for: Default::default(), score_discard: Float::new(0.0f64), score_reject: Float::new(0.0f64), score_spam: Float::new(5.0f64), trust_replies: true, spam_filter_rules_url: Some("https://github.com/stalwartlabs/spam-filter/releases/latest/download/spam-filter-rules.json.gz".to_string()), } } } impl IntoValue for SpamSettings { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(10); map.insert_unchecked(Property::TrustContacts, self.trust_contacts.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::GreylistFor, self.greylist_for.into_value()); map.insert_unchecked(Property::ScoreDiscard, self.score_discard.into_value()); map.insert_unchecked(Property::ScoreReject, self.score_reject.into_value()); map.insert_unchecked(Property::ScoreSpam, self.score_spam.into_value()); map.insert_unchecked(Property::TrustReplies, self.trust_replies.into_value()); map.insert_unchecked( Property::SpamFilterRulesUrl, self.spam_filter_rules_url.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamSettings { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::TrustContacts) => self.trust_contacts.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::GreylistFor) => self.greylist_for.patch(pointer, value), Some(Property::ScoreDiscard) => self.score_discard.patch(pointer, value), Some(Property::ScoreReject) => self.score_reject.patch(pointer, value), Some(Property::ScoreSpam) => self.score_spam.patch(pointer, value), Some(Property::TrustReplies) => self.trust_replies.patch(pointer, value), Some(Property::SpamFilterRulesUrl) => self .spam_filter_rules_url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SpamTag { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SpamTag; fn validate(&self, errors: &mut Vec) -> bool { match self { SpamTag::Score(inner) => inner.validate(errors), SpamTag::Discard(inner) => inner.validate(errors), SpamTag::Reject(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { SpamTag::Score(object) => { object.index(i); } SpamTag::Discard(object) => { object.index(i); } SpamTag::Reject(object) => { object.index(i); } } } } impl Default for SpamTag { fn default() -> Self { SpamTag::Score(Default::default()) } } impl Pickle for SpamTag { fn pickle(&self, out: &mut Vec) { match self { SpamTag::Score(inner) => { 0u16.pickle(out); inner.pickle(out); } SpamTag::Discard(inner) => { 1u16.pickle(out); inner.pickle(out); } SpamTag::Reject(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(SpamTag::Score), 1 => Pickle::unpickle(stream).map(SpamTag::Discard), 2 => Pickle::unpickle(stream).map(SpamTag::Reject), _ => None, } } } impl IntoValue for SpamTag { fn into_value(self) -> JmapValue<'static> { match self { SpamTag::Score(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Score".into())); obj } SpamTag::Discard(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Discard".into())); obj } SpamTag::Reject(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Reject".into())); obj } } } } impl RegistryJsonPatch for SpamTag { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { SpamTagType::Score => *self = SpamTag::Score(Default::default()), SpamTagType::Discard => *self = SpamTag::Discard(Default::default()), SpamTagType::Reject => *self = SpamTag::Reject(Default::default()), } } match self { SpamTag::Score(inner) => inner.patch(pointer, value), SpamTag::Discard(inner) => inner.patch(pointer, value), SpamTag::Reject(inner) => inner.patch(pointer, value), } } } impl SpamTag { pub fn object_type(&self) -> SpamTagType { match self { SpamTag::Score(_) => SpamTagType::Score, SpamTag::Discard(_) => SpamTagType::Discard, SpamTag::Reject(_) => SpamTagType::Reject, } } } impl SpamTagAction { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.tag; if value.is_empty() { errors.push(ValidationError::required(Property::Tag)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Tag, &self.tag); } } impl Pickle for SpamTagAction { fn pickle(&self, out: &mut Vec) { self.tag.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.tag = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamTagAction { fn default() -> Self { Self { tag: Default::default(), } } } impl IntoValue for SpamTagAction { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Tag, self.tag.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamTagAction { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Tag) => self.tag.patch( pointer .with_validators(&[StringValidator::RemoveSpaces, StringValidator::Uppercase]), value, ), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SpamTagScore { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.tag; if value.is_empty() { errors.push(ValidationError::required(Property::Tag)); } let value = &self.score; if *value < Float::new(-999999.0) { errors.push(ValidationError::min_value(Property::Score, -999999)); } if *value > Float::new(999999.0) { errors.push(ValidationError::max_value(Property::Score, 999999)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique(Property::Tag, &self.tag); } } impl Pickle for SpamTagScore { fn pickle(&self, out: &mut Vec) { self.tag.pickle(out); self.score.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.tag = Pickle::unpickle(stream)?; this.score = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamTagScore { fn default() -> Self { Self { tag: Default::default(), score: Float::new(0.0f64), } } } impl IntoValue for SpamTagScore { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Tag, self.tag.into_value()); map.insert_unchecked(Property::Score, self.score.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamTagScore { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Tag) => self.tag.patch( pointer .with_validators(&[StringValidator::RemoveSpaces, StringValidator::Uppercase]), value, ), Some(Property::Score) => self.score.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SpamTrainingSample { const FLAGS: u64 = OBJ_FILTER_ACCOUNT; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SpamTrainingSample; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.from; if value.is_empty() { errors.push(ValidationError::required(Property::From)); } let value = &self.subject; if value.is_empty() { errors.push(ValidationError::required(Property::Subject)); } let value = &self.blob_id; if value.is_empty() { errors.push(ValidationError::required(Property::BlobId)); } if let Some(value) = &self.account_id { if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } } let value = &self.expires_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ExpiresAt, value)); } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id, None); if let Some(value) = &self.account_id { i.search(Property::AccountId, value); } } } impl Pickle for SpamTrainingSample { fn pickle(&self, out: &mut Vec) { self.from.pickle(out); self.subject.pickle(out); self.blob_id.pickle(out); self.is_spam.pickle(out); self.account_id.pickle(out); self.expires_at.pickle(out); self.delete_after_use.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.from = Pickle::unpickle(stream)?; this.subject = Pickle::unpickle(stream)?; this.blob_id = Pickle::unpickle(stream)?; this.is_spam = Pickle::unpickle(stream)?; this.account_id = Pickle::unpickle(stream)?; this.expires_at = Pickle::unpickle(stream)?; this.delete_after_use = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpamTrainingSample { fn default() -> Self { Self { from: Default::default(), subject: Default::default(), blob_id: Default::default(), is_spam: false, account_id: Default::default(), expires_at: Default::default(), delete_after_use: false, } } } impl IntoValue for SpamTrainingSample { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked(Property::From, self.from.into_value()); map.insert_unchecked(Property::Subject, self.subject.into_value()); map.insert_unchecked(Property::BlobId, self.blob_id.into_value()); map.insert_unchecked(Property::IsSpam, self.is_spam.into_value()); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked(Property::ExpiresAt, self.expires_at.into_value()); map.insert_unchecked(Property::DeleteAfterUse, self.delete_after_use.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpamTrainingSample { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::From) => pointer.assert_server_set(), Some(Property::Subject) => pointer.assert_server_set(), Some(Property::BlobId) => self.blob_id.patch(pointer.assert_read_only()?, value), Some(Property::IsSpam) => self.is_spam.patch(pointer.assert_read_only()?, value), Some(Property::AccountId) => self .account_id .patch(pointer.assert_read_only()?.assert_can_set_account()?, value), Some(Property::ExpiresAt) => pointer.assert_server_set(), Some(Property::DeleteAfterUse) => self .delete_after_use .patch(pointer.assert_read_only()?, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SpfReportSettings { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SpfReportSettings; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.from_address; value.validate(errors); let value = &self.from_name; value.validate(errors); let value = &self.send_frequency; value.validate(errors); let value = &self.dkim_sign_domain; value.validate(errors); let value = &self.subject; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl SpfReportSettings { pub fn ctx_from_address(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.from_address, default: Some(Expression { else_: "'noreply-spf@' + system('domain')".to_string(), ..Default::default() }), property: Property::FromAddress, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_from_name(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.from_name, default: Some(Expression { else_: "'Report Subsystem'".to_string(), ..Default::default() }), property: Property::FromName, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_send_frequency(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.send_frequency, default: Some(Expression { else_: "[1, 1d]".to_string(), ..Default::default() }), property: Property::SendFrequency, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_dkim_sign_domain(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.dkim_sign_domain, default: Some(Expression { else_: "system('domain')".to_string(), ..Default::default() }), property: Property::DkimSignDomain, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn ctx_subject(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.subject, default: Some(Expression { else_: "'SPF Authentication Failure Report'".to_string(), ..Default::default() }), property: Property::Subject, allowed_variables: MTA_MAIL_FROM_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_from_address(), self.ctx_from_name(), self.ctx_send_frequency(), self.ctx_dkim_sign_domain(), self.ctx_subject(), ] } } impl Pickle for SpfReportSettings { fn pickle(&self, out: &mut Vec) { self.from_address.pickle(out); self.from_name.pickle(out); self.send_frequency.pickle(out); self.dkim_sign_domain.pickle(out); self.subject.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.from_address = Pickle::unpickle(stream)?; this.from_name = Pickle::unpickle(stream)?; this.send_frequency = Pickle::unpickle(stream)?; this.dkim_sign_domain = Pickle::unpickle(stream)?; this.subject = Pickle::unpickle(stream)?; Some(this) } } impl Default for SpfReportSettings { fn default() -> Self { Self { from_address: Expression { else_: "'noreply-spf@' + system('domain')".to_string(), ..Default::default() }, from_name: Expression { else_: "'Report Subsystem'".to_string(), ..Default::default() }, send_frequency: Expression { else_: "[1, 1d]".to_string(), ..Default::default() }, dkim_sign_domain: Expression { else_: "system('domain')".to_string(), ..Default::default() }, subject: Expression { else_: "'SPF Authentication Failure Report'".to_string(), ..Default::default() }, } } } impl IntoValue for SpfReportSettings { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::FromAddress, self.from_address.into_value()); map.insert_unchecked(Property::FromName, self.from_name.into_value()); map.insert_unchecked(Property::SendFrequency, self.send_frequency.into_value()); map.insert_unchecked(Property::DkimSignDomain, self.dkim_sign_domain.into_value()); map.insert_unchecked(Property::Subject, self.subject.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SpfReportSettings { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::FromAddress) => self.from_address.patch(pointer, value), Some(Property::FromName) => self.from_name.patch(pointer, value), Some(Property::SendFrequency) => self.send_frequency.patch(pointer, value), Some(Property::DkimSignDomain) => self.dkim_sign_domain.patch(pointer, value), Some(Property::Subject) => self.subject.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SqlAuthStore { fn validate(&self, errors: &mut Vec) -> bool { match self { SqlAuthStore::Default => true, SqlAuthStore::PostgreSql(inner) => inner.validate(errors), SqlAuthStore::MySql(inner) => inner.validate(errors), SqlAuthStore::Sqlite(inner) => inner.validate(errors), } } } impl Default for SqlAuthStore { fn default() -> Self { SqlAuthStore::Default } } impl Pickle for SqlAuthStore { fn pickle(&self, out: &mut Vec) { match self { SqlAuthStore::Default => { 0u16.pickle(out); } SqlAuthStore::PostgreSql(inner) => { 1u16.pickle(out); inner.pickle(out); } SqlAuthStore::MySql(inner) => { 2u16.pickle(out); inner.pickle(out); } SqlAuthStore::Sqlite(inner) => { 3u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(SqlAuthStore::Default), 1 => Pickle::unpickle(stream).map(SqlAuthStore::PostgreSql), 2 => Pickle::unpickle(stream).map(SqlAuthStore::MySql), 3 => Pickle::unpickle(stream).map(SqlAuthStore::Sqlite), _ => None, } } } impl IntoValue for SqlAuthStore { fn into_value(self) -> JmapValue<'static> { match self { SqlAuthStore::Default => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Default".into())); JmapValue::Object(obj) } SqlAuthStore::PostgreSql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("PostgreSql".into())); obj } SqlAuthStore::MySql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("MySql".into())); obj } SqlAuthStore::Sqlite(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Sqlite".into())); obj } } } } impl RegistryJsonPatch for SqlAuthStore { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { SqlAuthStoreType::Default => *self = SqlAuthStore::Default, SqlAuthStoreType::PostgreSql => { *self = SqlAuthStore::PostgreSql(Default::default()) } SqlAuthStoreType::MySql => *self = SqlAuthStore::MySql(Default::default()), SqlAuthStoreType::Sqlite => *self = SqlAuthStore::Sqlite(Default::default()), } } match self { SqlAuthStore::Default => pointer.assert_eof(), SqlAuthStore::PostgreSql(inner) => inner.patch(pointer, value), SqlAuthStore::MySql(inner) => inner.patch(pointer, value), SqlAuthStore::Sqlite(inner) => inner.patch(pointer, value), } } } impl SqlAuthStore { pub fn object_type(&self) -> SqlAuthStoreType { match self { SqlAuthStore::Default => SqlAuthStoreType::Default, SqlAuthStore::PostgreSql(_) => SqlAuthStoreType::PostgreSql, SqlAuthStore::MySql(_) => SqlAuthStoreType::MySql, SqlAuthStore::Sqlite(_) => SqlAuthStoreType::Sqlite, } } } impl SqlDirectory { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.description; if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } let value = &self.store; value.validate(errors); let value = &self.column_email; if value.is_empty() { errors.push(ValidationError::required(Property::ColumnEmail)); } let value = &self.column_secret; if value.is_empty() { errors.push(ValidationError::required(Property::ColumnSecret)); } if let Some(value) = &self.column_class { if value.is_empty() { errors.push(ValidationError::required(Property::ColumnClass)); } } if let Some(value) = &self.column_description { if value.is_empty() { errors.push(ValidationError::required(Property::ColumnDescription)); } } let value = &self.query_login; if value.is_empty() { errors.push(ValidationError::required(Property::QueryLogin)); } let value = &self.query_recipient; if value.is_empty() { errors.push(ValidationError::required(Property::QueryRecipient)); } if let Some(value) = &self.query_member_of { if value.is_empty() { errors.push(ValidationError::required(Property::QueryMemberOf)); } } if let Some(value) = &self.query_email_aliases { if value.is_empty() { errors.push(ValidationError::required(Property::QueryEmailAliases)); } } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } } } impl Pickle for SqlDirectory { fn pickle(&self, out: &mut Vec) { self.description.pickle(out); self.store.pickle(out); self.column_email.pickle(out); self.column_secret.pickle(out); self.column_class.pickle(out); self.column_description.pickle(out); self.query_login.pickle(out); self.query_recipient.pickle(out); self.query_member_of.pickle(out); self.query_email_aliases.pickle(out); self.member_tenant_id.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.description = Pickle::unpickle(stream)?; this.store = Pickle::unpickle(stream)?; this.column_email = Pickle::unpickle(stream)?; this.column_secret = Pickle::unpickle(stream)?; this.column_class = Pickle::unpickle(stream)?; this.column_description = Pickle::unpickle(stream)?; this.query_login = Pickle::unpickle(stream)?; this.query_recipient = Pickle::unpickle(stream)?; this.query_member_of = Pickle::unpickle(stream)?; this.query_email_aliases = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; Some(this) } } impl Default for SqlDirectory { fn default() -> Self { Self { description: Default::default(), store: Default::default(), column_email: "name".to_string(), column_secret: "secret".to_string(), column_class: Some("type".to_string()), column_description: Some("description".to_string()), query_login: "SELECT name, secret, description, type FROM accounts WHERE name = $1".to_string(), query_recipient: "SELECT name, secret, description, type FROM accounts WHERE name = $1 AND active = true".to_string(), query_member_of: Some("SELECT member_of FROM group_members WHERE name = $1".to_string()), query_email_aliases: Some("SELECT address FROM emails WHERE name = $1".to_string()), member_tenant_id: Default::default(), } } } impl IntoValue for SqlDirectory { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(13); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Store, self.store.into_value()); map.insert_unchecked(Property::ColumnEmail, self.column_email.into_value()); map.insert_unchecked(Property::ColumnSecret, self.column_secret.into_value()); map.insert_unchecked(Property::ColumnClass, self.column_class.into_value()); map.insert_unchecked( Property::ColumnDescription, self.column_description.into_value(), ); map.insert_unchecked(Property::QueryLogin, self.query_login.into_value()); map.insert_unchecked(Property::QueryRecipient, self.query_recipient.into_value()); map.insert_unchecked(Property::QueryMemberOf, self.query_member_of.into_value()); map.insert_unchecked( Property::QueryEmailAliases, self.query_email_aliases.into_value(), ); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SqlDirectory { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Description) => self .description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Store) => self.store.patch(pointer, value), Some(Property::ColumnEmail) => self .column_email .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ColumnSecret) => self .column_secret .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ColumnClass) => self .column_class .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::ColumnDescription) => self .column_description .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::QueryLogin) => self .query_login .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::QueryRecipient) => self .query_recipient .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::QueryMemberOf) => self .query_member_of .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::QueryEmailAliases) => self .query_email_aliases .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SqliteStore { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.path; if value.is_empty() { errors.push(ValidationError::required(Property::Path)); } if let Some(value) = &self.pool_workers { if *value > 64 { errors.push(ValidationError::max_value(Property::PoolWorkers, 64)); } if *value < 1 { errors.push(ValidationError::min_value(Property::PoolWorkers, 1)); } } let value = &self.pool_max_connections; if *value > 8192 { errors.push(ValidationError::max_value( Property::PoolMaxConnections, 8192, )); } if *value < 1 { errors.push(ValidationError::min_value(Property::PoolMaxConnections, 1)); } errors.len() == neb } } impl Pickle for SqliteStore { fn pickle(&self, out: &mut Vec) { self.path.pickle(out); self.pool_workers.pickle(out); self.pool_max_connections.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.path = Pickle::unpickle(stream)?; this.pool_workers = Pickle::unpickle(stream)?; this.pool_max_connections = Pickle::unpickle(stream)?; Some(this) } } impl Default for SqliteStore { fn default() -> Self { Self { path: Default::default(), pool_workers: Default::default(), pool_max_connections: 10u64, } } } impl IntoValue for SqliteStore { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::Path, self.path.into_value()); map.insert_unchecked(Property::PoolWorkers, self.pool_workers.into_value()); map.insert_unchecked( Property::PoolMaxConnections, self.pool_max_connections.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SqliteStore { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Path) => self .path .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::PoolWorkers) => self.pool_workers.patch(pointer, value), Some(Property::PoolMaxConnections) => self.pool_max_connections.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for StoreLookup { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::StoreLookup; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.namespace; if value.is_empty() { errors.push(ValidationError::required(Property::Namespace)); } let value = &self.store; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique_global(Property::Namespace, &self.namespace); } } impl Pickle for StoreLookup { fn pickle(&self, out: &mut Vec) { self.namespace.pickle(out); self.store.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.namespace = Pickle::unpickle(stream)?; this.store = Pickle::unpickle(stream)?; Some(this) } } impl Default for StoreLookup { fn default() -> Self { Self { namespace: Default::default(), store: Default::default(), } } } impl IntoValue for StoreLookup { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Namespace, self.namespace.into_value()); map.insert_unchecked(Property::Store, self.store.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for StoreLookup { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Namespace) => self.namespace.patch( pointer .assert_read_only()? .with_validators(&[StringValidator::Trim]), value, ), Some(Property::Store) => self.store.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl SubAddressing { fn validate(&self, errors: &mut Vec) -> bool { match self { SubAddressing::Enabled => true, SubAddressing::Custom(inner) => inner.validate(errors), SubAddressing::Disabled => true, } } } impl Default for SubAddressing { fn default() -> Self { SubAddressing::Enabled } } impl Pickle for SubAddressing { fn pickle(&self, out: &mut Vec) { match self { SubAddressing::Enabled => { 0u16.pickle(out); } SubAddressing::Custom(inner) => { 1u16.pickle(out); inner.pickle(out); } SubAddressing::Disabled => { 2u16.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(SubAddressing::Enabled), 1 => Pickle::unpickle(stream).map(SubAddressing::Custom), 2 => Some(SubAddressing::Disabled), _ => None, } } } impl IntoValue for SubAddressing { fn into_value(self) -> JmapValue<'static> { match self { SubAddressing::Enabled => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Enabled".into())); JmapValue::Object(obj) } SubAddressing::Custom(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Custom".into())); obj } SubAddressing::Disabled => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Disabled".into())); JmapValue::Object(obj) } } } } impl RegistryJsonPatch for SubAddressing { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { SubAddressingType::Enabled => *self = SubAddressing::Enabled, SubAddressingType::Custom => *self = SubAddressing::Custom(Default::default()), SubAddressingType::Disabled => *self = SubAddressing::Disabled, } } match self { SubAddressing::Enabled => pointer.assert_eof(), SubAddressing::Custom(inner) => inner.patch(pointer, value), SubAddressing::Disabled => pointer.assert_eof(), } } } impl SubAddressing { pub fn object_type(&self) -> SubAddressingType { match self { SubAddressing::Enabled => SubAddressingType::Enabled, SubAddressing::Custom(_) => SubAddressingType::Custom, SubAddressing::Disabled => SubAddressingType::Disabled, } } pub fn expression_ctxs(&self) -> Vec> { match self { SubAddressing::Custom(obj) => obj.expression_ctxs(), _ => vec![], } } } impl SubAddressingCustom { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.custom_rule; value.validate(errors); errors.len() == neb } } impl SubAddressingCustom { pub fn ctx_custom_rule(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.custom_rule, default: None, property: Property::CustomRule, allowed_variables: MTA_RCPT_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![self.ctx_custom_rule()] } } impl Pickle for SubAddressingCustom { fn pickle(&self, out: &mut Vec) { self.custom_rule.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.custom_rule = Pickle::unpickle(stream)?; Some(this) } } impl Default for SubAddressingCustom { fn default() -> Self { Self { custom_rule: Default::default(), } } } impl IntoValue for SubAddressingCustom { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::CustomRule, self.custom_rule.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SubAddressingCustom { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::CustomRule) => self.custom_rule.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for SystemSettings { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::SystemSettings; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.default_hostname; if value.is_empty() { errors.push(ValidationError::required(Property::DefaultHostname)); } let value = &self.default_domain_id; if !value.is_valid() { errors.push(ValidationError::required(Property::DefaultDomainId)); } if let Some(value) = &self.default_certificate_id { if !value.is_valid() { errors.push(ValidationError::required(Property::DefaultCertificateId)); } } if let Some(value) = &self.thread_pool_size { if *value < 1 { errors.push(ValidationError::min_value(Property::ThreadPoolSize, 1)); } } let value = &self.max_connections; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxConnections, 1)); } let value = &self.proxy_trusted_networks; for value in value.iter() { if !value.is_valid() { errors.push(ValidationError::invalid( Property::ProxyTrustedNetworks, value, )); } } let value = &self.mail_exchangers; for value in value.values() { value.validate(errors); } let value = &self.services; for value in value.values() { value.validate(errors); } let value = &self.provider_info; for value in value.values() { if value.is_empty() { errors.push(ValidationError::required(Property::ProviderInfo)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Domain, self.default_domain_id.into(), None); i.foreign_key(ObjectType::Certificate, self.default_certificate_id, None); } } impl Pickle for SystemSettings { fn pickle(&self, out: &mut Vec) { self.default_hostname.pickle(out); self.default_domain_id.pickle(out); self.default_certificate_id.pickle(out); self.thread_pool_size.pickle(out); self.max_connections.pickle(out); self.proxy_trusted_networks.pickle(out); self.mail_exchangers.pickle(out); self.services.pickle(out); self.provider_info.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.default_hostname = Pickle::unpickle(stream)?; this.default_domain_id = Pickle::unpickle(stream)?; this.default_certificate_id = Pickle::unpickle(stream)?; this.thread_pool_size = Pickle::unpickle(stream)?; this.max_connections = Pickle::unpickle(stream)?; this.proxy_trusted_networks = Pickle::unpickle(stream)?; this.mail_exchangers = Pickle::unpickle(stream)?; this.services = Pickle::unpickle(stream)?; this.provider_info = Pickle::unpickle(stream)?; Some(this) } } impl Default for SystemSettings { fn default() -> Self { Self { default_hostname: Default::default(), default_domain_id: Default::default(), default_certificate_id: Default::default(), thread_pool_size: Default::default(), max_connections: 8192u64, proxy_trusted_networks: Default::default(), mail_exchangers: List::from_iter([MailExchanger { priority: 10u64, ..Default::default() }]), services: VecMap::from_iter([ ( ServiceProtocol::Caldav, Service { cleartext: false, ..Default::default() }, ), ( ServiceProtocol::Carddav, Service { cleartext: false, ..Default::default() }, ), ( ServiceProtocol::Imap, Service { cleartext: false, ..Default::default() }, ), ( ServiceProtocol::Jmap, Service { cleartext: false, ..Default::default() }, ), ( ServiceProtocol::Managesieve, Service { cleartext: false, ..Default::default() }, ), ( ServiceProtocol::Pop3, Service { cleartext: false, ..Default::default() }, ), ( ServiceProtocol::Smtp, Service { cleartext: false, ..Default::default() }, ), ( ServiceProtocol::Webdav, Service { cleartext: false, ..Default::default() }, ), ]), provider_info: Default::default(), } } } impl IntoValue for SystemSettings { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked( Property::DefaultHostname, self.default_hostname.into_value(), ); map.insert_unchecked( Property::DefaultDomainId, self.default_domain_id.into_value(), ); map.insert_unchecked( Property::DefaultCertificateId, self.default_certificate_id.into_value(), ); map.insert_unchecked(Property::ThreadPoolSize, self.thread_pool_size.into_value()); map.insert_unchecked(Property::MaxConnections, self.max_connections.into_value()); map.insert_unchecked( Property::ProxyTrustedNetworks, self.proxy_trusted_networks.into_value(), ); map.insert_unchecked(Property::MailExchangers, self.mail_exchangers.into_value()); map.insert_unchecked(Property::Services, self.services.into_value()); map.insert_unchecked(Property::ProviderInfo, self.provider_info.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for SystemSettings { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::DefaultHostname) => self .default_hostname .patch(pointer.with_validators(&[StringValidator::Hostname]), value), Some(Property::DefaultDomainId) => self.default_domain_id.patch(pointer, value), Some(Property::DefaultCertificateId) => { self.default_certificate_id.patch(pointer, value) } Some(Property::ThreadPoolSize) => self.thread_pool_size.patch(pointer, value), Some(Property::MaxConnections) => self.max_connections.patch(pointer, value), Some(Property::ProxyTrustedNetworks) => self .proxy_trusted_networks .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::MailExchangers) => self.mail_exchangers.patch(pointer, value), Some(Property::Services) => self.services.patch(pointer, value), Some(Property::ProviderInfo) => self.provider_info.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Task { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Task; fn validate(&self, errors: &mut Vec) -> bool { match self { Task::IndexDocument(inner) => inner.validate(errors), Task::UnindexDocument(inner) => inner.validate(errors), Task::IndexTrace(inner) => inner.validate(errors), Task::CalendarAlarmEmail(inner) => inner.validate(errors), Task::CalendarAlarmNotification(inner) => inner.validate(errors), Task::CalendarItipMessage(inner) => inner.validate(errors), Task::MergeThreads(inner) => inner.validate(errors), Task::DmarcReport(inner) => inner.validate(errors), Task::TlsReport(inner) => inner.validate(errors), Task::RestoreArchivedItem(inner) => inner.validate(errors), Task::DestroyAccount(inner) => inner.validate(errors), Task::AccountMaintenance(inner) => inner.validate(errors), Task::TenantMaintenance(inner) => inner.validate(errors), Task::StoreMaintenance(inner) => inner.validate(errors), Task::SpamFilterMaintenance(inner) => inner.validate(errors), Task::AcmeRenewal(inner) => inner.validate(errors), Task::DkimManagement(inner) => inner.validate(errors), Task::DnsManagement(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { Task::IndexDocument(object) => { object.index(i); } Task::UnindexDocument(object) => { object.index(i); } Task::IndexTrace(object) => { object.index(i); } Task::CalendarAlarmEmail(object) => { object.index(i); } Task::CalendarAlarmNotification(object) => { object.index(i); } Task::CalendarItipMessage(object) => { object.index(i); } Task::MergeThreads(object) => { object.index(i); } Task::DmarcReport(object) => { object.index(i); } Task::TlsReport(object) => { object.index(i); } Task::RestoreArchivedItem(object) => { object.index(i); } Task::DestroyAccount(object) => { object.index(i); } Task::AccountMaintenance(object) => { object.index(i); } Task::TenantMaintenance(object) => { object.index(i); } Task::StoreMaintenance(_) => {} Task::SpamFilterMaintenance(_) => {} Task::AcmeRenewal(object) => { object.index(i); } Task::DkimManagement(object) => { object.index(i); } Task::DnsManagement(object) => { object.index(i); } } } } impl Default for Task { fn default() -> Self { Task::IndexDocument(Default::default()) } } impl Pickle for Task { fn pickle(&self, out: &mut Vec) { match self { Task::IndexDocument(inner) => { 0u16.pickle(out); inner.pickle(out); } Task::UnindexDocument(inner) => { 1u16.pickle(out); inner.pickle(out); } Task::IndexTrace(inner) => { 2u16.pickle(out); inner.pickle(out); } Task::CalendarAlarmEmail(inner) => { 3u16.pickle(out); inner.pickle(out); } Task::CalendarAlarmNotification(inner) => { 4u16.pickle(out); inner.pickle(out); } Task::CalendarItipMessage(inner) => { 5u16.pickle(out); inner.pickle(out); } Task::MergeThreads(inner) => { 6u16.pickle(out); inner.pickle(out); } Task::DmarcReport(inner) => { 7u16.pickle(out); inner.pickle(out); } Task::TlsReport(inner) => { 8u16.pickle(out); inner.pickle(out); } Task::RestoreArchivedItem(inner) => { 9u16.pickle(out); inner.pickle(out); } Task::DestroyAccount(inner) => { 10u16.pickle(out); inner.pickle(out); } Task::AccountMaintenance(inner) => { 11u16.pickle(out); inner.pickle(out); } Task::TenantMaintenance(inner) => { 12u16.pickle(out); inner.pickle(out); } Task::StoreMaintenance(inner) => { 13u16.pickle(out); inner.pickle(out); } Task::SpamFilterMaintenance(inner) => { 14u16.pickle(out); inner.pickle(out); } Task::AcmeRenewal(inner) => { 15u16.pickle(out); inner.pickle(out); } Task::DkimManagement(inner) => { 16u16.pickle(out); inner.pickle(out); } Task::DnsManagement(inner) => { 17u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(Task::IndexDocument), 1 => Pickle::unpickle(stream).map(Task::UnindexDocument), 2 => Pickle::unpickle(stream).map(Task::IndexTrace), 3 => Pickle::unpickle(stream).map(Task::CalendarAlarmEmail), 4 => Pickle::unpickle(stream).map(Task::CalendarAlarmNotification), 5 => Pickle::unpickle(stream).map(Task::CalendarItipMessage), 6 => Pickle::unpickle(stream).map(Task::MergeThreads), 7 => Pickle::unpickle(stream).map(Task::DmarcReport), 8 => Pickle::unpickle(stream).map(Task::TlsReport), 9 => Pickle::unpickle(stream).map(Task::RestoreArchivedItem), 10 => Pickle::unpickle(stream).map(Task::DestroyAccount), 11 => Pickle::unpickle(stream).map(Task::AccountMaintenance), 12 => Pickle::unpickle(stream).map(Task::TenantMaintenance), 13 => Pickle::unpickle(stream).map(Task::StoreMaintenance), 14 => Pickle::unpickle(stream).map(Task::SpamFilterMaintenance), 15 => Pickle::unpickle(stream).map(Task::AcmeRenewal), 16 => Pickle::unpickle(stream).map(Task::DkimManagement), 17 => Pickle::unpickle(stream).map(Task::DnsManagement), _ => None, } } } impl IntoValue for Task { fn into_value(self) -> JmapValue<'static> { match self { Task::IndexDocument(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("IndexDocument".into())); obj } Task::UnindexDocument(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("UnindexDocument".into())); obj } Task::IndexTrace(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("IndexTrace".into())); obj } Task::CalendarAlarmEmail(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("CalendarAlarmEmail".into())); obj } Task::CalendarAlarmNotification(obj) => { let mut obj = obj.into_value(); obj.as_object_mut().unwrap().insert_unchecked( Property::Type, JmapValue::Str("CalendarAlarmNotification".into()), ); obj } Task::CalendarItipMessage(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("CalendarItipMessage".into())); obj } Task::MergeThreads(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("MergeThreads".into())); obj } Task::DmarcReport(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("DmarcReport".into())); obj } Task::TlsReport(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("TlsReport".into())); obj } Task::RestoreArchivedItem(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("RestoreArchivedItem".into())); obj } Task::DestroyAccount(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("DestroyAccount".into())); obj } Task::AccountMaintenance(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("AccountMaintenance".into())); obj } Task::TenantMaintenance(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("TenantMaintenance".into())); obj } Task::StoreMaintenance(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("StoreMaintenance".into())); obj } Task::SpamFilterMaintenance(obj) => { let mut obj = obj.into_value(); obj.as_object_mut().unwrap().insert_unchecked( Property::Type, JmapValue::Str("SpamFilterMaintenance".into()), ); obj } Task::AcmeRenewal(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("AcmeRenewal".into())); obj } Task::DkimManagement(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("DkimManagement".into())); obj } Task::DnsManagement(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("DnsManagement".into())); obj } } } } impl RegistryJsonPatch for Task { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { TaskType::IndexDocument => *self = Task::IndexDocument(Default::default()), TaskType::UnindexDocument => *self = Task::UnindexDocument(Default::default()), TaskType::IndexTrace => *self = Task::IndexTrace(Default::default()), TaskType::CalendarAlarmEmail => { *self = Task::CalendarAlarmEmail(Default::default()) } TaskType::CalendarAlarmNotification => { *self = Task::CalendarAlarmNotification(Default::default()) } TaskType::CalendarItipMessage => { *self = Task::CalendarItipMessage(Default::default()) } TaskType::MergeThreads => *self = Task::MergeThreads(Default::default()), TaskType::DmarcReport => *self = Task::DmarcReport(Default::default()), TaskType::TlsReport => *self = Task::TlsReport(Default::default()), TaskType::RestoreArchivedItem => { *self = Task::RestoreArchivedItem(Default::default()) } TaskType::DestroyAccount => *self = Task::DestroyAccount(Default::default()), TaskType::AccountMaintenance => { *self = Task::AccountMaintenance(Default::default()) } TaskType::TenantMaintenance => *self = Task::TenantMaintenance(Default::default()), TaskType::StoreMaintenance => *self = Task::StoreMaintenance(Default::default()), TaskType::SpamFilterMaintenance => { *self = Task::SpamFilterMaintenance(Default::default()) } TaskType::AcmeRenewal => *self = Task::AcmeRenewal(Default::default()), TaskType::DkimManagement => *self = Task::DkimManagement(Default::default()), TaskType::DnsManagement => *self = Task::DnsManagement(Default::default()), } } match self { Task::IndexDocument(inner) => inner.patch(pointer, value), Task::UnindexDocument(inner) => inner.patch(pointer, value), Task::IndexTrace(inner) => inner.patch(pointer, value), Task::CalendarAlarmEmail(inner) => inner.patch(pointer, value), Task::CalendarAlarmNotification(inner) => inner.patch(pointer, value), Task::CalendarItipMessage(inner) => inner.patch(pointer, value), Task::MergeThreads(inner) => inner.patch(pointer, value), Task::DmarcReport(inner) => inner.patch(pointer, value), Task::TlsReport(inner) => inner.patch(pointer, value), Task::RestoreArchivedItem(inner) => inner.patch(pointer, value), Task::DestroyAccount(inner) => inner.patch(pointer, value), Task::AccountMaintenance(inner) => inner.patch(pointer, value), Task::TenantMaintenance(inner) => inner.patch(pointer, value), Task::StoreMaintenance(inner) => inner.patch(pointer, value), Task::SpamFilterMaintenance(inner) => inner.patch(pointer, value), Task::AcmeRenewal(inner) => inner.patch(pointer, value), Task::DkimManagement(inner) => inner.patch(pointer, value), Task::DnsManagement(inner) => inner.patch(pointer, value), } } } impl Task { pub fn object_type(&self) -> TaskType { match self { Task::IndexDocument(_) => TaskType::IndexDocument, Task::UnindexDocument(_) => TaskType::UnindexDocument, Task::IndexTrace(_) => TaskType::IndexTrace, Task::CalendarAlarmEmail(_) => TaskType::CalendarAlarmEmail, Task::CalendarAlarmNotification(_) => TaskType::CalendarAlarmNotification, Task::CalendarItipMessage(_) => TaskType::CalendarItipMessage, Task::MergeThreads(_) => TaskType::MergeThreads, Task::DmarcReport(_) => TaskType::DmarcReport, Task::TlsReport(_) => TaskType::TlsReport, Task::RestoreArchivedItem(_) => TaskType::RestoreArchivedItem, Task::DestroyAccount(_) => TaskType::DestroyAccount, Task::AccountMaintenance(_) => TaskType::AccountMaintenance, Task::TenantMaintenance(_) => TaskType::TenantMaintenance, Task::StoreMaintenance(_) => TaskType::StoreMaintenance, Task::SpamFilterMaintenance(_) => TaskType::SpamFilterMaintenance, Task::AcmeRenewal(_) => TaskType::AcmeRenewal, Task::DkimManagement(_) => TaskType::DkimManagement, Task::DnsManagement(_) => TaskType::DnsManagement, } } } impl TaskAccountMaintenance { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.account_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } let value = &self.status; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id.into(), None); } } impl Pickle for TaskAccountMaintenance { fn pickle(&self, out: &mut Vec) { self.account_id.pickle(out); self.maintenance_type.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.account_id = Pickle::unpickle(stream)?; this.maintenance_type = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskAccountMaintenance { fn default() -> Self { Self { account_id: Default::default(), maintenance_type: Default::default(), status: Default::default(), } } } impl IntoValue for TaskAccountMaintenance { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked( Property::MaintenanceType, self.maintenance_type.into_value(), ); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskAccountMaintenance { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AccountId) => self .account_id .patch(pointer.assert_read_only()?.assert_can_set_account()?, value), Some(Property::MaintenanceType) => self .maintenance_type .patch(pointer.assert_read_only()?, value), Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskCalendarAlarmEmail { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.event_start; if !value.is_valid() { errors.push(ValidationError::invalid(Property::EventStart, value)); } let value = &self.event_end; if !value.is_valid() { errors.push(ValidationError::invalid(Property::EventEnd, value)); } let value = &self.account_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } let value = &self.document_id; if !value.is_valid() { errors.push(ValidationError::invalid(Property::DocumentId, value)); } let value = &self.status; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id.into(), None); } } impl Pickle for TaskCalendarAlarmEmail { fn pickle(&self, out: &mut Vec) { self.alarm_id.pickle(out); self.event_id.pickle(out); self.event_start.pickle(out); self.event_end.pickle(out); self.event_start_tz.pickle(out); self.event_end_tz.pickle(out); self.account_id.pickle(out); self.document_id.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.alarm_id = Pickle::unpickle(stream)?; this.event_id = Pickle::unpickle(stream)?; this.event_start = Pickle::unpickle(stream)?; this.event_end = Pickle::unpickle(stream)?; this.event_start_tz = Pickle::unpickle(stream)?; this.event_end_tz = Pickle::unpickle(stream)?; this.account_id = Pickle::unpickle(stream)?; this.document_id = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskCalendarAlarmEmail { fn default() -> Self { Self { alarm_id: 0u64, event_id: 0u64, event_start: Default::default(), event_end: Default::default(), event_start_tz: 0u64, event_end_tz: 0u64, account_id: Default::default(), document_id: Default::default(), status: Default::default(), } } } impl IntoValue for TaskCalendarAlarmEmail { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(11); map.insert_unchecked(Property::AlarmId, self.alarm_id.into_value()); map.insert_unchecked(Property::EventId, self.event_id.into_value()); map.insert_unchecked(Property::EventStart, self.event_start.into_value()); map.insert_unchecked(Property::EventEnd, self.event_end.into_value()); map.insert_unchecked(Property::EventStartTz, self.event_start_tz.into_value()); map.insert_unchecked(Property::EventEndTz, self.event_end_tz.into_value()); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked(Property::DocumentId, self.document_id.into_value()); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskCalendarAlarmEmail { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AlarmId) => pointer.assert_server_set(), Some(Property::EventId) => pointer.assert_server_set(), Some(Property::EventStart) => pointer.assert_server_set(), Some(Property::EventEnd) => pointer.assert_server_set(), Some(Property::EventStartTz) => pointer.assert_server_set(), Some(Property::EventEndTz) => pointer.assert_server_set(), Some(Property::AccountId) => self .account_id .patch(pointer.assert_read_only()?.assert_can_set_account()?, value), Some(Property::DocumentId) => { self.document_id.patch(pointer.assert_read_only()?, value) } Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskCalendarAlarmNotification { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.account_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } let value = &self.document_id; if !value.is_valid() { errors.push(ValidationError::invalid(Property::DocumentId, value)); } let value = &self.status; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id.into(), None); } } impl Pickle for TaskCalendarAlarmNotification { fn pickle(&self, out: &mut Vec) { self.alarm_id.pickle(out); self.event_id.pickle(out); self.recurrence_id.pickle(out); self.account_id.pickle(out); self.document_id.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.alarm_id = Pickle::unpickle(stream)?; this.event_id = Pickle::unpickle(stream)?; this.recurrence_id = Pickle::unpickle(stream)?; this.account_id = Pickle::unpickle(stream)?; this.document_id = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskCalendarAlarmNotification { fn default() -> Self { Self { alarm_id: 0u64, event_id: 0u64, recurrence_id: Default::default(), account_id: Default::default(), document_id: Default::default(), status: Default::default(), } } } impl IntoValue for TaskCalendarAlarmNotification { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::AlarmId, self.alarm_id.into_value()); map.insert_unchecked(Property::EventId, self.event_id.into_value()); map.insert_unchecked(Property::RecurrenceId, self.recurrence_id.into_value()); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked(Property::DocumentId, self.document_id.into_value()); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskCalendarAlarmNotification { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AlarmId) => pointer.assert_server_set(), Some(Property::EventId) => pointer.assert_server_set(), Some(Property::RecurrenceId) => pointer.assert_server_set(), Some(Property::AccountId) => self .account_id .patch(pointer.assert_read_only()?.assert_can_set_account()?, value), Some(Property::DocumentId) => { self.document_id.patch(pointer.assert_read_only()?, value) } Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskCalendarItipContents { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.from; if value.is_empty() { errors.push(ValidationError::required(Property::From)); } let value = &self.to; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::To)); } } let value = &self.i_calendar_data; if value.is_empty() { errors.push(ValidationError::required(Property::ICalendarData)); } let value = &self.summary; if value.is_empty() { errors.push(ValidationError::required(Property::Summary)); } errors.len() == neb } } impl Pickle for TaskCalendarItipContents { fn pickle(&self, out: &mut Vec) { self.from.pickle(out); self.to.pickle(out); self.is_from_organizer.pickle(out); self.i_calendar_data.pickle(out); self.summary.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.from = Pickle::unpickle(stream)?; this.to = Pickle::unpickle(stream)?; this.is_from_organizer = Pickle::unpickle(stream)?; this.i_calendar_data = Pickle::unpickle(stream)?; this.summary = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskCalendarItipContents { fn default() -> Self { Self { from: Default::default(), to: Default::default(), is_from_organizer: false, i_calendar_data: Default::default(), summary: Default::default(), } } } impl IntoValue for TaskCalendarItipContents { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::From, self.from.into_value()); map.insert_unchecked(Property::To, self.to.into_value()); map.insert_unchecked( Property::IsFromOrganizer, self.is_from_organizer.into_value(), ); map.insert_unchecked(Property::ICalendarData, self.i_calendar_data.into_value()); map.insert_unchecked(Property::Summary, self.summary.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskCalendarItipContents { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::From) => pointer.assert_server_set(), Some(Property::To) => pointer.assert_server_set(), Some(Property::IsFromOrganizer) => pointer.assert_server_set(), Some(Property::ICalendarData) => pointer.assert_server_set(), Some(Property::Summary) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskCalendarItipMessage { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.messages; for value in value.values() { value.validate(errors); } let value = &self.account_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } let value = &self.document_id; if !value.is_valid() { errors.push(ValidationError::invalid(Property::DocumentId, value)); } let value = &self.status; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id.into(), None); } } impl Pickle for TaskCalendarItipMessage { fn pickle(&self, out: &mut Vec) { self.messages.pickle(out); self.account_id.pickle(out); self.document_id.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.messages = Pickle::unpickle(stream)?; this.account_id = Pickle::unpickle(stream)?; this.document_id = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskCalendarItipMessage { fn default() -> Self { Self { messages: Default::default(), account_id: Default::default(), document_id: Default::default(), status: Default::default(), } } } impl IntoValue for TaskCalendarItipMessage { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Messages, self.messages.into_value()); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked(Property::DocumentId, self.document_id.into_value()); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskCalendarItipMessage { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Messages) => pointer.assert_server_set(), Some(Property::AccountId) => self .account_id .patch(pointer.assert_read_only()?.assert_can_set_account()?, value), Some(Property::DocumentId) => { self.document_id.patch(pointer.assert_read_only()?, value) } Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskDestroyAccount { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.account_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } let value = &self.account_name; if value.is_empty() { errors.push(ValidationError::required(Property::AccountName)); } let value = &self.account_domain_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountDomainId)); } let value = &self.status; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id.into(), None); i.foreign_key(ObjectType::Domain, self.account_domain_id.into(), None); } } impl Pickle for TaskDestroyAccount { fn pickle(&self, out: &mut Vec) { self.account_id.pickle(out); self.account_name.pickle(out); self.account_domain_id.pickle(out); self.account_type.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.account_id = Pickle::unpickle(stream)?; this.account_name = Pickle::unpickle(stream)?; this.account_domain_id = Pickle::unpickle(stream)?; this.account_type = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskDestroyAccount { fn default() -> Self { Self { account_id: Default::default(), account_name: Default::default(), account_domain_id: Default::default(), account_type: Default::default(), status: Default::default(), } } } impl IntoValue for TaskDestroyAccount { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked(Property::AccountName, self.account_name.into_value()); map.insert_unchecked( Property::AccountDomainId, self.account_domain_id.into_value(), ); map.insert_unchecked(Property::AccountType, self.account_type.into_value()); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskDestroyAccount { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AccountId) => pointer.assert_server_set(), Some(Property::AccountName) => self.account_name.patch(pointer, value), Some(Property::AccountDomainId) => self.account_domain_id.patch(pointer, value), Some(Property::AccountType) => pointer.assert_server_set(), Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskDmarcReport { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.report_id; if !value.is_valid() { errors.push(ValidationError::required(Property::ReportId)); } let value = &self.status; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::DmarcInternalReport, self.report_id.into(), None); } } impl Pickle for TaskDmarcReport { fn pickle(&self, out: &mut Vec) { self.report_id.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.report_id = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskDmarcReport { fn default() -> Self { Self { report_id: Default::default(), status: Default::default(), } } } impl IntoValue for TaskDmarcReport { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::ReportId, self.report_id.into_value()); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskDmarcReport { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ReportId) => pointer.assert_server_set(), Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskDnsManagement { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.domain_id; if !value.is_valid() { errors.push(ValidationError::required(Property::DomainId)); } let value = &self.status; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Domain, self.domain_id.into(), None); } } impl Pickle for TaskDnsManagement { fn pickle(&self, out: &mut Vec) { self.update_records.pickle(out); self.on_success_renew_certificate.pickle(out); self.domain_id.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.update_records = Pickle::unpickle(stream)?; this.on_success_renew_certificate = Pickle::unpickle(stream)?; this.domain_id = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskDnsManagement { fn default() -> Self { Self { update_records: Default::default(), on_success_renew_certificate: false, domain_id: Default::default(), status: Default::default(), } } } impl IntoValue for TaskDnsManagement { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::UpdateRecords, self.update_records.into_value()); map.insert_unchecked( Property::OnSuccessRenewCertificate, self.on_success_renew_certificate.into_value(), ); map.insert_unchecked(Property::DomainId, self.domain_id.into_value()); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskDnsManagement { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::UpdateRecords) => self.update_records.patch(pointer, value), Some(Property::OnSuccessRenewCertificate) => { self.on_success_renew_certificate.patch(pointer, value) } Some(Property::DomainId) => self.domain_id.patch(pointer.assert_read_only()?, value), Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskDomainManagement { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.domain_id; if !value.is_valid() { errors.push(ValidationError::required(Property::DomainId)); } let value = &self.status; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Domain, self.domain_id.into(), None); } } impl Pickle for TaskDomainManagement { fn pickle(&self, out: &mut Vec) { self.domain_id.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.domain_id = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskDomainManagement { fn default() -> Self { Self { domain_id: Default::default(), status: Default::default(), } } } impl IntoValue for TaskDomainManagement { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::DomainId, self.domain_id.into_value()); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskDomainManagement { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::DomainId) => self.domain_id.patch(pointer.assert_read_only()?, value), Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskIndexDocument { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.account_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } let value = &self.document_id; if !value.is_valid() { errors.push(ValidationError::invalid(Property::DocumentId, value)); } let value = &self.status; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id.into(), None); } } impl Pickle for TaskIndexDocument { fn pickle(&self, out: &mut Vec) { self.document_type.pickle(out); self.account_id.pickle(out); self.document_id.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.document_type = Pickle::unpickle(stream)?; this.account_id = Pickle::unpickle(stream)?; this.document_id = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskIndexDocument { fn default() -> Self { Self { document_type: Default::default(), account_id: Default::default(), document_id: Default::default(), status: Default::default(), } } } impl IntoValue for TaskIndexDocument { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::DocumentType, self.document_type.into_value()); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked(Property::DocumentId, self.document_id.into_value()); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskIndexDocument { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::DocumentType) => { self.document_type.patch(pointer.assert_read_only()?, value) } Some(Property::AccountId) => self .account_id .patch(pointer.assert_read_only()?.assert_can_set_account()?, value), Some(Property::DocumentId) => { self.document_id.patch(pointer.assert_read_only()?, value) } Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskIndexTrace { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.trace_id; if !value.is_valid() { errors.push(ValidationError::required(Property::TraceId)); } let value = &self.status; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Trace, self.trace_id.into(), None); } } impl Pickle for TaskIndexTrace { fn pickle(&self, out: &mut Vec) { self.trace_id.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.trace_id = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskIndexTrace { fn default() -> Self { Self { trace_id: Default::default(), status: Default::default(), } } } impl IntoValue for TaskIndexTrace { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::TraceId, self.trace_id.into_value()); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskIndexTrace { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::TraceId) => self.trace_id.patch(pointer.assert_read_only()?, value), Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for TaskManager { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::TaskManager; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.max_attempts; if *value < 1 { errors.push(ValidationError::min_value(Property::MaxAttempts, 1)); } let value = &self.strategy; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for TaskManager { fn pickle(&self, out: &mut Vec) { self.max_attempts.pickle(out); self.strategy.pickle(out); self.total_deadline.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.max_attempts = Pickle::unpickle(stream)?; this.strategy = Pickle::unpickle(stream)?; this.total_deadline = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskManager { fn default() -> Self { Self { max_attempts: 3u64, strategy: Default::default(), total_deadline: Duration::from_millis(21600000), } } } impl IntoValue for TaskManager { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::MaxAttempts, self.max_attempts.into_value()); map.insert_unchecked(Property::Strategy, self.strategy.into_value()); map.insert_unchecked(Property::TotalDeadline, self.total_deadline.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskManager { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::MaxAttempts) => self.max_attempts.patch(pointer, value), Some(Property::Strategy) => self.strategy.patch(pointer, value), Some(Property::TotalDeadline) => self.total_deadline.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskMergeThreads { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.account_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } let value = &self.thread_name; if value.is_empty() { errors.push(ValidationError::required(Property::ThreadName)); } let value = &self.message_ids; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::MessageIds)); } } let value = &self.status; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id.into(), None); } } impl Pickle for TaskMergeThreads { fn pickle(&self, out: &mut Vec) { self.account_id.pickle(out); self.thread_name.pickle(out); self.message_ids.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.account_id = Pickle::unpickle(stream)?; this.thread_name = Pickle::unpickle(stream)?; this.message_ids = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskMergeThreads { fn default() -> Self { Self { account_id: Default::default(), thread_name: Default::default(), message_ids: Default::default(), status: Default::default(), } } } impl IntoValue for TaskMergeThreads { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked(Property::ThreadName, self.thread_name.into_value()); map.insert_unchecked(Property::MessageIds, self.message_ids.into_value()); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskMergeThreads { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AccountId) => pointer.assert_server_set(), Some(Property::ThreadName) => pointer.assert_server_set(), Some(Property::MessageIds) => pointer.assert_server_set(), Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskRestoreArchivedItem { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.blob_id; if value.is_empty() { errors.push(ValidationError::required(Property::BlobId)); } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } let value = &self.archived_until; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ArchivedUntil, value)); } let value = &self.account_id; if !value.is_valid() { errors.push(ValidationError::required(Property::AccountId)); } let value = &self.status; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Account, self.account_id.into(), None); } } impl Pickle for TaskRestoreArchivedItem { fn pickle(&self, out: &mut Vec) { self.blob_id.pickle(out); self.archived_item_type.pickle(out); self.created_at.pickle(out); self.archived_until.pickle(out); self.account_id.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.blob_id = Pickle::unpickle(stream)?; this.archived_item_type = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.archived_until = Pickle::unpickle(stream)?; this.account_id = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskRestoreArchivedItem { fn default() -> Self { Self { blob_id: Default::default(), archived_item_type: Default::default(), created_at: Default::default(), archived_until: Default::default(), account_id: Default::default(), status: Default::default(), } } } impl IntoValue for TaskRestoreArchivedItem { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::BlobId, self.blob_id.into_value()); map.insert_unchecked( Property::ArchivedItemType, self.archived_item_type.into_value(), ); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::ArchivedUntil, self.archived_until.into_value()); map.insert_unchecked(Property::AccountId, self.account_id.into_value()); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskRestoreArchivedItem { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::BlobId) => pointer.assert_server_set(), Some(Property::ArchivedItemType) => pointer.assert_server_set(), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::ArchivedUntil) => pointer.assert_server_set(), Some(Property::AccountId) => pointer.assert_server_set(), Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskRetryStrategy { fn validate(&self, errors: &mut Vec) -> bool { match self { TaskRetryStrategy::ExponentialBackoff(inner) => inner.validate(errors), TaskRetryStrategy::FixedDelay(inner) => inner.validate(errors), } } } impl Default for TaskRetryStrategy { fn default() -> Self { TaskRetryStrategy::ExponentialBackoff(Default::default()) } } impl Pickle for TaskRetryStrategy { fn pickle(&self, out: &mut Vec) { match self { TaskRetryStrategy::ExponentialBackoff(inner) => { 0u16.pickle(out); inner.pickle(out); } TaskRetryStrategy::FixedDelay(inner) => { 1u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(TaskRetryStrategy::ExponentialBackoff), 1 => Pickle::unpickle(stream).map(TaskRetryStrategy::FixedDelay), _ => None, } } } impl IntoValue for TaskRetryStrategy { fn into_value(self) -> JmapValue<'static> { match self { TaskRetryStrategy::ExponentialBackoff(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("ExponentialBackoff".into())); obj } TaskRetryStrategy::FixedDelay(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("FixedDelay".into())); obj } } } } impl RegistryJsonPatch for TaskRetryStrategy { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { TaskRetryStrategyType::ExponentialBackoff => { *self = TaskRetryStrategy::ExponentialBackoff(Default::default()) } TaskRetryStrategyType::FixedDelay => { *self = TaskRetryStrategy::FixedDelay(Default::default()) } } } match self { TaskRetryStrategy::ExponentialBackoff(inner) => inner.patch(pointer, value), TaskRetryStrategy::FixedDelay(inner) => inner.patch(pointer, value), } } } impl TaskRetryStrategy { pub fn object_type(&self) -> TaskRetryStrategyType { match self { TaskRetryStrategy::ExponentialBackoff(_) => TaskRetryStrategyType::ExponentialBackoff, TaskRetryStrategy::FixedDelay(_) => TaskRetryStrategyType::FixedDelay, } } } impl TaskRetryStrategyBackoff { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.factor; if *value < Float::new(1.0) { errors.push(ValidationError::min_value(Property::Factor, 1)); } errors.len() == neb } } impl Pickle for TaskRetryStrategyBackoff { fn pickle(&self, out: &mut Vec) { self.factor.pickle(out); self.initial_delay.pickle(out); self.max_delay.pickle(out); self.jitter.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.factor = Pickle::unpickle(stream)?; this.initial_delay = Pickle::unpickle(stream)?; this.max_delay = Pickle::unpickle(stream)?; this.jitter = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskRetryStrategyBackoff { fn default() -> Self { Self { factor: Float::new(2.0f64), initial_delay: Duration::from_millis(60000), max_delay: Duration::from_millis(1800000), jitter: true, } } } impl IntoValue for TaskRetryStrategyBackoff { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::Factor, self.factor.into_value()); map.insert_unchecked(Property::InitialDelay, self.initial_delay.into_value()); map.insert_unchecked(Property::MaxDelay, self.max_delay.into_value()); map.insert_unchecked(Property::Jitter, self.jitter.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskRetryStrategyBackoff { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Factor) => self.factor.patch(pointer, value), Some(Property::InitialDelay) => self.initial_delay.patch(pointer, value), Some(Property::MaxDelay) => self.max_delay.patch(pointer, value), Some(Property::Jitter) => self.jitter.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskRetryStrategyFixed { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for TaskRetryStrategyFixed { fn pickle(&self, out: &mut Vec) { self.delay.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.delay = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskRetryStrategyFixed { fn default() -> Self { Self { delay: Duration::from_millis(300000), } } } impl IntoValue for TaskRetryStrategyFixed { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Delay, self.delay.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskRetryStrategyFixed { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Delay) => self.delay.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskSpamFilterMaintenance { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.status; value.validate(errors); errors.len() == neb } } impl Pickle for TaskSpamFilterMaintenance { fn pickle(&self, out: &mut Vec) { self.maintenance_type.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.maintenance_type = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskSpamFilterMaintenance { fn default() -> Self { Self { maintenance_type: Default::default(), status: Default::default(), } } } impl IntoValue for TaskSpamFilterMaintenance { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked( Property::MaintenanceType, self.maintenance_type.into_value(), ); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskSpamFilterMaintenance { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::MaintenanceType) => self .maintenance_type .patch(pointer.assert_read_only()?, value), Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskStatus { fn validate(&self, errors: &mut Vec) -> bool { match self { TaskStatus::Pending(inner) => inner.validate(errors), TaskStatus::Retry(inner) => inner.validate(errors), TaskStatus::Failed(inner) => inner.validate(errors), } } } impl Default for TaskStatus { fn default() -> Self { TaskStatus::Pending(Default::default()) } } impl Pickle for TaskStatus { fn pickle(&self, out: &mut Vec) { match self { TaskStatus::Pending(inner) => { 0u16.pickle(out); inner.pickle(out); } TaskStatus::Retry(inner) => { 1u16.pickle(out); inner.pickle(out); } TaskStatus::Failed(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(TaskStatus::Pending), 1 => Pickle::unpickle(stream).map(TaskStatus::Retry), 2 => Pickle::unpickle(stream).map(TaskStatus::Failed), _ => None, } } } impl IntoValue for TaskStatus { fn into_value(self) -> JmapValue<'static> { match self { TaskStatus::Pending(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Pending".into())); obj } TaskStatus::Retry(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Retry".into())); obj } TaskStatus::Failed(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Failed".into())); obj } } } } impl RegistryJsonPatch for TaskStatus { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { TaskStatusType::Pending => *self = TaskStatus::Pending(Default::default()), TaskStatusType::Retry => *self = TaskStatus::Retry(Default::default()), TaskStatusType::Failed => *self = TaskStatus::Failed(Default::default()), } } match self { TaskStatus::Pending(inner) => inner.patch(pointer, value), TaskStatus::Retry(inner) => inner.patch(pointer, value), TaskStatus::Failed(inner) => inner.patch(pointer, value), } } } impl TaskStatus { pub fn object_type(&self) -> TaskStatusType { match self { TaskStatus::Pending(_) => TaskStatusType::Pending, TaskStatus::Retry(_) => TaskStatusType::Retry, TaskStatus::Failed(_) => TaskStatusType::Failed, } } } impl TaskStatusFailed { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } let value = &self.failed_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::FailedAt, value)); } let value = &self.failure_reason; if value.is_empty() { errors.push(ValidationError::required(Property::FailureReason)); } errors.len() == neb } } impl Pickle for TaskStatusFailed { fn pickle(&self, out: &mut Vec) { self.created_at.pickle(out); self.failed_at.pickle(out); self.failed_attempt_number.pickle(out); self.failure_reason.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.created_at = Pickle::unpickle(stream)?; this.failed_at = Pickle::unpickle(stream)?; this.failed_attempt_number = Pickle::unpickle(stream)?; this.failure_reason = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskStatusFailed { fn default() -> Self { Self { created_at: Default::default(), failed_at: Default::default(), failed_attempt_number: 0u64, failure_reason: Default::default(), } } } impl IntoValue for TaskStatusFailed { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::FailedAt, self.failed_at.into_value()); map.insert_unchecked( Property::FailedAttemptNumber, self.failed_attempt_number.into_value(), ); map.insert_unchecked(Property::FailureReason, self.failure_reason.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskStatusFailed { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::FailedAt) => self.failed_at.patch(pointer, value), Some(Property::FailedAttemptNumber) => self.failed_attempt_number.patch(pointer, value), Some(Property::FailureReason) => self.failure_reason.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskStatusPending { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } let value = &self.due; if !value.is_valid() { errors.push(ValidationError::invalid(Property::Due, value)); } errors.len() == neb } } impl Pickle for TaskStatusPending { fn pickle(&self, out: &mut Vec) { self.created_at.pickle(out); self.due.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.created_at = Pickle::unpickle(stream)?; this.due = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskStatusPending { fn default() -> Self { Self { created_at: Default::default(), due: Default::default(), } } } impl IntoValue for TaskStatusPending { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::Due, self.due.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskStatusPending { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::Due) => self.due.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskStatusRetry { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } let value = &self.due; if !value.is_valid() { errors.push(ValidationError::invalid(Property::Due, value)); } let value = &self.failure_reason; if value.is_empty() { errors.push(ValidationError::required(Property::FailureReason)); } errors.len() == neb } } impl Pickle for TaskStatusRetry { fn pickle(&self, out: &mut Vec) { self.created_at.pickle(out); self.due.pickle(out); self.attempt_number.pickle(out); self.failure_reason.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.created_at = Pickle::unpickle(stream)?; this.due = Pickle::unpickle(stream)?; this.attempt_number = Pickle::unpickle(stream)?; this.failure_reason = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskStatusRetry { fn default() -> Self { Self { created_at: Default::default(), due: Default::default(), attempt_number: 1u64, failure_reason: Default::default(), } } } impl IntoValue for TaskStatusRetry { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(6); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::Due, self.due.into_value()); map.insert_unchecked(Property::AttemptNumber, self.attempt_number.into_value()); map.insert_unchecked(Property::FailureReason, self.failure_reason.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskStatusRetry { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::Due) => self.due.patch(pointer, value), Some(Property::AttemptNumber) => self.attempt_number.patch(pointer, value), Some(Property::FailureReason) => self.failure_reason.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskStoreMaintenance { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.status; value.validate(errors); errors.len() == neb } } impl Pickle for TaskStoreMaintenance { fn pickle(&self, out: &mut Vec) { self.maintenance_type.pickle(out); self.shard_index.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.maintenance_type = Pickle::unpickle(stream)?; this.shard_index = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskStoreMaintenance { fn default() -> Self { Self { maintenance_type: Default::default(), shard_index: Default::default(), status: Default::default(), } } } impl IntoValue for TaskStoreMaintenance { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked( Property::MaintenanceType, self.maintenance_type.into_value(), ); map.insert_unchecked(Property::ShardIndex, self.shard_index.into_value()); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskStoreMaintenance { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::MaintenanceType) => self .maintenance_type .patch(pointer.assert_read_only()?, value), Some(Property::ShardIndex) => self.shard_index.patch(pointer, value), Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskTenantMaintenance { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.tenant_id; if !value.is_valid() { errors.push(ValidationError::required(Property::TenantId)); } let value = &self.status; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.tenant_id.into(), None); } } impl Pickle for TaskTenantMaintenance { fn pickle(&self, out: &mut Vec) { self.tenant_id.pickle(out); self.maintenance_type.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.tenant_id = Pickle::unpickle(stream)?; this.maintenance_type = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskTenantMaintenance { fn default() -> Self { Self { tenant_id: Default::default(), maintenance_type: Default::default(), status: Default::default(), } } } impl IntoValue for TaskTenantMaintenance { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::TenantId, self.tenant_id.into_value()); map.insert_unchecked( Property::MaintenanceType, self.maintenance_type.into_value(), ); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskTenantMaintenance { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::TenantId) => self.tenant_id.patch(pointer.assert_read_only()?, value), Some(Property::MaintenanceType) => self .maintenance_type .patch(pointer.assert_read_only()?, value), Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TaskTlsReport { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.report_id; if !value.is_valid() { errors.push(ValidationError::required(Property::ReportId)); } let value = &self.status; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::TlsInternalReport, self.report_id.into(), None); } } impl Pickle for TaskTlsReport { fn pickle(&self, out: &mut Vec) { self.report_id.pickle(out); self.status.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.report_id = Pickle::unpickle(stream)?; this.status = Pickle::unpickle(stream)?; Some(this) } } impl Default for TaskTlsReport { fn default() -> Self { Self { report_id: Default::default(), status: Default::default(), } } } impl IntoValue for TaskTlsReport { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::ReportId, self.report_id.into_value()); map.insert_unchecked(Property::Status, self.status.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TaskTlsReport { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ReportId) => pointer.assert_server_set(), Some(Property::Status) => self.status.patch(pointer, value), Some(Property::Due) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Tenant { const FLAGS: u64 = OBJ_SEQ_ID; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Tenant; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } if let Some(value) = &self.logo { if value.is_empty() { errors.push(ValidationError::required(Property::Logo)); } } let value = &self.roles; value.validate(errors); let value = &self.permissions; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.text(Property::Text, &self.name); self.roles.index(i); } } impl Pickle for Tenant { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.created_at.pickle(out); self.logo.pickle(out); self.roles.pickle(out); self.permissions.pickle(out); self.quotas.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.logo = Pickle::unpickle(stream)?; this.roles = Pickle::unpickle(stream)?; this.permissions = Pickle::unpickle(stream)?; this.quotas = Pickle::unpickle(stream)?; Some(this) } } impl Default for Tenant { fn default() -> Self { Self { name: Default::default(), created_at: Default::default(), logo: Default::default(), roles: Default::default(), permissions: Default::default(), quotas: Default::default(), } } } impl IntoValue for Tenant { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::Logo, self.logo.into_value()); map.insert_unchecked(Property::Roles, self.roles.into_value()); map.insert_unchecked(Property::Permissions, self.permissions.into_value()); map.insert_unchecked(Property::Quotas, self.quotas.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Tenant { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self.name.patch(pointer, value), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::Logo) => self.logo.patch(pointer, value), Some(Property::Roles) => self.roles.patch(pointer, value), Some(Property::Permissions) => self.permissions.patch(pointer, value), Some(Property::Quotas) => self.quotas.patch(pointer, value), Some(Property::UsedDiskQuota) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for TlsExternalReport { const FLAGS: u64 = OBJ_FILTER_TENANT; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::TlsExternalReport; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.report; value.validate(errors); let value = &self.from; if value.is_empty() { errors.push(ValidationError::required(Property::From)); } let value = &self.subject; if value.is_empty() { errors.push(ValidationError::required(Property::Subject)); } let value = &self.to; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::To)); } } let value = &self.received_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ReceivedAt, value)); } let value = &self.expires_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::ExpiresAt, value)); } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); } } impl Pickle for TlsExternalReport { fn pickle(&self, out: &mut Vec) { self.report.pickle(out); self.from.pickle(out); self.subject.pickle(out); self.to.pickle(out); self.received_at.pickle(out); self.expires_at.pickle(out); self.member_tenant_id.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.report = Pickle::unpickle(stream)?; this.from = Pickle::unpickle(stream)?; this.subject = Pickle::unpickle(stream)?; this.to = Pickle::unpickle(stream)?; this.received_at = Pickle::unpickle(stream)?; this.expires_at = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; Some(this) } } impl Default for TlsExternalReport { fn default() -> Self { Self { report: Default::default(), from: Default::default(), subject: Default::default(), to: Default::default(), received_at: Default::default(), expires_at: Default::default(), member_tenant_id: Default::default(), } } } impl IntoValue for TlsExternalReport { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked(Property::Report, self.report.into_value()); map.insert_unchecked(Property::From, self.from.into_value()); map.insert_unchecked(Property::Subject, self.subject.into_value()); map.insert_unchecked(Property::To, self.to.into_value()); map.insert_unchecked(Property::ReceivedAt, self.received_at.into_value()); map.insert_unchecked(Property::ExpiresAt, self.expires_at.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TlsExternalReport { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Report) => self.report.patch(pointer, value), Some(Property::From) => self .from .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::Subject) => self.subject.patch(pointer, value), Some(Property::To) => self .to .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::ReceivedAt) => self.received_at.patch(pointer, value), Some(Property::ExpiresAt) => self.expires_at.patch(pointer, value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TlsFailureDetails { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.sending_mta_ip { if !value.is_valid() { errors.push(ValidationError::invalid(Property::SendingMtaIp, value)); } } if let Some(value) = &self.receiving_mx_hostname { if value.is_empty() { errors.push(ValidationError::required(Property::ReceivingMxHostname)); } } if let Some(value) = &self.receiving_mx_helo { if value.is_empty() { errors.push(ValidationError::required(Property::ReceivingMxHelo)); } } if let Some(value) = &self.receiving_ip { if !value.is_valid() { errors.push(ValidationError::invalid(Property::ReceivingIp, value)); } } if let Some(value) = &self.additional_information { if value.is_empty() { errors.push(ValidationError::required(Property::AdditionalInformation)); } } if let Some(value) = &self.failure_reason_code { if value.is_empty() { errors.push(ValidationError::required(Property::FailureReasonCode)); } } errors.len() == neb } } impl Pickle for TlsFailureDetails { fn pickle(&self, out: &mut Vec) { self.result_type.pickle(out); self.sending_mta_ip.pickle(out); self.receiving_mx_hostname.pickle(out); self.receiving_mx_helo.pickle(out); self.receiving_ip.pickle(out); self.failed_session_count.pickle(out); self.additional_information.pickle(out); self.failure_reason_code.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.result_type = Pickle::unpickle(stream)?; this.sending_mta_ip = Pickle::unpickle(stream)?; this.receiving_mx_hostname = Pickle::unpickle(stream)?; this.receiving_mx_helo = Pickle::unpickle(stream)?; this.receiving_ip = Pickle::unpickle(stream)?; this.failed_session_count = Pickle::unpickle(stream)?; this.additional_information = Pickle::unpickle(stream)?; this.failure_reason_code = Pickle::unpickle(stream)?; Some(this) } } impl Default for TlsFailureDetails { fn default() -> Self { Self { result_type: Default::default(), sending_mta_ip: Default::default(), receiving_mx_hostname: Default::default(), receiving_mx_helo: Default::default(), receiving_ip: Default::default(), failed_session_count: 0u64, additional_information: Default::default(), failure_reason_code: Default::default(), } } } impl IntoValue for TlsFailureDetails { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(10); map.insert_unchecked(Property::ResultType, self.result_type.into_value()); map.insert_unchecked(Property::SendingMtaIp, self.sending_mta_ip.into_value()); map.insert_unchecked( Property::ReceivingMxHostname, self.receiving_mx_hostname.into_value(), ); map.insert_unchecked( Property::ReceivingMxHelo, self.receiving_mx_helo.into_value(), ); map.insert_unchecked(Property::ReceivingIp, self.receiving_ip.into_value()); map.insert_unchecked( Property::FailedSessionCount, self.failed_session_count.into_value(), ); map.insert_unchecked( Property::AdditionalInformation, self.additional_information.into_value(), ); map.insert_unchecked( Property::FailureReasonCode, self.failure_reason_code.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TlsFailureDetails { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ResultType) => self.result_type.patch(pointer, value), Some(Property::SendingMtaIp) => self.sending_mta_ip.patch(pointer, value), Some(Property::ReceivingMxHostname) => self.receiving_mx_hostname.patch(pointer, value), Some(Property::ReceivingMxHelo) => self.receiving_mx_helo.patch(pointer, value), Some(Property::ReceivingIp) => self.receiving_ip.patch(pointer, value), Some(Property::FailedSessionCount) => self.failed_session_count.patch(pointer, value), Some(Property::AdditionalInformation) => { self.additional_information.patch(pointer, value) } Some(Property::FailureReasonCode) => self.failure_reason_code.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for TlsInternalReport { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::TlsInternalReport; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.mail_rua; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::MailRua)); } } let value = &self.http_rua; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::HttpRua)); } } let value = &self.report; value.validate(errors); let value = &self.domain; if value.is_empty() { errors.push(ValidationError::required(Property::Domain)); } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } let value = &self.deliver_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::DeliverAt, value)); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for TlsInternalReport { fn pickle(&self, out: &mut Vec) { self.policy_identifiers.pickle(out); self.mail_rua.pickle(out); self.http_rua.pickle(out); self.report.pickle(out); self.domain.pickle(out); self.created_at.pickle(out); self.deliver_at.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.policy_identifiers = Pickle::unpickle(stream)?; this.mail_rua = Pickle::unpickle(stream)?; this.http_rua = Pickle::unpickle(stream)?; this.report = Pickle::unpickle(stream)?; this.domain = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.deliver_at = Pickle::unpickle(stream)?; Some(this) } } impl Default for TlsInternalReport { fn default() -> Self { Self { policy_identifiers: Default::default(), mail_rua: Default::default(), http_rua: Default::default(), report: Default::default(), domain: Default::default(), created_at: Default::default(), deliver_at: Default::default(), } } } impl IntoValue for TlsInternalReport { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked( Property::PolicyIdentifiers, self.policy_identifiers.into_value(), ); map.insert_unchecked(Property::MailRua, self.mail_rua.into_value()); map.insert_unchecked(Property::HttpRua, self.http_rua.into_value()); map.insert_unchecked(Property::Report, self.report.into_value()); map.insert_unchecked(Property::Domain, self.domain.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::DeliverAt, self.deliver_at.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TlsInternalReport { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::PolicyIdentifiers) => self.policy_identifiers.patch(pointer, value), Some(Property::MailRua) => self .mail_rua .patch(pointer.with_validators(&[StringValidator::Email]), value), Some(Property::HttpRua) => self.http_rua.patch(pointer, value), Some(Property::Report) => self.report.patch(pointer, value), Some(Property::Domain) => self .domain .patch(pointer.with_validators(&[StringValidator::Domain]), value), Some(Property::CreatedAt) => self.created_at.patch(pointer, value), Some(Property::DeliverAt) => self.deliver_at.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TlsReport { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.organization_name { if value.is_empty() { errors.push(ValidationError::required(Property::OrganizationName)); } } if let Some(value) = &self.contact_info { if value.is_empty() { errors.push(ValidationError::required(Property::ContactInfo)); } } let value = &self.report_id; if value.is_empty() { errors.push(ValidationError::required(Property::ReportId)); } let value = &self.date_range_start; if !value.is_valid() { errors.push(ValidationError::invalid(Property::DateRangeStart, value)); } let value = &self.date_range_end; if !value.is_valid() { errors.push(ValidationError::invalid(Property::DateRangeEnd, value)); } let value = &self.policies; for value in value.values() { value.validate(errors); } errors.len() == neb } } impl Pickle for TlsReport { fn pickle(&self, out: &mut Vec) { self.organization_name.pickle(out); self.contact_info.pickle(out); self.report_id.pickle(out); self.date_range_start.pickle(out); self.date_range_end.pickle(out); self.policies.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.organization_name = Pickle::unpickle(stream)?; this.contact_info = Pickle::unpickle(stream)?; this.report_id = Pickle::unpickle(stream)?; this.date_range_start = Pickle::unpickle(stream)?; this.date_range_end = Pickle::unpickle(stream)?; this.policies = Pickle::unpickle(stream)?; Some(this) } } impl Default for TlsReport { fn default() -> Self { Self { organization_name: Default::default(), contact_info: Default::default(), report_id: Default::default(), date_range_start: Default::default(), date_range_end: Default::default(), policies: Default::default(), } } } impl IntoValue for TlsReport { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(8); map.insert_unchecked( Property::OrganizationName, self.organization_name.into_value(), ); map.insert_unchecked(Property::ContactInfo, self.contact_info.into_value()); map.insert_unchecked(Property::ReportId, self.report_id.into_value()); map.insert_unchecked(Property::DateRangeStart, self.date_range_start.into_value()); map.insert_unchecked(Property::DateRangeEnd, self.date_range_end.into_value()); map.insert_unchecked(Property::Policies, self.policies.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TlsReport { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::OrganizationName) => self.organization_name.patch(pointer, value), Some(Property::ContactInfo) => self.contact_info.patch(pointer, value), Some(Property::ReportId) => self.report_id.patch(pointer, value), Some(Property::DateRangeStart) => self.date_range_start.patch(pointer, value), Some(Property::DateRangeEnd) => self.date_range_end.patch(pointer, value), Some(Property::Policies) => self.policies.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TlsReportPolicy { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.policy_strings; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::PolicyStrings)); } } let value = &self.policy_domain; if value.is_empty() { errors.push(ValidationError::required(Property::PolicyDomain)); } let value = &self.mx_hosts; for value in value.iter() { if value.is_empty() { errors.push(ValidationError::required(Property::MxHosts)); } } let value = &self.failure_details; for value in value.values() { value.validate(errors); } errors.len() == neb } } impl Pickle for TlsReportPolicy { fn pickle(&self, out: &mut Vec) { self.policy_type.pickle(out); self.policy_strings.pickle(out); self.policy_domain.pickle(out); self.mx_hosts.pickle(out); self.total_successful_sessions.pickle(out); self.total_failed_sessions.pickle(out); self.failure_details.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.policy_type = Pickle::unpickle(stream)?; this.policy_strings = Pickle::unpickle(stream)?; this.policy_domain = Pickle::unpickle(stream)?; this.mx_hosts = Pickle::unpickle(stream)?; this.total_successful_sessions = Pickle::unpickle(stream)?; this.total_failed_sessions = Pickle::unpickle(stream)?; this.failure_details = Pickle::unpickle(stream)?; Some(this) } } impl Default for TlsReportPolicy { fn default() -> Self { Self { policy_type: Default::default(), policy_strings: Default::default(), policy_domain: Default::default(), mx_hosts: Default::default(), total_successful_sessions: 0u64, total_failed_sessions: 0u64, failure_details: Default::default(), } } } impl IntoValue for TlsReportPolicy { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked(Property::PolicyType, self.policy_type.into_value()); map.insert_unchecked(Property::PolicyStrings, self.policy_strings.into_value()); map.insert_unchecked(Property::PolicyDomain, self.policy_domain.into_value()); map.insert_unchecked(Property::MxHosts, self.mx_hosts.into_value()); map.insert_unchecked( Property::TotalSuccessfulSessions, self.total_successful_sessions.into_value(), ); map.insert_unchecked( Property::TotalFailedSessions, self.total_failed_sessions.into_value(), ); map.insert_unchecked(Property::FailureDetails, self.failure_details.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TlsReportPolicy { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::PolicyType) => self.policy_type.patch(pointer, value), Some(Property::PolicyStrings) => self.policy_strings.patch(pointer, value), Some(Property::PolicyDomain) => self .policy_domain .patch(pointer.with_validators(&[StringValidator::Domain]), value), Some(Property::MxHosts) => self.mx_hosts.patch(pointer, value), Some(Property::TotalSuccessfulSessions) => { self.total_successful_sessions.patch(pointer, value) } Some(Property::TotalFailedSessions) => self.total_failed_sessions.patch(pointer, value), Some(Property::FailureDetails) => self.failure_details.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for TlsReportSettings { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::TlsReportSettings; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.contact_info; value.validate(errors); let value = &self.from_address; value.validate(errors); let value = &self.from_name; value.validate(errors); let value = &self.max_report_size; value.validate(errors); let value = &self.org_name; value.validate(errors); let value = &self.send_frequency; value.validate(errors); let value = &self.dkim_sign_domain; value.validate(errors); let value = &self.subject; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl TlsReportSettings { pub fn ctx_contact_info(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.contact_info, default: Some(Expression { else_: "false".to_string(), ..Default::default() }), property: Property::ContactInfo, allowed_variables: MTA_QUEUE_HOST_VARIABLE, allowed_constants: &[], } } pub fn ctx_from_address(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.from_address, default: Some(Expression { else_: "'noreply-tls@' + system('domain')".to_string(), ..Default::default() }), property: Property::FromAddress, allowed_variables: MTA_QUEUE_HOST_VARIABLE, allowed_constants: &[], } } pub fn ctx_from_name(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.from_name, default: Some(Expression { else_: "'Report Subsystem'".to_string(), ..Default::default() }), property: Property::FromName, allowed_variables: MTA_QUEUE_HOST_VARIABLE, allowed_constants: &[], } } pub fn ctx_max_report_size(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.max_report_size, default: Some(Expression { else_: "5242880".to_string(), ..Default::default() }), property: Property::MaxReportSize, allowed_variables: MTA_QUEUE_HOST_VARIABLE, allowed_constants: &[], } } pub fn ctx_org_name(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.org_name, default: Some(Expression { else_: "system('domain')".to_string(), ..Default::default() }), property: Property::OrgName, allowed_variables: MTA_QUEUE_HOST_VARIABLE, allowed_constants: &[], } } pub fn ctx_send_frequency(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.send_frequency, default: Some(Expression { else_: "daily".to_string(), ..Default::default() }), property: Property::SendFrequency, allowed_variables: MTA_QUEUE_HOST_VARIABLE, allowed_constants: MTA_AGGREGATE_CONSTANT, } } pub fn ctx_dkim_sign_domain(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.dkim_sign_domain, default: Some(Expression { else_: "system('domain')".to_string(), ..Default::default() }), property: Property::DkimSignDomain, allowed_variables: MTA_QUEUE_HOST_VARIABLE, allowed_constants: &[], } } pub fn ctx_subject(&self) -> ExpressionContext<'_> { ExpressionContext { expr: &self.subject, default: Some(Expression { else_: "'TLS Aggregate Report'".to_string(), ..Default::default() }), property: Property::Subject, allowed_variables: MTA_QUEUE_HOST_VARIABLE, allowed_constants: &[], } } pub fn expression_ctxs(&self) -> Vec> { vec![ self.ctx_contact_info(), self.ctx_from_address(), self.ctx_from_name(), self.ctx_max_report_size(), self.ctx_org_name(), self.ctx_send_frequency(), self.ctx_dkim_sign_domain(), self.ctx_subject(), ] } } impl Pickle for TlsReportSettings { fn pickle(&self, out: &mut Vec) { self.contact_info.pickle(out); self.from_address.pickle(out); self.from_name.pickle(out); self.max_report_size.pickle(out); self.org_name.pickle(out); self.send_frequency.pickle(out); self.dkim_sign_domain.pickle(out); self.subject.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.contact_info = Pickle::unpickle(stream)?; this.from_address = Pickle::unpickle(stream)?; this.from_name = Pickle::unpickle(stream)?; this.max_report_size = Pickle::unpickle(stream)?; this.org_name = Pickle::unpickle(stream)?; this.send_frequency = Pickle::unpickle(stream)?; this.dkim_sign_domain = Pickle::unpickle(stream)?; this.subject = Pickle::unpickle(stream)?; Some(this) } } impl Default for TlsReportSettings { fn default() -> Self { Self { contact_info: Expression { else_: "false".to_string(), ..Default::default() }, from_address: Expression { else_: "'noreply-tls@' + system('domain')".to_string(), ..Default::default() }, from_name: Expression { else_: "'Report Subsystem'".to_string(), ..Default::default() }, max_report_size: Expression { else_: "5242880".to_string(), ..Default::default() }, org_name: Expression { else_: "system('domain')".to_string(), ..Default::default() }, send_frequency: Expression { else_: "daily".to_string(), ..Default::default() }, dkim_sign_domain: Expression { else_: "system('domain')".to_string(), ..Default::default() }, subject: Expression { else_: "'TLS Aggregate Report'".to_string(), ..Default::default() }, } } } impl IntoValue for TlsReportSettings { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(10); map.insert_unchecked(Property::ContactInfo, self.contact_info.into_value()); map.insert_unchecked(Property::FromAddress, self.from_address.into_value()); map.insert_unchecked(Property::FromName, self.from_name.into_value()); map.insert_unchecked(Property::MaxReportSize, self.max_report_size.into_value()); map.insert_unchecked(Property::OrgName, self.org_name.into_value()); map.insert_unchecked(Property::SendFrequency, self.send_frequency.into_value()); map.insert_unchecked(Property::DkimSignDomain, self.dkim_sign_domain.into_value()); map.insert_unchecked(Property::Subject, self.subject.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TlsReportSettings { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::ContactInfo) => self.contact_info.patch(pointer, value), Some(Property::FromAddress) => self.from_address.patch(pointer, value), Some(Property::FromName) => self.from_name.patch(pointer, value), Some(Property::MaxReportSize) => self.max_report_size.patch(pointer, value), Some(Property::OrgName) => self.org_name.patch(pointer, value), Some(Property::SendFrequency) => self.send_frequency.patch(pointer, value), Some(Property::DkimSignDomain) => self.dkim_sign_domain.patch(pointer, value), Some(Property::Subject) => self.subject.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Trace { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Trace; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.events; for value in value.values() { value.validate(errors); } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for Trace { fn pickle(&self, out: &mut Vec) { self.events.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.events = Pickle::unpickle(stream)?; Some(this) } } impl Default for Trace { fn default() -> Self { Self { events: Default::default(), } } } impl IntoValue for Trace { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Events, self.events.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for Trace { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Events) => self.events.patch(pointer, value), Some(Property::Timestamp) => pointer.assert_server_set(), Some(Property::From) => pointer.assert_server_set(), Some(Property::To) => pointer.assert_server_set(), Some(Property::Size) => pointer.assert_server_set(), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TraceEvent { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.timestamp; if !value.is_valid() { errors.push(ValidationError::invalid(Property::Timestamp, value)); } let value = &self.key_values; for value in value.values() { value.validate(errors); } errors.len() == neb } } impl Pickle for TraceEvent { fn pickle(&self, out: &mut Vec) { self.event.pickle(out); self.timestamp.pickle(out); self.key_values.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.event = Pickle::unpickle(stream)?; this.timestamp = Pickle::unpickle(stream)?; this.key_values = Pickle::unpickle(stream)?; Some(this) } } impl Default for TraceEvent { fn default() -> Self { Self { event: Default::default(), timestamp: Default::default(), key_values: Default::default(), } } } impl IntoValue for TraceEvent { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(5); map.insert_unchecked(Property::Event, self.event.into_value()); map.insert_unchecked(Property::Timestamp, self.timestamp.into_value()); map.insert_unchecked(Property::KeyValues, self.key_values.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TraceEvent { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Event) => self.event.patch(pointer, value), Some(Property::Timestamp) => self.timestamp.patch(pointer, value), Some(Property::KeyValues) => self.key_values.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TraceKeyValue { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.value; value.validate(errors); errors.len() == neb } } impl Pickle for TraceKeyValue { fn pickle(&self, out: &mut Vec) { self.key.pickle(out); self.value.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.key = Pickle::unpickle(stream)?; this.value = Pickle::unpickle(stream)?; Some(this) } } impl Default for TraceKeyValue { fn default() -> Self { Self { key: Default::default(), value: Default::default(), } } } impl IntoValue for TraceKeyValue { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Key, self.key.into_value()); map.insert_unchecked(Property::Value, self.value.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TraceKeyValue { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Key) => self.key.patch(pointer, value), Some(Property::Value) => self.value.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TraceValue { fn validate(&self, errors: &mut Vec) -> bool { match self { TraceValue::String(inner) => inner.validate(errors), TraceValue::UnsignedInt(inner) => inner.validate(errors), TraceValue::Integer(inner) => inner.validate(errors), TraceValue::Boolean(inner) => inner.validate(errors), TraceValue::Float(inner) => inner.validate(errors), TraceValue::UTCDateTime(inner) => inner.validate(errors), TraceValue::Duration(inner) => inner.validate(errors), TraceValue::IpAddr(inner) => inner.validate(errors), TraceValue::List(inner) => inner.validate(errors), TraceValue::Event(inner) => inner.validate(errors), TraceValue::Null => true, } } } impl Default for TraceValue { fn default() -> Self { TraceValue::String(Default::default()) } } impl Pickle for TraceValue { fn pickle(&self, out: &mut Vec) { match self { TraceValue::String(inner) => { 0u16.pickle(out); inner.pickle(out); } TraceValue::UnsignedInt(inner) => { 1u16.pickle(out); inner.pickle(out); } TraceValue::Integer(inner) => { 2u16.pickle(out); inner.pickle(out); } TraceValue::Boolean(inner) => { 3u16.pickle(out); inner.pickle(out); } TraceValue::Float(inner) => { 4u16.pickle(out); inner.pickle(out); } TraceValue::UTCDateTime(inner) => { 5u16.pickle(out); inner.pickle(out); } TraceValue::Duration(inner) => { 6u16.pickle(out); inner.pickle(out); } TraceValue::IpAddr(inner) => { 7u16.pickle(out); inner.pickle(out); } TraceValue::List(inner) => { 8u16.pickle(out); inner.pickle(out); } TraceValue::Event(inner) => { 9u16.pickle(out); inner.pickle(out); } TraceValue::Null => { 10u16.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(TraceValue::String), 1 => Pickle::unpickle(stream).map(TraceValue::UnsignedInt), 2 => Pickle::unpickle(stream).map(TraceValue::Integer), 3 => Pickle::unpickle(stream).map(TraceValue::Boolean), 4 => Pickle::unpickle(stream).map(TraceValue::Float), 5 => Pickle::unpickle(stream).map(TraceValue::UTCDateTime), 6 => Pickle::unpickle(stream).map(TraceValue::Duration), 7 => Pickle::unpickle(stream).map(TraceValue::IpAddr), 8 => Pickle::unpickle(stream).map(TraceValue::List), 9 => Pickle::unpickle(stream).map(TraceValue::Event), 10 => Some(TraceValue::Null), _ => None, } } } impl IntoValue for TraceValue { fn into_value(self) -> JmapValue<'static> { match self { TraceValue::String(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("String".into())); obj } TraceValue::UnsignedInt(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("UnsignedInt".into())); obj } TraceValue::Integer(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Integer".into())); obj } TraceValue::Boolean(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Boolean".into())); obj } TraceValue::Float(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Float".into())); obj } TraceValue::UTCDateTime(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("UTCDateTime".into())); obj } TraceValue::Duration(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Duration".into())); obj } TraceValue::IpAddr(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("IpAddr".into())); obj } TraceValue::List(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("List".into())); obj } TraceValue::Event(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Event".into())); obj } TraceValue::Null => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Null".into())); JmapValue::Object(obj) } } } } impl RegistryJsonPatch for TraceValue { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { TraceValueType::String => *self = TraceValue::String(Default::default()), TraceValueType::UnsignedInt => *self = TraceValue::UnsignedInt(Default::default()), TraceValueType::Integer => *self = TraceValue::Integer(Default::default()), TraceValueType::Boolean => *self = TraceValue::Boolean(Default::default()), TraceValueType::Float => *self = TraceValue::Float(Default::default()), TraceValueType::UTCDateTime => *self = TraceValue::UTCDateTime(Default::default()), TraceValueType::Duration => *self = TraceValue::Duration(Default::default()), TraceValueType::IpAddr => *self = TraceValue::IpAddr(Default::default()), TraceValueType::List => *self = TraceValue::List(Default::default()), TraceValueType::Event => *self = TraceValue::Event(Default::default()), TraceValueType::Null => *self = TraceValue::Null, } } match self { TraceValue::String(inner) => inner.patch(pointer, value), TraceValue::UnsignedInt(inner) => inner.patch(pointer, value), TraceValue::Integer(inner) => inner.patch(pointer, value), TraceValue::Boolean(inner) => inner.patch(pointer, value), TraceValue::Float(inner) => inner.patch(pointer, value), TraceValue::UTCDateTime(inner) => inner.patch(pointer, value), TraceValue::Duration(inner) => inner.patch(pointer, value), TraceValue::IpAddr(inner) => inner.patch(pointer, value), TraceValue::List(inner) => inner.patch(pointer, value), TraceValue::Event(inner) => inner.patch(pointer, value), TraceValue::Null => pointer.assert_eof(), } } } impl TraceValue { pub fn object_type(&self) -> TraceValueType { match self { TraceValue::String(_) => TraceValueType::String, TraceValue::UnsignedInt(_) => TraceValueType::UnsignedInt, TraceValue::Integer(_) => TraceValueType::Integer, TraceValue::Boolean(_) => TraceValueType::Boolean, TraceValue::Float(_) => TraceValueType::Float, TraceValue::UTCDateTime(_) => TraceValueType::UTCDateTime, TraceValue::Duration(_) => TraceValueType::Duration, TraceValue::IpAddr(_) => TraceValueType::IpAddr, TraceValue::List(_) => TraceValueType::List, TraceValue::Event(_) => TraceValueType::Event, TraceValue::Null => TraceValueType::Null, } } } impl TraceValueBoolean { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for TraceValueBoolean { fn pickle(&self, out: &mut Vec) { self.value.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.value = Pickle::unpickle(stream)?; Some(this) } } impl Default for TraceValueBoolean { fn default() -> Self { Self { value: false } } } impl IntoValue for TraceValueBoolean { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Value, self.value.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TraceValueBoolean { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Value) => self.value.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TraceValueDuration { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for TraceValueDuration { fn pickle(&self, out: &mut Vec) { self.value.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.value = Pickle::unpickle(stream)?; Some(this) } } impl Default for TraceValueDuration { fn default() -> Self { Self { value: 0u64 } } } impl IntoValue for TraceValueDuration { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Value, self.value.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TraceValueDuration { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Value) => self.value.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TraceValueEvent { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.value; for value in value.values() { value.validate(errors); } errors.len() == neb } } impl Pickle for TraceValueEvent { fn pickle(&self, out: &mut Vec) { self.event.pickle(out); self.value.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.event = Pickle::unpickle(stream)?; this.value = Pickle::unpickle(stream)?; Some(this) } } impl Default for TraceValueEvent { fn default() -> Self { Self { event: Default::default(), value: Default::default(), } } } impl IntoValue for TraceValueEvent { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(4); map.insert_unchecked(Property::Event, self.event.into_value()); map.insert_unchecked(Property::Value, self.value.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TraceValueEvent { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Event) => self.event.patch(pointer, value), Some(Property::Value) => self.value.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TraceValueFloat { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for TraceValueFloat { fn pickle(&self, out: &mut Vec) { self.value.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.value = Pickle::unpickle(stream)?; Some(this) } } impl Default for TraceValueFloat { fn default() -> Self { Self { value: Float::new(0.0f64), } } } impl IntoValue for TraceValueFloat { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Value, self.value.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TraceValueFloat { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Value) => self.value.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TraceValueInteger { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for TraceValueInteger { fn pickle(&self, out: &mut Vec) { self.value.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.value = Pickle::unpickle(stream)?; Some(this) } } impl Default for TraceValueInteger { fn default() -> Self { Self { value: 0i64 } } } impl IntoValue for TraceValueInteger { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Value, self.value.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TraceValueInteger { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Value) => self.value.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TraceValueIpAddr { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.value; if !value.is_valid() { errors.push(ValidationError::invalid(Property::Value, value)); } errors.len() == neb } } impl Pickle for TraceValueIpAddr { fn pickle(&self, out: &mut Vec) { self.value.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.value = Pickle::unpickle(stream)?; Some(this) } } impl Default for TraceValueIpAddr { fn default() -> Self { Self { value: Default::default(), } } } impl IntoValue for TraceValueIpAddr { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Value, self.value.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TraceValueIpAddr { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Value) => self.value.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TraceValueList { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.value; for value in value.values() { value.validate(errors); } errors.len() == neb } } impl Pickle for TraceValueList { fn pickle(&self, out: &mut Vec) { self.value.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.value = Pickle::unpickle(stream)?; Some(this) } } impl Default for TraceValueList { fn default() -> Self { Self { value: Default::default(), } } } impl IntoValue for TraceValueList { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Value, self.value.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TraceValueList { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Value) => self.value.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TraceValueString { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.value; if value.is_empty() { errors.push(ValidationError::required(Property::Value)); } errors.len() == neb } } impl Pickle for TraceValueString { fn pickle(&self, out: &mut Vec) { self.value.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.value = Pickle::unpickle(stream)?; Some(this) } } impl Default for TraceValueString { fn default() -> Self { Self { value: Default::default(), } } } impl IntoValue for TraceValueString { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Value, self.value.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TraceValueString { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Value) => self.value.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TraceValueUTCDateTime { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.value; if !value.is_valid() { errors.push(ValidationError::invalid(Property::Value, value)); } errors.len() == neb } } impl Pickle for TraceValueUTCDateTime { fn pickle(&self, out: &mut Vec) { self.value.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.value = Pickle::unpickle(stream)?; Some(this) } } impl Default for TraceValueUTCDateTime { fn default() -> Self { Self { value: Default::default(), } } } impl IntoValue for TraceValueUTCDateTime { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Value, self.value.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TraceValueUTCDateTime { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Value) => self.value.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TraceValueUnsignedInt { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for TraceValueUnsignedInt { fn pickle(&self, out: &mut Vec) { self.value.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.value = Pickle::unpickle(stream)?; Some(this) } } impl Default for TraceValueUnsignedInt { fn default() -> Self { Self { value: 0u64 } } } impl IntoValue for TraceValueUnsignedInt { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Value, self.value.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TraceValueUnsignedInt { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Value) => self.value.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for Tracer { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::Tracer; fn validate(&self, errors: &mut Vec) -> bool { match self { Tracer::Log(inner) => inner.validate(errors), Tracer::Stdout(inner) => inner.validate(errors), Tracer::Journal(inner) => inner.validate(errors), Tracer::OtelHttp(inner) => inner.validate(errors), Tracer::OtelGrpc(inner) => inner.validate(errors), } } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Default for Tracer { fn default() -> Self { Tracer::Log(Default::default()) } } impl Pickle for Tracer { fn pickle(&self, out: &mut Vec) { match self { Tracer::Log(inner) => { 0u16.pickle(out); inner.pickle(out); } Tracer::Stdout(inner) => { 1u16.pickle(out); inner.pickle(out); } Tracer::Journal(inner) => { 2u16.pickle(out); inner.pickle(out); } Tracer::OtelHttp(inner) => { 3u16.pickle(out); inner.pickle(out); } Tracer::OtelGrpc(inner) => { 4u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Pickle::unpickle(stream).map(Tracer::Log), 1 => Pickle::unpickle(stream).map(Tracer::Stdout), 2 => Pickle::unpickle(stream).map(Tracer::Journal), 3 => Pickle::unpickle(stream).map(Tracer::OtelHttp), 4 => Pickle::unpickle(stream).map(Tracer::OtelGrpc), _ => None, } } } impl IntoValue for Tracer { fn into_value(self) -> JmapValue<'static> { match self { Tracer::Log(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Log".into())); obj } Tracer::Stdout(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Stdout".into())); obj } Tracer::Journal(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Journal".into())); obj } Tracer::OtelHttp(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("OtelHttp".into())); obj } Tracer::OtelGrpc(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("OtelGrpc".into())); obj } } } } impl RegistryJsonPatch for Tracer { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { TracerType::Log => *self = Tracer::Log(Default::default()), TracerType::Stdout => *self = Tracer::Stdout(Default::default()), TracerType::Journal => *self = Tracer::Journal(Default::default()), TracerType::OtelHttp => *self = Tracer::OtelHttp(Default::default()), TracerType::OtelGrpc => *self = Tracer::OtelGrpc(Default::default()), } } match self { Tracer::Log(inner) => inner.patch(pointer, value), Tracer::Stdout(inner) => inner.patch(pointer, value), Tracer::Journal(inner) => inner.patch(pointer, value), Tracer::OtelHttp(inner) => inner.patch(pointer, value), Tracer::OtelGrpc(inner) => inner.patch(pointer, value), } } } impl Tracer { pub fn object_type(&self) -> TracerType { match self { Tracer::Log(_) => TracerType::Log, Tracer::Stdout(_) => TracerType::Stdout, Tracer::Journal(_) => TracerType::Journal, Tracer::OtelHttp(_) => TracerType::OtelHttp, Tracer::OtelGrpc(_) => TracerType::OtelGrpc, } } } impl TracerCommon { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for TracerCommon { fn pickle(&self, out: &mut Vec) { self.enable.pickle(out); self.level.pickle(out); self.lossy.pickle(out); self.events.pickle(out); self.events_policy.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.enable = Pickle::unpickle(stream)?; this.level = Pickle::unpickle(stream)?; this.lossy = Pickle::unpickle(stream)?; this.events = Pickle::unpickle(stream)?; this.events_policy = Pickle::unpickle(stream)?; Some(this) } } impl Default for TracerCommon { fn default() -> Self { Self { enable: true, level: TracingLevel::Info, lossy: false, events: Default::default(), events_policy: EventPolicy::Exclude, } } } impl IntoValue for TracerCommon { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(7); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Level, self.level.into_value()); map.insert_unchecked(Property::Lossy, self.lossy.into_value()); map.insert_unchecked(Property::Events, self.events.into_value()); map.insert_unchecked(Property::EventsPolicy, self.events_policy.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TracerCommon { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Level) => self.level.patch(pointer, value), Some(Property::Lossy) => self.lossy.patch(pointer, value), Some(Property::Events) => self.events.patch(pointer, value), Some(Property::EventsPolicy) => self.events_policy.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TracerLog { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.path; if value.is_empty() { errors.push(ValidationError::required(Property::Path)); } let value = &self.prefix; if value.is_empty() { errors.push(ValidationError::required(Property::Prefix)); } errors.len() == neb } } impl Pickle for TracerLog { fn pickle(&self, out: &mut Vec) { self.path.pickle(out); self.prefix.pickle(out); self.rotate.pickle(out); self.ansi.pickle(out); self.multiline.pickle(out); self.enable.pickle(out); self.level.pickle(out); self.lossy.pickle(out); self.events.pickle(out); self.events_policy.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.path = Pickle::unpickle(stream)?; this.prefix = Pickle::unpickle(stream)?; this.rotate = Pickle::unpickle(stream)?; this.ansi = Pickle::unpickle(stream)?; this.multiline = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.level = Pickle::unpickle(stream)?; this.lossy = Pickle::unpickle(stream)?; this.events = Pickle::unpickle(stream)?; this.events_policy = Pickle::unpickle(stream)?; Some(this) } } impl Default for TracerLog { fn default() -> Self { Self { path: Default::default(), prefix: "stalwart".to_string(), rotate: LogRotateFrequency::Daily, ansi: true, multiline: false, enable: true, level: TracingLevel::Info, lossy: false, events: Default::default(), events_policy: EventPolicy::Exclude, } } } impl IntoValue for TracerLog { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(12); map.insert_unchecked(Property::Path, self.path.into_value()); map.insert_unchecked(Property::Prefix, self.prefix.into_value()); map.insert_unchecked(Property::Rotate, self.rotate.into_value()); map.insert_unchecked(Property::Ansi, self.ansi.into_value()); map.insert_unchecked(Property::Multiline, self.multiline.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Level, self.level.into_value()); map.insert_unchecked(Property::Lossy, self.lossy.into_value()); map.insert_unchecked(Property::Events, self.events.into_value()); map.insert_unchecked(Property::EventsPolicy, self.events_policy.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TracerLog { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Path) => self .path .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Prefix) => self .prefix .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Rotate) => self.rotate.patch(pointer, value), Some(Property::Ansi) => self.ansi.patch(pointer, value), Some(Property::Multiline) => self.multiline.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Level) => self.level.patch(pointer, value), Some(Property::Lossy) => self.lossy.patch(pointer, value), Some(Property::Events) => self.events.patch(pointer, value), Some(Property::EventsPolicy) => self.events_policy.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TracerOtelGrpc { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); if let Some(value) = &self.endpoint { if value.is_empty() { errors.push(ValidationError::required(Property::Endpoint)); } } let value = &self.http_auth; value.validate(errors); let value = &self.http_headers; for value in value.values() { if value.is_empty() { errors.push(ValidationError::required(Property::HttpHeaders)); } } errors.len() == neb } } impl Pickle for TracerOtelGrpc { fn pickle(&self, out: &mut Vec) { self.endpoint.pickle(out); self.enable_log_exporter.pickle(out); self.enable_span_exporter.pickle(out); self.throttle.pickle(out); self.timeout.pickle(out); self.http_auth.pickle(out); self.http_headers.pickle(out); self.enable.pickle(out); self.level.pickle(out); self.lossy.pickle(out); self.events.pickle(out); self.events_policy.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.endpoint = Pickle::unpickle(stream)?; this.enable_log_exporter = Pickle::unpickle(stream)?; this.enable_span_exporter = Pickle::unpickle(stream)?; this.throttle = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.http_auth = Pickle::unpickle(stream)?; this.http_headers = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.level = Pickle::unpickle(stream)?; this.lossy = Pickle::unpickle(stream)?; this.events = Pickle::unpickle(stream)?; this.events_policy = Pickle::unpickle(stream)?; Some(this) } } impl Default for TracerOtelGrpc { fn default() -> Self { Self { endpoint: Default::default(), enable_log_exporter: true, enable_span_exporter: true, throttle: Duration::from_millis(1000), timeout: Duration::from_millis(10000), http_auth: Default::default(), http_headers: Default::default(), enable: true, level: TracingLevel::Info, lossy: false, events: Default::default(), events_policy: EventPolicy::Exclude, } } } impl IntoValue for TracerOtelGrpc { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked(Property::Endpoint, self.endpoint.into_value()); map.insert_unchecked( Property::EnableLogExporter, self.enable_log_exporter.into_value(), ); map.insert_unchecked( Property::EnableSpanExporter, self.enable_span_exporter.into_value(), ); map.insert_unchecked(Property::Throttle, self.throttle.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::HttpAuth, self.http_auth.into_value()); map.insert_unchecked(Property::HttpHeaders, self.http_headers.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Level, self.level.into_value()); map.insert_unchecked(Property::Lossy, self.lossy.into_value()); map.insert_unchecked(Property::Events, self.events.into_value()); map.insert_unchecked(Property::EventsPolicy, self.events_policy.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TracerOtelGrpc { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Endpoint) => self .endpoint .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::EnableLogExporter) => self.enable_log_exporter.patch(pointer, value), Some(Property::EnableSpanExporter) => self.enable_span_exporter.patch(pointer, value), Some(Property::Throttle) => self.throttle.patch(pointer, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::HttpAuth) => self.http_auth.patch(pointer, value), Some(Property::HttpHeaders) => self .http_headers .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Level) => self.level.patch(pointer, value), Some(Property::Lossy) => self.lossy.patch(pointer, value), Some(Property::Events) => self.events.patch(pointer, value), Some(Property::EventsPolicy) => self.events_policy.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TracerOtelHttp { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.endpoint; if value.is_empty() { errors.push(ValidationError::required(Property::Endpoint)); } let value = &self.http_auth; value.validate(errors); let value = &self.http_headers; for value in value.values() { if value.is_empty() { errors.push(ValidationError::required(Property::HttpHeaders)); } } errors.len() == neb } } impl Pickle for TracerOtelHttp { fn pickle(&self, out: &mut Vec) { self.endpoint.pickle(out); self.enable_log_exporter.pickle(out); self.enable_span_exporter.pickle(out); self.throttle.pickle(out); self.timeout.pickle(out); self.http_auth.pickle(out); self.http_headers.pickle(out); self.enable.pickle(out); self.level.pickle(out); self.lossy.pickle(out); self.events.pickle(out); self.events_policy.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.endpoint = Pickle::unpickle(stream)?; this.enable_log_exporter = Pickle::unpickle(stream)?; this.enable_span_exporter = Pickle::unpickle(stream)?; this.throttle = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.http_auth = Pickle::unpickle(stream)?; this.http_headers = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.level = Pickle::unpickle(stream)?; this.lossy = Pickle::unpickle(stream)?; this.events = Pickle::unpickle(stream)?; this.events_policy = Pickle::unpickle(stream)?; Some(this) } } impl Default for TracerOtelHttp { fn default() -> Self { Self { endpoint: Default::default(), enable_log_exporter: true, enable_span_exporter: true, throttle: Duration::from_millis(1000), timeout: Duration::from_millis(10000), http_auth: Default::default(), http_headers: Default::default(), enable: true, level: TracingLevel::Info, lossy: false, events: Default::default(), events_policy: EventPolicy::Exclude, } } } impl IntoValue for TracerOtelHttp { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(14); map.insert_unchecked(Property::Endpoint, self.endpoint.into_value()); map.insert_unchecked( Property::EnableLogExporter, self.enable_log_exporter.into_value(), ); map.insert_unchecked( Property::EnableSpanExporter, self.enable_span_exporter.into_value(), ); map.insert_unchecked(Property::Throttle, self.throttle.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::HttpAuth, self.http_auth.into_value()); map.insert_unchecked(Property::HttpHeaders, self.http_headers.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Level, self.level.into_value()); map.insert_unchecked(Property::Lossy, self.lossy.into_value()); map.insert_unchecked(Property::Events, self.events.into_value()); map.insert_unchecked(Property::EventsPolicy, self.events_policy.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TracerOtelHttp { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Endpoint) => self .endpoint .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::EnableLogExporter) => self.enable_log_exporter.patch(pointer, value), Some(Property::EnableSpanExporter) => self.enable_span_exporter.patch(pointer, value), Some(Property::Throttle) => self.throttle.patch(pointer, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::HttpAuth) => self.http_auth.patch(pointer, value), Some(Property::HttpHeaders) => self .http_headers .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Level) => self.level.patch(pointer, value), Some(Property::Lossy) => self.lossy.patch(pointer, value), Some(Property::Events) => self.events.patch(pointer, value), Some(Property::EventsPolicy) => self.events_policy.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl TracerStdout { fn validate(&self, _: &mut Vec) -> bool { true } } impl Pickle for TracerStdout { fn pickle(&self, out: &mut Vec) { self.buffered.pickle(out); self.ansi.pickle(out); self.multiline.pickle(out); self.enable.pickle(out); self.level.pickle(out); self.lossy.pickle(out); self.events.pickle(out); self.events_policy.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.buffered = Pickle::unpickle(stream)?; this.ansi = Pickle::unpickle(stream)?; this.multiline = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.level = Pickle::unpickle(stream)?; this.lossy = Pickle::unpickle(stream)?; this.events = Pickle::unpickle(stream)?; this.events_policy = Pickle::unpickle(stream)?; Some(this) } } impl Default for TracerStdout { fn default() -> Self { Self { buffered: true, ansi: false, multiline: false, enable: true, level: TracingLevel::Info, lossy: false, events: Default::default(), events_policy: EventPolicy::Exclude, } } } impl IntoValue for TracerStdout { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(10); map.insert_unchecked(Property::Buffered, self.buffered.into_value()); map.insert_unchecked(Property::Ansi, self.ansi.into_value()); map.insert_unchecked(Property::Multiline, self.multiline.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Level, self.level.into_value()); map.insert_unchecked(Property::Lossy, self.lossy.into_value()); map.insert_unchecked(Property::Events, self.events.into_value()); map.insert_unchecked(Property::EventsPolicy, self.events_policy.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for TracerStdout { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Buffered) => self.buffered.patch(pointer, value), Some(Property::Ansi) => self.ansi.patch(pointer, value), Some(Property::Multiline) => self.multiline.patch(pointer, value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Level) => self.level.patch(pointer, value), Some(Property::Lossy) => self.lossy.patch(pointer, value), Some(Property::Events) => self.events.patch(pointer, value), Some(Property::EventsPolicy) => self.events_policy.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for TracingStore { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::TracingStore; fn validate(&self, errors: &mut Vec) -> bool { match self { TracingStore::Disabled => true, TracingStore::Default => true, TracingStore::FoundationDb(inner) => inner.validate(errors), TracingStore::PostgreSql(inner) => inner.validate(errors), TracingStore::MySql(inner) => inner.validate(errors), } } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Default for TracingStore { fn default() -> Self { TracingStore::Disabled } } impl Pickle for TracingStore { fn pickle(&self, out: &mut Vec) { match self { TracingStore::Disabled => { 0u16.pickle(out); } TracingStore::Default => { 1u16.pickle(out); } TracingStore::FoundationDb(inner) => { 2u16.pickle(out); inner.pickle(out); } TracingStore::PostgreSql(inner) => { 3u16.pickle(out); inner.pickle(out); } TracingStore::MySql(inner) => { 4u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(TracingStore::Disabled), 1 => Some(TracingStore::Default), 2 => Pickle::unpickle(stream).map(TracingStore::FoundationDb), 3 => Pickle::unpickle(stream).map(TracingStore::PostgreSql), 4 => Pickle::unpickle(stream).map(TracingStore::MySql), _ => None, } } } impl IntoValue for TracingStore { fn into_value(self) -> JmapValue<'static> { match self { TracingStore::Disabled => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Disabled".into())); JmapValue::Object(obj) } TracingStore::Default => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Default".into())); JmapValue::Object(obj) } TracingStore::FoundationDb(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("FoundationDb".into())); obj } TracingStore::PostgreSql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("PostgreSql".into())); obj } TracingStore::MySql(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("MySql".into())); obj } } } } impl RegistryJsonPatch for TracingStore { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { TracingStoreType::Disabled => *self = TracingStore::Disabled, TracingStoreType::Default => *self = TracingStore::Default, TracingStoreType::FoundationDb => { *self = TracingStore::FoundationDb(Default::default()) } TracingStoreType::PostgreSql => { *self = TracingStore::PostgreSql(Default::default()) } TracingStoreType::MySql => *self = TracingStore::MySql(Default::default()), } } match self { TracingStore::Disabled => pointer.assert_eof(), TracingStore::Default => pointer.assert_eof(), TracingStore::FoundationDb(inner) => inner.patch(pointer, value), TracingStore::PostgreSql(inner) => inner.patch(pointer, value), TracingStore::MySql(inner) => inner.patch(pointer, value), } } } impl TracingStore { pub fn object_type(&self) -> TracingStoreType { match self { TracingStore::Disabled => TracingStoreType::Disabled, TracingStore::Default => TracingStoreType::Default, TracingStore::FoundationDb(_) => TracingStoreType::FoundationDb, TracingStore::PostgreSql(_) => TracingStoreType::PostgreSql, TracingStore::MySql(_) => TracingStoreType::MySql, } } } impl UserAccount { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.name; if value.is_empty() { errors.push(ValidationError::required(Property::Name)); } let value = &self.domain_id; if !value.is_valid() { errors.push(ValidationError::required(Property::DomainId)); } let value = &self.credentials; for value in value.values() { value.validate(errors); } let value = &self.created_at; if !value.is_valid() { errors.push(ValidationError::invalid(Property::CreatedAt, value)); } let value = &self.member_group_ids; for value in value.iter() { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberGroupIds)); } } if let Some(value) = &self.member_tenant_id { if !value.is_valid() { errors.push(ValidationError::required(Property::MemberTenantId)); } } let value = &self.roles; value.validate(errors); let value = &self.permissions; value.validate(errors); let value = &self.aliases; for value in value.values() { value.validate(errors); } if let Some(value) = &self.external_id { if value.is_empty() { errors.push(ValidationError::required(Property::ExternalId)); } } if let Some(value) = &self.description { if value.is_empty() { errors.push(ValidationError::required(Property::Description)); } } let value = &self.encryption_at_rest; value.validate(errors); errors.len() == neb } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { i.unique_global_composite(Property::Email, &self.name, &self.domain_id); i.text(Property::Text, &self.name); i.search(Property::Name, &self.name); i.foreign_key(ObjectType::Domain, self.domain_id.into(), None); i.search(Property::DomainId, &self.domain_id); for id in self.member_group_ids.iter() { i.foreign_key( ObjectType::Account, Some(*id), Some(AccountType::Group.to_id()), ); } for value in self.member_group_ids.iter() { i.search(Property::MemberGroupIds, value); } i.foreign_key(ObjectType::Tenant, self.member_tenant_id, None); if let Some(value) = &self.member_tenant_id { i.search(Property::MemberTenantId, value); } self.roles.index(i); for item in self.aliases.values() { item.index(i); } if let Some(value) = &self.external_id { i.search(Property::ExternalId, value); } if let Some(value) = &self.description { i.text(Property::Text, value); } self.encryption_at_rest.index(i); } } impl Pickle for UserAccount { fn pickle(&self, out: &mut Vec) { self.name.pickle(out); self.domain_id.pickle(out); self.credentials.pickle(out); self.created_at.pickle(out); self.member_group_ids.pickle(out); self.member_tenant_id.pickle(out); self.roles.pickle(out); self.permissions.pickle(out); self.quotas.pickle(out); self.aliases.pickle(out); self.external_id.pickle(out); self.description.pickle(out); self.locale.pickle(out); self.time_zone.pickle(out); self.encryption_at_rest.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.name = Pickle::unpickle(stream)?; this.domain_id = Pickle::unpickle(stream)?; this.credentials = Pickle::unpickle(stream)?; this.created_at = Pickle::unpickle(stream)?; this.member_group_ids = Pickle::unpickle(stream)?; this.member_tenant_id = Pickle::unpickle(stream)?; this.roles = Pickle::unpickle(stream)?; this.permissions = Pickle::unpickle(stream)?; this.quotas = Pickle::unpickle(stream)?; this.aliases = Pickle::unpickle(stream)?; if stream.version() >= 1 { this.external_id = Pickle::unpickle(stream)?; } this.description = Pickle::unpickle(stream)?; this.locale = Pickle::unpickle(stream)?; this.time_zone = Pickle::unpickle(stream)?; this.encryption_at_rest = Pickle::unpickle(stream)?; Some(this) } } impl Default for UserAccount { fn default() -> Self { Self { name: Default::default(), domain_id: Default::default(), credentials: Default::default(), created_at: Default::default(), member_group_ids: Default::default(), member_tenant_id: Default::default(), roles: Default::default(), permissions: Default::default(), quotas: Default::default(), aliases: Default::default(), external_id: Default::default(), description: Default::default(), locale: Locale::EnUS, time_zone: Default::default(), encryption_at_rest: Default::default(), } } } impl IntoValue for UserAccount { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(17); map.insert_unchecked(Property::Name, self.name.into_value()); map.insert_unchecked(Property::DomainId, self.domain_id.into_value()); map.insert_unchecked(Property::Credentials, self.credentials.into_value()); map.insert_unchecked(Property::CreatedAt, self.created_at.into_value()); map.insert_unchecked(Property::MemberGroupIds, self.member_group_ids.into_value()); map.insert_unchecked(Property::MemberTenantId, self.member_tenant_id.into_value()); map.insert_unchecked(Property::Roles, self.roles.into_value()); map.insert_unchecked(Property::Permissions, self.permissions.into_value()); map.insert_unchecked(Property::Quotas, self.quotas.into_value()); map.insert_unchecked(Property::Aliases, self.aliases.into_value()); map.insert_unchecked(Property::ExternalId, self.external_id.into_value()); map.insert_unchecked(Property::Description, self.description.into_value()); map.insert_unchecked(Property::Locale, self.locale.into_value()); map.insert_unchecked(Property::TimeZone, self.time_zone.into_value()); map.insert_unchecked( Property::EncryptionAtRest, self.encryption_at_rest.into_value(), ); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for UserAccount { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Name) => self.name.patch( pointer.with_validators(&[StringValidator::EmailLocalPart]), value, ), Some(Property::DomainId) => self.domain_id.patch(pointer, value), Some(Property::EmailAddress) => pointer.assert_server_set(), Some(Property::Credentials) => self.credentials.patch(pointer, value), Some(Property::CreatedAt) => pointer.assert_server_set(), Some(Property::MemberGroupIds) => self.member_group_ids.patch(pointer, value), Some(Property::MemberTenantId) => self .member_tenant_id .patch(pointer.assert_can_set_tenant()?, value), Some(Property::Roles) => self.roles.patch(pointer, value), Some(Property::Permissions) => self.permissions.patch(pointer, value), Some(Property::Quotas) => self.quotas.patch(pointer, value), Some(Property::UsedDiskQuota) => pointer.assert_server_set(), Some(Property::Aliases) => self.aliases.patch(pointer, value), Some(Property::ExternalId) => self.external_id.patch(pointer, value), Some(Property::Description) => self.description.patch(pointer, value), Some(Property::Locale) => self.locale.patch(pointer, value), Some(Property::TimeZone) => self.time_zone.patch(pointer, value), Some(Property::EncryptionAtRest) => self.encryption_at_rest.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl UserRoles { fn validate(&self, errors: &mut Vec) -> bool { match self { UserRoles::User => true, UserRoles::Admin => true, UserRoles::Custom(inner) => inner.validate(errors), } } fn index<'x>(&'x self, i: &mut IndexBuilder<'x>) { match self { UserRoles::User => {} UserRoles::Admin => {} UserRoles::Custom(object) => { object.index(i); } } } } impl Default for UserRoles { fn default() -> Self { UserRoles::User } } impl Pickle for UserRoles { fn pickle(&self, out: &mut Vec) { match self { UserRoles::User => { 0u16.pickle(out); } UserRoles::Admin => { 1u16.pickle(out); } UserRoles::Custom(inner) => { 2u16.pickle(out); inner.pickle(out); } } } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { match u16::unpickle(stream)? { 0 => Some(UserRoles::User), 1 => Some(UserRoles::Admin), 2 => Pickle::unpickle(stream).map(UserRoles::Custom), _ => None, } } } impl IntoValue for UserRoles { fn into_value(self) -> JmapValue<'static> { match self { UserRoles::User => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("User".into())); JmapValue::Object(obj) } UserRoles::Admin => { let mut obj = jmap_tools::Map::new(); obj.insert_unchecked(Property::Type, JmapValue::Str("Admin".into())); JmapValue::Object(obj) } UserRoles::Custom(obj) => { let mut obj = obj.into_value(); obj.as_object_mut() .unwrap() .insert_unchecked(Property::Type, JmapValue::Str("Custom".into())); obj } } } } impl RegistryJsonPatch for UserRoles { fn patch<'x>( &mut self, pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { if !pointer.has_next() { match object_type(&pointer, &value)? { UserRolesType::User => *self = UserRoles::User, UserRolesType::Admin => *self = UserRoles::Admin, UserRolesType::Custom => *self = UserRoles::Custom(Default::default()), } } match self { UserRoles::User => pointer.assert_eof(), UserRoles::Admin => pointer.assert_eof(), UserRoles::Custom(inner) => inner.patch(pointer, value), } } } impl UserRoles { pub fn object_type(&self) -> UserRolesType { match self { UserRoles::User => UserRolesType::User, UserRoles::Admin => UserRolesType::Admin, UserRoles::Custom(_) => UserRolesType::Custom, } } } impl ObjectImpl for WebDav { const FLAGS: u64 = OBJ_SINGLETON; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::WebDav; fn validate(&self, _: &mut Vec) -> bool { true } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for WebDav { fn pickle(&self, out: &mut Vec) { self.enable_assisted_discovery.pickle(out); self.max_lock_timeout.pickle(out); self.max_locks.pickle(out); self.dead_property_max_size.pickle(out); self.live_property_max_size.pickle(out); self.request_max_size.pickle(out); self.max_results.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.enable_assisted_discovery = Pickle::unpickle(stream)?; this.max_lock_timeout = Pickle::unpickle(stream)?; this.max_locks = Pickle::unpickle(stream)?; this.dead_property_max_size = Pickle::unpickle(stream)?; this.live_property_max_size = Pickle::unpickle(stream)?; this.request_max_size = Pickle::unpickle(stream)?; this.max_results = Pickle::unpickle(stream)?; Some(this) } } impl Default for WebDav { fn default() -> Self { Self { enable_assisted_discovery: true, max_lock_timeout: Duration::from_millis(3600000), max_locks: 10u64, dead_property_max_size: Some(1024u64), live_property_max_size: 250u64, request_max_size: 26214400, max_results: 2000u64, } } } impl IntoValue for WebDav { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(9); map.insert_unchecked( Property::EnableAssistedDiscovery, self.enable_assisted_discovery.into_value(), ); map.insert_unchecked(Property::MaxLockTimeout, self.max_lock_timeout.into_value()); map.insert_unchecked(Property::MaxLocks, self.max_locks.into_value()); map.insert_unchecked( Property::DeadPropertyMaxSize, self.dead_property_max_size.into_value(), ); map.insert_unchecked( Property::LivePropertyMaxSize, self.live_property_max_size.into_value(), ); map.insert_unchecked(Property::RequestMaxSize, self.request_max_size.into_value()); map.insert_unchecked(Property::MaxResults, self.max_results.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for WebDav { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::EnableAssistedDiscovery) => { self.enable_assisted_discovery.patch(pointer, value) } Some(Property::MaxLockTimeout) => self.max_lock_timeout.patch(pointer, value), Some(Property::MaxLocks) => self.max_locks.patch(pointer, value), Some(Property::DeadPropertyMaxSize) => { self.dead_property_max_size.patch(pointer, value) } Some(Property::LivePropertyMaxSize) => { self.live_property_max_size.patch(pointer, value) } Some(Property::RequestMaxSize) => self.request_max_size.patch(pointer, value), Some(Property::MaxResults) => self.max_results.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ObjectImpl for WebHook { const FLAGS: u64 = 0; const VERSION: u8 = 0; const OBJECT: ObjectType = ObjectType::WebHook; fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.signature_key; value.validate(errors); let value = &self.url; if value.is_empty() { errors.push(ValidationError::required(Property::Url)); } let value = &self.http_auth; value.validate(errors); let value = &self.http_headers; for value in value.values() { if value.is_empty() { errors.push(ValidationError::required(Property::HttpHeaders)); } } errors.len() == neb } fn index<'x>(&'x self, _: &mut IndexBuilder<'x>) {} } impl Pickle for WebHook { fn pickle(&self, out: &mut Vec) { self.allow_invalid_certs.pickle(out); self.signature_key.pickle(out); self.throttle.pickle(out); self.timeout.pickle(out); self.discard_after.pickle(out); self.url.pickle(out); self.http_auth.pickle(out); self.http_headers.pickle(out); self.enable.pickle(out); self.level.pickle(out); self.lossy.pickle(out); self.events.pickle(out); self.events_policy.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.allow_invalid_certs = Pickle::unpickle(stream)?; this.signature_key = Pickle::unpickle(stream)?; this.throttle = Pickle::unpickle(stream)?; this.timeout = Pickle::unpickle(stream)?; this.discard_after = Pickle::unpickle(stream)?; this.url = Pickle::unpickle(stream)?; this.http_auth = Pickle::unpickle(stream)?; this.http_headers = Pickle::unpickle(stream)?; this.enable = Pickle::unpickle(stream)?; this.level = Pickle::unpickle(stream)?; this.lossy = Pickle::unpickle(stream)?; this.events = Pickle::unpickle(stream)?; this.events_policy = Pickle::unpickle(stream)?; Some(this) } } impl Default for WebHook { fn default() -> Self { Self { allow_invalid_certs: false, signature_key: Default::default(), throttle: Duration::from_millis(1000), timeout: Duration::from_millis(30000), discard_after: Duration::from_millis(300000), url: Default::default(), http_auth: Default::default(), http_headers: Default::default(), enable: true, level: TracingLevel::Info, lossy: false, events: Default::default(), events_policy: EventPolicy::Exclude, } } } impl IntoValue for WebHook { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(15); map.insert_unchecked( Property::AllowInvalidCerts, self.allow_invalid_certs.into_value(), ); map.insert_unchecked(Property::SignatureKey, self.signature_key.into_value()); map.insert_unchecked(Property::Throttle, self.throttle.into_value()); map.insert_unchecked(Property::Timeout, self.timeout.into_value()); map.insert_unchecked(Property::DiscardAfter, self.discard_after.into_value()); map.insert_unchecked(Property::Url, self.url.into_value()); map.insert_unchecked(Property::HttpAuth, self.http_auth.into_value()); map.insert_unchecked(Property::HttpHeaders, self.http_headers.into_value()); map.insert_unchecked(Property::Enable, self.enable.into_value()); map.insert_unchecked(Property::Level, self.level.into_value()); map.insert_unchecked(Property::Lossy, self.lossy.into_value()); map.insert_unchecked(Property::Events, self.events.into_value()); map.insert_unchecked(Property::EventsPolicy, self.events_policy.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for WebHook { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::AllowInvalidCerts) => self.allow_invalid_certs.patch(pointer, value), Some(Property::SignatureKey) => self.signature_key.patch(pointer, value), Some(Property::Throttle) => self.throttle.patch(pointer, value), Some(Property::Timeout) => self.timeout.patch(pointer, value), Some(Property::DiscardAfter) => self.discard_after.patch(pointer, value), Some(Property::Url) => self .url .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::HttpAuth) => self.http_auth.patch(pointer, value), Some(Property::HttpHeaders) => self .http_headers .patch(pointer.with_validators(&[StringValidator::Trim]), value), Some(Property::Enable) => self.enable.patch(pointer, value), Some(Property::Level) => self.level.patch(pointer, value), Some(Property::Lossy) => self.lossy.patch(pointer, value), Some(Property::Events) => self.events.patch(pointer, value), Some(Property::EventsPolicy) => self.events_policy.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } } impl ZenohCoordinator { fn validate(&self, errors: &mut Vec) -> bool { let neb = errors.len(); let value = &self.config; if value.is_empty() { errors.push(ValidationError::required(Property::Config)); } errors.len() == neb } } impl Pickle for ZenohCoordinator { fn pickle(&self, out: &mut Vec) { self.config.pickle(out); } fn unpickle(stream: &mut crate::pickle::PickledStream<'_>) -> Option { let mut this = Self::default(); this.config = Pickle::unpickle(stream)?; Some(this) } } impl Default for ZenohCoordinator { fn default() -> Self { Self { config: Default::default(), } } } impl IntoValue for ZenohCoordinator { fn into_value(self) -> JmapValue<'static> { let mut map = jmap_tools::Map::with_capacity(3); map.insert_unchecked(Property::Config, self.config.into_value()); JmapValue::Object(map) } } impl RegistryJsonPropertyPatch for ZenohCoordinator { fn patch_property<'x>( &mut self, mut pointer: JsonPointerPatch<'_>, value: JmapValue<'x>, ) -> PatchResult<'x> { match pointer.next_property() { Some(Property::Config) => self.config.patch(pointer, value), Some(Property::Type) => Ok(MaybeUnpatched::Unpatched { property: Property::Type, value, }), _ => Err(PatchError::new(pointer, "Invalid property")), } } }