weiss_core/
visibility_policy.rs

1use crate::config::{CurriculumConfig, ObservationVisibility};
2use crate::events::Zone;
3use crate::state::TargetZone;
4
5/// Visibility policy for revealing zone identities.
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub enum ZoneIdentityVisibility {
8    /// Publicly visible identity.
9    Public,
10    /// Visible only to the owner.
11    OwnerOnly,
12}
13
14/// Determine identity visibility for a concrete zone.
15pub fn zone_identity_visibility(
16    zone: Zone,
17    curriculum: &CurriculumConfig,
18) -> ZoneIdentityVisibility {
19    match zone {
20        Zone::Deck | Zone::Hand | Zone::Stock => ZoneIdentityVisibility::OwnerOnly,
21        Zone::Memory => {
22            if curriculum.memory_is_public {
23                ZoneIdentityVisibility::Public
24            } else {
25                ZoneIdentityVisibility::OwnerOnly
26            }
27        }
28        _ => ZoneIdentityVisibility::Public,
29    }
30}
31
32/// Determine identity visibility for a targeted zone.
33pub fn target_zone_identity_visibility(
34    zone: TargetZone,
35    curriculum: &CurriculumConfig,
36) -> ZoneIdentityVisibility {
37    match zone {
38        TargetZone::Hand | TargetZone::DeckTop | TargetZone::Stock => {
39            ZoneIdentityVisibility::OwnerOnly
40        }
41        TargetZone::Memory => {
42            if curriculum.memory_is_public {
43                ZoneIdentityVisibility::Public
44            } else {
45                ZoneIdentityVisibility::OwnerOnly
46            }
47        }
48        _ => ZoneIdentityVisibility::Public,
49    }
50}
51
52/// Whether a zone should be hidden for a given viewer.
53pub fn hide_zone_for_viewer(
54    visibility: ObservationVisibility,
55    viewer: Option<u8>,
56    owner: u8,
57    zone: Zone,
58    curriculum: &CurriculumConfig,
59) -> bool {
60    if visibility != ObservationVisibility::Public {
61        return false;
62    }
63    match zone_identity_visibility(zone, curriculum) {
64        ZoneIdentityVisibility::Public => false,
65        ZoneIdentityVisibility::OwnerOnly => viewer.map(|v| v != owner).unwrap_or(true),
66    }
67}
68
69/// Whether a target zone should be hidden for a given viewer.
70pub fn hide_target_zone_for_viewer(
71    visibility: ObservationVisibility,
72    viewer: Option<u8>,
73    owner: u8,
74    zone: TargetZone,
75    curriculum: &CurriculumConfig,
76) -> bool {
77    if visibility != ObservationVisibility::Public {
78        return false;
79    }
80    match target_zone_identity_visibility(zone, curriculum) {
81        ZoneIdentityVisibility::Public => false,
82        ZoneIdentityVisibility::OwnerOnly => viewer.map(|v| v != owner).unwrap_or(true),
83    }
84}
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89
90    #[test]
91    fn zone_identity_visibility_respects_memory_flag() {
92        let mut curriculum = CurriculumConfig {
93            memory_is_public: false,
94            ..CurriculumConfig::default()
95        };
96
97        assert_eq!(
98            zone_identity_visibility(Zone::Deck, &curriculum),
99            ZoneIdentityVisibility::OwnerOnly
100        );
101        assert_eq!(
102            zone_identity_visibility(Zone::Hand, &curriculum),
103            ZoneIdentityVisibility::OwnerOnly
104        );
105        assert_eq!(
106            zone_identity_visibility(Zone::Stock, &curriculum),
107            ZoneIdentityVisibility::OwnerOnly
108        );
109        assert_eq!(
110            zone_identity_visibility(Zone::Memory, &curriculum),
111            ZoneIdentityVisibility::OwnerOnly
112        );
113        assert_eq!(
114            zone_identity_visibility(Zone::Stage, &curriculum),
115            ZoneIdentityVisibility::Public
116        );
117
118        curriculum.memory_is_public = true;
119        assert_eq!(
120            zone_identity_visibility(Zone::Memory, &curriculum),
121            ZoneIdentityVisibility::Public
122        );
123    }
124
125    #[test]
126    fn target_zone_identity_visibility_respects_memory_flag() {
127        let mut curriculum = CurriculumConfig {
128            memory_is_public: false,
129            ..CurriculumConfig::default()
130        };
131
132        assert_eq!(
133            target_zone_identity_visibility(TargetZone::Hand, &curriculum),
134            ZoneIdentityVisibility::OwnerOnly
135        );
136        assert_eq!(
137            target_zone_identity_visibility(TargetZone::DeckTop, &curriculum),
138            ZoneIdentityVisibility::OwnerOnly
139        );
140        assert_eq!(
141            target_zone_identity_visibility(TargetZone::Stock, &curriculum),
142            ZoneIdentityVisibility::OwnerOnly
143        );
144        assert_eq!(
145            target_zone_identity_visibility(TargetZone::Memory, &curriculum),
146            ZoneIdentityVisibility::OwnerOnly
147        );
148        assert_eq!(
149            target_zone_identity_visibility(TargetZone::Stage, &curriculum),
150            ZoneIdentityVisibility::Public
151        );
152
153        curriculum.memory_is_public = true;
154        assert_eq!(
155            target_zone_identity_visibility(TargetZone::Memory, &curriculum),
156            ZoneIdentityVisibility::Public
157        );
158    }
159
160    #[test]
161    fn hide_zone_for_viewer_only_hides_private_zones_in_public_mode() {
162        let mut curriculum = CurriculumConfig {
163            memory_is_public: false,
164            ..CurriculumConfig::default()
165        };
166
167        assert!(!hide_zone_for_viewer(
168            ObservationVisibility::Full,
169            Some(1),
170            0,
171            Zone::Hand,
172            &curriculum
173        ));
174        assert!(!hide_zone_for_viewer(
175            ObservationVisibility::Public,
176            Some(0),
177            0,
178            Zone::Hand,
179            &curriculum
180        ));
181        assert!(hide_zone_for_viewer(
182            ObservationVisibility::Public,
183            Some(1),
184            0,
185            Zone::Hand,
186            &curriculum
187        ));
188        assert!(hide_zone_for_viewer(
189            ObservationVisibility::Public,
190            None,
191            0,
192            Zone::Hand,
193            &curriculum
194        ));
195        assert!(!hide_zone_for_viewer(
196            ObservationVisibility::Public,
197            Some(1),
198            0,
199            Zone::Stage,
200            &curriculum
201        ));
202        assert!(hide_zone_for_viewer(
203            ObservationVisibility::Public,
204            Some(1),
205            0,
206            Zone::Memory,
207            &curriculum
208        ));
209
210        curriculum.memory_is_public = true;
211        assert!(!hide_zone_for_viewer(
212            ObservationVisibility::Public,
213            Some(1),
214            0,
215            Zone::Memory,
216            &curriculum
217        ));
218    }
219
220    #[test]
221    fn hide_target_zone_for_viewer_only_hides_private_zones_in_public_mode() {
222        let mut curriculum = CurriculumConfig {
223            memory_is_public: false,
224            ..CurriculumConfig::default()
225        };
226
227        assert!(!hide_target_zone_for_viewer(
228            ObservationVisibility::Full,
229            Some(1),
230            0,
231            TargetZone::Hand,
232            &curriculum
233        ));
234        assert!(!hide_target_zone_for_viewer(
235            ObservationVisibility::Public,
236            Some(0),
237            0,
238            TargetZone::DeckTop,
239            &curriculum
240        ));
241        assert!(hide_target_zone_for_viewer(
242            ObservationVisibility::Public,
243            Some(1),
244            0,
245            TargetZone::Stock,
246            &curriculum
247        ));
248        assert!(hide_target_zone_for_viewer(
249            ObservationVisibility::Public,
250            None,
251            0,
252            TargetZone::Hand,
253            &curriculum
254        ));
255        assert!(!hide_target_zone_for_viewer(
256            ObservationVisibility::Public,
257            Some(1),
258            0,
259            TargetZone::Stage,
260            &curriculum
261        ));
262        assert!(hide_target_zone_for_viewer(
263            ObservationVisibility::Public,
264            Some(1),
265            0,
266            TargetZone::Memory,
267            &curriculum
268        ));
269
270        curriculum.memory_is_public = true;
271        assert!(!hide_target_zone_for_viewer(
272            ObservationVisibility::Public,
273            Some(1),
274            0,
275            TargetZone::Memory,
276            &curriculum
277        ));
278    }
279}