Crate feattle[−][src]
Featture toggles for Rust (called “feattles”, for short), extensible and with background synchronization and administration UI.
Example
use rusoto_s3::S3Client; use rusoto_core::Region; use feattle::*; use std::sync::Arc; /// A struct with your feature toggles: you can use primitive types (like `bool`, `i32`, etc), /// standard collections (like `Vec`, `BTreeSet`, etc) or any arbitrary type that implements /// the required trait. feattles! { struct MyFeattles { /// Is this usage considered cool? is_cool: bool = true, /// Limit the number of "blings" available. /// This will not change the number of "blengs", though! max_blings: i32, /// List the actions that should not be available blocked_actions: Vec<String>, } } // Store their values and history in AWS' S3 let s3_client = S3Client::new(Region::default()); let persistence = S3::new(s3_client, "my-bucket".to_owned(), "some/s3/prefix/".to_owned()); // Create a new instance let my_feattles = Arc::new(MyFeattles::new(persistence)); // Poll the storage in the background BackgroundSync::new(&my_feattles).spawn(); // Start the admin UI with `warp` let admin_panel = Arc::new(AdminPanel::new(my_feattles.clone(), "Project Panda - DEV".to_owned())); tokio::spawn(run_warp_server(admin_panel, ([127, 0, 0, 1], 3030))); // Read values (note the use of `*`) assert_eq!(*my_feattles.is_cool(), true); assert_eq!(*my_feattles.max_blings(), 0); assert_eq!(*my_feattles.blocked_actions(), Vec::<String>::new());
You can run a full example locally with: cargo run --example full --features='s3 uuid warp'
.
With this code, you’ll get an Web Admin UI like:
You can use the UI to edit the current values and see their change history. For example, this
is what you can expect when editing an enum
:
It also supports complex types with a JSON editor and helpful error diagnostics:
How it works
The macro will generate a struct with the given name and visibility modifier (assuming private
by default). The generated struct implements Feattles
and also exposes one method for each
feattle.
The methods created for each feattle allow reading their current value. For example, for a
feattle is_cool: bool
, there will be a method like
pub fn is_cool(&self) -> MappedRwLockReadGuard<bool>
. Note the use of
[parking_lot::MappedRwLockReadGuard
] because the interior of the struct is stored behind a RwLock
to
control concurrent access.
A feattle is created with the syntax $key: $type [= $default]
. You can use doc coments (
starting with ///
) to describe nicely what they do in your system. You can use any type that
implements FeattleValue
and optionally provide a default. If not provided, the default
will be created with Default::default()
.
Minimum supported Rust version
As of this release, the MSRV is 1.45.0, as tested in the CI. A patch release will never require a newer MSRV.
Optional features
You can easily declare feattles with your custom types, use another persistance storage logic or Web Framework (or any at all). For some out-of-the-box functionality, you can activate these cargo features:
- uuid: will add support for [
uuid::Uuid
]. - s3: provides [
S3
] to integrate with AWS’ S3 - warp: provides [
run_warp_server
] for a read-to-use integration with [warp
]
Crate’s organization
This crate is a simple re-export of these three components:
Having them separate allows for leaner lower-level integration. If you’re creating a crate to
provide a different storage or admin, you just need feattle-core
.
Modules
json_reading | Helper free functions to read Rust values from |
persist | Define the interface with some external persistence logic |
Macros
feattle_enum | Define an |
feattles | The main macro of this crate, used to generate a struct that will provide the Feattles functionalities. |
Structs
AdminPanel | The administration panel, agnostic to the choice of web-framework. |
BackgroundSync | Spawn a tokio task to poll |
Disk | Persist the data in the local filesystem, under a given directory. |
FeattleDefinition | A data struct, describing a single feattle. |
RenderedPage | Represent a rendered page |
SerializedFormat | A precise description of a feattle type |
StringFormat | A precise description of a feattle string-type |
Enums
HistoryError | The error type returned by |
RenderError | Represent what can go wrong while handling a request |
SerializedFormatKind | An exact and machine-readable description of a feattle type. |
StringFormatKind | An exact and machine-readable description of a feattle string-type |
UpdateError | The error type returned by |
Traits
FeattleStringValue | The base trait for string-types that can be used for feattles. |
FeattleValue | The base trait for types that can be used for feattles. |
Feattles | The main trait of this crate. |