ave_core/model/common/
viewpoints.rs1use ave_common::{SchemaType, schematype::ReservedWords};
2use std::collections::BTreeSet;
3
4pub fn validate_fact_viewpoints(
5 fact_viewpoints: &BTreeSet<String>,
6 schema_id: &SchemaType,
7 schema_viewpoints: Option<&BTreeSet<String>>,
8) -> Result<(), String> {
9 if schema_id.is_gov() {
10 if !fact_viewpoints.is_empty() {
11 return Err(
12 "governance fact events cannot define viewpoints".to_owned()
13 );
14 }
15
16 return Ok(());
17 }
18
19 let Some(schema_viewpoints) = schema_viewpoints else {
20 return Err(
21 "tracker fact evaluation is missing schema viewpoints".to_owned()
22 );
23 };
24
25 if schema_viewpoints.is_empty() && !fact_viewpoints.is_empty() {
26 return Err(format!("schema {} does not define viewpoints", schema_id));
27 }
28
29 for viewpoint in fact_viewpoints {
30 if viewpoint.trim().len() != viewpoint.len() {
31 return Err(
32 "viewpoints cannot have surrounding whitespace".to_owned()
33 );
34 }
35
36 if viewpoint.is_empty() {
37 return Err("viewpoints cannot be empty".to_owned());
38 }
39
40 if viewpoint == &ReservedWords::AllViewpoints.to_string() {
41 return Err(
42 "AllViewpoints is not valid in fact requests; use an empty viewpoints set to indicate an unsegmented event"
43 .to_owned(),
44 );
45 }
46
47 if viewpoint.len() > 100 {
48 return Err(
49 "viewpoints cannot be longer than 100 characters".to_owned()
50 );
51 }
52 }
53
54 if fact_viewpoints.is_empty() {
55 return Ok(());
56 }
57
58 for viewpoint in fact_viewpoints {
59 if !schema_viewpoints.contains(viewpoint) {
60 return Err(format!(
61 "viewpoint '{}' is not defined in schema {}",
62 viewpoint, schema_id
63 ));
64 }
65 }
66
67 Ok(())
68}