heddle_api/v2/
spool_settings.rs1use crate::heddle::api::v1alpha2::SpoolSettings;
3use prost_types::FieldMask;
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
6pub enum SpoolSettingsPatchError {
7 #[error("invalid settings mask")]
8 Mask,
9 #[error("settings clearDenied")]
10 ClearDenied,
11}
12
13pub fn apply_spool_settings_patch(
22 current: &SpoolSettings,
23 patch: Option<&SpoolSettings>,
24 mask: Option<&FieldMask>,
25 mut can_clear: impl FnMut(&str) -> bool,
26) -> Result<SpoolSettings, SpoolSettingsPatchError> {
27 let mut result = current.clone();
28 let empty = SpoolSettings::default();
29 let patch = patch.unwrap_or(&empty);
30 let Some(mask) = mask else { return Ok(result) };
31 for (index, path) in mask.paths.iter().enumerate() {
32 if mask.paths[..index].contains(path) {
33 return Err(SpoolSettingsPatchError::Mask);
34 }
35 macro_rules! assign {
36 ($field:ident, $replacing:expr) => {{
37 if (patch.$field == empty.$field || $replacing) && !can_clear(path) {
38 return Err(SpoolSettingsPatchError::ClearDenied);
39 }
40 result.$field = patch.$field.to_owned();
41 }};
42 }
43 match path.as_str() {
44 "audience" => assign!(audience, false),
45 "default_state_audience" => assign!(default_state_audience, false),
46 "description" => assign!(description, false),
47 "allow_child_creation" => assign!(allow_child_creation, false),
48 "require_review_to_land" => assign!(require_review_to_land, false),
49 "abandoned_thread_retention" => assign!(abandoned_thread_retention, false),
50 "default_review_policy" => assign!(
51 default_review_policy,
52 current.default_review_policy.is_some()
53 && patch.default_review_policy != current.default_review_policy
54 ),
55 "hold_lifecycle" => assign!(hold_lifecycle, false),
56 "blocking_discussion_resolve_rule" => assign!(blocking_discussion_resolve_rule, false),
57 "default_thread" => assign!(
58 default_thread,
59 current.default_thread.is_some() && patch.default_thread != current.default_thread
60 ),
61 _ => return Err(SpoolSettingsPatchError::Mask),
62 }
63 }
64 Ok(result)
65}