1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// =============================================================================
// Copyright (c) 2026 Haixing Hu.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0.
// =============================================================================
//! Builder for immutable minimum redaction floors.
use std::sync::Arc;
use super::{
FieldNameMatching,
PolicyError,
PolicyLocation,
RedactionFloor,
RedactionRulesBuilder,
SensitiveFieldPreset,
Sensitivity,
UnknownFieldPolicy,
};
/// Builder for a [`RedactionFloor`].
#[must_use]
#[derive(Debug, Clone)]
pub struct RedactionFloorBuilder {
rules: RedactionRulesBuilder,
}
impl RedactionFloorBuilder {
/// Creates an empty builder for the floor construction context.
pub(super) fn empty() -> Self {
Self {
rules: RedactionRulesBuilder::empty(PolicyLocation::Floor),
}
}
/// Copies every field rule from `floor`.
pub(super) fn from_floor(floor: &RedactionFloor) -> Self {
Self {
rules: RedactionRulesBuilder::from_inner(
&floor.inner,
PolicyLocation::Floor,
),
}
}
/// Adds every sensitive field in one preset.
pub fn include_preset(mut self, preset: SensitiveFieldPreset) -> Self {
self.rules.include_preset(preset);
self
}
/// Raises `field` to at least `level`.
///
/// # Errors
///
/// Returns [`PolicyError::EmptyFieldName`] when `field` has no canonical
/// floor-rule name.
pub fn raise(
mut self,
field: &str,
level: Sensitivity,
) -> Result<Self, PolicyError> {
self.rules.raise(field, level)?;
Ok(self)
}
/// Sets field-name matching behavior.
pub fn matching(mut self, matching: FieldNameMatching) -> Self {
self.rules.matching(matching);
self
}
/// Sets the fallback for fields without an explicit floor rule.
pub fn unknown_field_policy(mut self, policy: UnknownFieldPolicy) -> Self {
self.rules.unknown_field_policy(policy);
self
}
/// Validates and constructs the immutable floor.
///
/// # Errors
///
/// Returns a [`PolicyError`] located at [`PolicyLocation::Floor`] when a
/// field name or fixed mask is invalid.
pub fn build(self) -> Result<RedactionFloor, PolicyError> {
let inner = self.rules.build_inner()?;
Ok(RedactionFloor {
inner: Arc::new(inner),
})
}
}