feattle_sync/
lib.rs

1//! This crate is the implementation for some synchronization strategies for the feature flags
2//! (called "feattles", for short).
3//!
4//! The crate [`feattle_core`] provides the trait [`feattle_core::persist::Persist`] as the
5//! extension point to implementors of the persistence layer logic. This crates has some useful
6//! concrete implementations: [`Disk`] and [`S3`]. Please refer to the
7//! [main package - `feattle`](https://crates.io/crates/feattle) for more information.
8//!
9//! It also provides a simple way to poll the persistence layer for updates in [`BackgroundSync`].
10//!
11//! # Optional features
12//!
13//! - **aws_sdk_s3**: provides [`S3`] to integrate with AWS' S3 using the crate `aws-sdk-s3` crate
14//! - **rusoto_s3**: provides [`RusotoS3`] to integrate with AWS' S3 using the crate `rusoto` crate
15
16#[cfg(feature = "aws_sdk_s3")]
17mod aws_sdk_s3;
18mod background_sync;
19mod disk;
20#[cfg(feature = "rusoto_s3")]
21mod rusoto_s3;
22
23#[cfg(feature = "aws_sdk_s3")]
24pub use aws_sdk_s3::*;
25pub use background_sync::*;
26pub use disk::*;
27#[cfg(feature = "rusoto_s3")]
28pub use rusoto_s3::*;
29
30#[cfg(test)]
31pub mod tests {
32    use chrono::Utc;
33    use serde_json::json;
34
35    use feattle_core::persist::{CurrentValue, CurrentValues, HistoryEntry, Persist, ValueHistory};
36
37    pub async fn test_persistence<P: Persist>(persistence: P) {
38        // Empty state
39        assert_eq!(persistence.load_current().await.unwrap(), None);
40        assert_eq!(persistence.load_history("key").await.unwrap(), None);
41
42        // Save new values and check if correctly saved
43        let feattles = vec![(
44            "key".to_string(),
45            CurrentValue {
46                modified_at: Utc::now(),
47                modified_by: "someone".to_owned(),
48                value: json!(17i32),
49            },
50        )]
51        .into_iter()
52        .collect();
53        let current_values = CurrentValues {
54            version: 17,
55            date: Utc::now(),
56            feattles,
57        };
58        persistence.save_current(&current_values).await.unwrap();
59        assert_eq!(
60            persistence.load_current().await.unwrap(),
61            Some(current_values)
62        );
63
64        // Save history and check if correctly saved
65        let history = ValueHistory {
66            entries: vec![HistoryEntry {
67                value: json!(17i32),
68                value_overview: "overview".to_owned(),
69                modified_at: Utc::now(),
70                modified_by: "someone else".to_owned(),
71            }],
72        };
73        persistence.save_history("key", &history).await.unwrap();
74        assert_eq!(
75            persistence.load_history("key").await.unwrap(),
76            Some(history)
77        );
78        assert_eq!(persistence.load_history("key2").await.unwrap(), None);
79    }
80}