detsys_ids_client/
checkin.rs1use std::{collections::HashMap, sync::Arc};
2
3use serde::Deserialize;
4
5use crate::{Map, collator::FeatureFacts};
6
7pub(crate) type CoherentFeatureFlags = HashMap<String, Arc<Feature<serde_json::Value>>>;
8
9#[derive(Clone, Debug, Deserialize, Default)]
10pub struct Checkin {
11 #[serde(default)]
12 pub(crate) server_options: ServerOptions,
13 pub(crate) options: CoherentFeatureFlags,
14}
15
16#[derive(Clone, Debug, Deserialize, Default)]
17pub(crate) struct ServerOptions {
18 pub(crate) compression_algorithms: crate::compression_set::CompressionSet,
19}
20
21impl Checkin {
22 pub(crate) fn as_feature_facts(&self) -> FeatureFacts {
23 let mut feature_facts = Map::new();
24 feature_facts.insert(
25 "$active_feature_flags".into(),
26 self.options
27 .keys()
28 .map(|v| serde_json::Value::from(v.to_owned()))
29 .collect::<Vec<serde_json::Value>>()
30 .into(),
31 );
32
33 for (name, feat) in self.options.iter() {
34 feature_facts.insert(format!("$feature/{name}"), feat.variant.clone());
35 }
36
37 FeatureFacts(feature_facts)
38 }
39}
40
41#[derive(Clone, Debug, Deserialize)]
42pub struct Feature<T: serde::de::DeserializeOwned> {
43 pub variant: serde_json::Value,
44 #[serde(
45 with = "crate::json_string",
46 skip_serializing_if = "Option::is_none",
47 default
48 )]
49 pub payload: Option<T>,
50}
51
52#[cfg(test)]
53mod test {
54 #[test]
55 fn test_parse() {
56 let json = r#"
57 {
58
59 "options": {
60 "dni-det-msg-ptr": {
61 "variant": "a",
62 "payload": "\"dni-det-msg-a\""
63 },
64 "dni-det-msg-a": {
65 "variant": "a",
66 "payload": "\"hello\""
67 },
68 "fine-grained-tokens": {
69 "variant": false
70 }
71 }
72 }"#;
73
74 let _: super::Checkin = serde_json::from_str(json).unwrap();
75 }
76}