1use std::collections::BTreeSet;
10
11use crate::event::{Change, Event, EventKind};
12use crate::model::{ActorRef, Attribution, Disclosure, Record, Visibility};
13
14#[derive(Clone, Debug, Default, PartialEq, Eq)]
16pub struct Viewer {
17 pub actor: Option<ActorRef>,
18 pub audiences: BTreeSet<String>,
19 pub privileged: bool,
21}
22
23impl Viewer {
24 pub fn public() -> Self {
26 Self::default()
27 }
28
29 pub fn privileged() -> Self {
31 Self { actor: None, audiences: BTreeSet::new(), privileged: true }
32 }
33
34 pub fn actor(actor: ActorRef) -> Self {
35 Self { actor: Some(actor), ..Self::default() }
36 }
37
38 pub fn with_audience(mut self, a: impl Into<String>) -> Self {
39 self.audiences.insert(a.into());
40 self
41 }
42
43 pub fn can_see(&self, v: &Visibility) -> bool {
44 match v {
45 Visibility::Public => true,
46 Visibility::Restricted { audiences } => {
47 self.privileged || audiences.iter().any(|a| self.audiences.contains(a))
48 }
49 }
50 }
51
52 fn mask(&self, a: &Attribution) -> Attribution {
53 let own = self.actor.as_ref() == Some(&a.actor);
54 if a.disclosure == Disclosure::Withheld && !self.privileged && !own {
55 Attribution { actor: ActorRef::Anonymous, disclosure: Disclosure::Withheld }
56 } else {
57 a.clone()
58 }
59 }
60}
61
62pub fn view_record(record: &Record, viewer: &Viewer) -> Option<Record> {
64 if !viewer.can_see(&record.visibility) {
65 return None;
66 }
67 let mut r = record.clone();
68 r.sources.retain(|s| viewer.can_see(&s.visibility));
69 for s in r.sources.iter_mut() {
70 if let Some(a) = &s.submitted_by {
71 s.submitted_by = Some(viewer.mask(a));
72 }
73 }
74 for a in r.actors.iter_mut() {
75 a.attribution = viewer.mask(&a.attribution);
76 }
77 for rel in r.relations.iter_mut() {
78 rel.asserted_by = viewer.mask(&rel.asserted_by);
79 rel.sources.retain(|s| viewer.can_see(&s.visibility));
80 }
81 Some(r)
82}
83
84pub fn view_history(events: &[Event], viewer: &Viewer) -> Vec<Event> {
88 let mut out = Vec::new();
89 for e in events {
90 if !viewer.can_see(&e.visibility) {
91 continue;
92 }
93 let mut e = e.clone();
94 e.attribution = viewer.mask(&e.attribution);
95 match &mut e.kind {
96 EventKind::Created { record } => {
97 let original = std::mem::take(&mut record.visibility);
100 if let Some(mut r) = view_record(record, viewer) {
101 r.visibility = original;
102 **record = r;
103 }
104 }
105 EventKind::Amended { changes } | EventKind::Corrected { changes, .. } => {
106 changes.retain(|c| match c {
107 Change::AddSource(s) => viewer.can_see(&s.visibility),
108 _ => true,
109 });
110 for c in changes.iter_mut() {
111 if let Change::AddActor(a) = c {
112 a.attribution = viewer.mask(&a.attribution);
113 }
114 }
115 }
116 EventKind::RelationAdded { relation } => {
117 relation.asserted_by = viewer.mask(&relation.asserted_by);
118 relation.sources.retain(|s| viewer.can_see(&s.visibility));
119 }
120 _ => {}
121 }
122 out.push(e);
123 }
124 out
125}