flags-rs 0.1.12

Rust Library for Flags.gg
Documentation
#[cfg(feature = "tower-middleware")]
use flags_rs::{Auth, Client, middleware::{FlagsLayer, RequestExt}};
use http::{Request, Response, StatusCode};
use http_body_util::{BodyExt, Empty, Full};
use std::convert::Infallible;
use tower::{ServiceBuilder, ServiceExt};
use bytes::Bytes;

#[cfg(not(feature = "tower-middleware"))]
fn main() {
    eprintln!("This example requires the 'tower-middleware' feature. Run with:");
    eprintln!("cargo run --example tower_middleware --features tower-middleware");
}

#[cfg(feature = "tower-middleware")]
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    env_logger::init();

    let auth = Auth {
        project_id: std::env::var("FLAGS_PROJECT_ID").unwrap_or_else(|_| "test-project".to_string()),
        agent_id: std::env::var("FLAGS_AGENT_ID").unwrap_or_else(|_| "test-agent".to_string()),
        environment_id: std::env::var("FLAGS_ENVIRONMENT_ID").unwrap_or_else(|_| "development".to_string()),
    };

    let client = Client::builder()
        .with_auth(auth)
        .build()
        .map_err(|e| Box::new(e) as Box<dyn std::error::Error>)?;

    let flags_layer = FlagsLayer::new(client)
        .with_header_name("X-Feature-Flags");

    let service = ServiceBuilder::new()
        .layer(flags_layer)
        .service_fn(handle_request);

    let request = Request::builder()
        .uri("/")
        .header("X-Feature-Flags", "feature-1,feature-2,feature-3")
        .body(Empty::<Bytes>::new())?;

    let response = service.oneshot(request).await?;
    
    println!("Response status: {}", response.status());
    if let Some(enabled_flags) = response.headers().get("X-Enabled-Flags") {
        println!("Enabled flags: {:?}", enabled_flags);
    }

    let auth2 = Auth {
        project_id: std::env::var("FLAGS_PROJECT_ID").unwrap_or_else(|_| "test-project".to_string()),
        agent_id: std::env::var("FLAGS_AGENT_ID").unwrap_or_else(|_| "test-agent".to_string()),
        environment_id: std::env::var("FLAGS_ENVIRONMENT_ID").unwrap_or_else(|_| "development".to_string()),
    };
    
    let client2 = Client::builder()
        .with_auth(auth2)
        .build()
        .map_err(|e| Box::new(e) as Box<dyn std::error::Error>)?;
    
    let service = ServiceBuilder::new()
        .layer(FlagsLayer::new(client2))
        .service_fn(handle_request_with_flag_check);

    let request = Request::builder()
        .uri("/protected")
        .body(Empty::<Bytes>::new())?;

    let response = service.oneshot(request).await?;
    println!("\nProtected endpoint response: {}", response.status());
    
    let body_bytes = response.into_body().collect().await?.to_bytes();
    let body_str = String::from_utf8_lossy(&body_bytes);
    println!("Response body: {}", body_str);

    Ok(())
}

#[cfg(feature = "tower-middleware")]
async fn handle_request<B>(_req: Request<B>) -> Result<Response<Full<Bytes>>, Infallible> {
    Ok(Response::builder()
        .status(StatusCode::OK)
        .body(Full::new("Hello from the service!".into()))
        .expect("Failed to build response"))
}

#[cfg(feature = "tower-middleware")]
async fn handle_request_with_flag_check<B>(req: Request<B>) -> Result<Response<Full<Bytes>>, Infallible> {
    if let Some(client) = req.flags_client() {
        if client.is("premium-features").enabled().await {
            Ok(Response::builder()
                .status(StatusCode::OK)
                .body(Full::new("Premium features are enabled!".into()))
                .expect("Failed to build response"))
        } else {
            Ok(Response::builder()
                .status(StatusCode::FORBIDDEN)
                .body(Full::new("Premium features are not enabled".into()))
                .expect("Failed to build response"))
        }
    } else {
        Ok(Response::builder()
            .status(StatusCode::INTERNAL_SERVER_ERROR)
            .body(Full::new("Flags client not available".into()))
            .expect("Failed to build response"))
    }
}