Skip to content

Flowfull-Rust

Community Starter Kit 🚧 Coming Soon

A Rust implementation of Flowfull is currently in development by the community.

Status

🚧 In Development - Community-driven starter kit

The Rust implementation will include all 7 core concepts adapted for Rust's ecosystem and best practices.

Planned Features

  • Rust 1.70+ - Modern Rust with async/await
  • Actix-web or Axum - Fast, safe web framework
  • Diesel or SeaORM - Type-safe database abstraction
  • All 7 Core Concepts - Bridge Validation, HybridCache, Trust Tokens, etc.
  • Memory Safety - Leveraging Rust's ownership system
  • Zero-Cost Abstractions - Maximum performance
  • Async/Await - Tokio runtime

Planned Structure

flowfull-rust/
├── src/
│   ├── lib/
│   │   ├── bridge/           # Bridge Validation
│   │   ├── cache/            # HybridCache
│   │   ├── auth/             # Auth Middleware
│   │   ├── database/         # Database
│   │   ├── tokens/           # Trust Tokens (PASETO)
│   │   └── config/           # Configuration
│   ├── routes/               # API Routes
│   │   ├── auth.rs
│   │   └── users.rs
│   └── main.rs               # Entry Point
├── migrations/               # Database Migrations
├── tests/
├── .env.example
├── Cargo.toml
└── README.md

Technology Stack (Planned)

TechnologyPurposeVersion
RustLanguage1.70+
Actix-web/AxumWeb FrameworkLatest
Diesel/SeaORMORMLatest
tokioAsync RuntimeLatest
redisRedis ClientLatest
rusty-pasetoTrust TokensLatest
serdeSerializationLatest

Core Concepts (Preview)

1. Bridge Validation

rust
use serde::{Deserialize, Serialize};
use reqwest::Client;

#[derive(Debug, Clone)]
pub struct BridgeValidator {
    flowless_url: String,
    bridge_secret: String,
    client: Client,
}

#[derive(Debug, Serialize)]
pub struct ValidationOptions {
    pub ip: Option<String>,
    pub user_agent: Option<String>,
    pub device_id: Option<String>,
}

#[derive(Debug, Deserialize)]
pub struct Session {
    pub user_id: String,
    pub email: String,
}

impl BridgeValidator {
    pub fn new(flowless_url: String, bridge_secret: String) -> Self {
        Self {
            flowless_url,
            bridge_secret,
            client: Client::new(),
        }
    }
    
    pub async fn validate_session(
        &self,
        session_id: &str,
        opts: ValidationOptions,
    ) -> Result<Session, Box<dyn std::error::Error>> {
        let response = self.client
            .post(format!("{}/api/bridge/validate", self.flowless_url))
            .json(&serde_json::json!({
                "session_id": session_id,
                "bridge_secret": &self.bridge_secret,
                "ip": opts.ip,
                "user_agent": opts.user_agent,
                "device_id": opts.device_id,
            }))
            .send()
            .await?;
        
        let session: Session = response.json().await?;
        Ok(session)
    }
}

2. HybridCache

rust
use std::sync::Arc;
use tokio::sync::RwLock;
use redis::AsyncCommands;

pub struct HybridCache {
    redis: redis::Client,
    lru: Arc<RwLock<lru::LruCache<String, Vec<u8>>>>,
}

impl HybridCache {
    pub fn new(redis_url: &str, max_size: usize) -> Result<Self, redis::RedisError> {
        Ok(Self {
            redis: redis::Client::open(redis_url)?,
            lru: Arc::new(RwLock::new(lru::LruCache::new(max_size))),
        })
    }
    
    pub async fn get<F, T>(
        &self,
        namespace: &str,
        key: &str,
        fetcher: F,
    ) -> Result<T, Box<dyn std::error::Error>>
    where
        F: FnOnce() -> Result<T, Box<dyn std::error::Error>>,
        T: serde::Serialize + serde::de::DeserializeOwned,
    {
        let cache_key = format!("{}:{}", namespace, key);
        
        // Layer 1: LRU
        {
            let mut lru = self.lru.write().await;
            if let Some(cached) = lru.get(&cache_key) {
                return Ok(serde_json::from_slice(cached)?);
            }
        }
        
        // Layer 2: Redis
        let mut conn = self.redis.get_async_connection().await?;
        if let Ok(cached) = conn.get::<_, Vec<u8>>(&cache_key).await {
            let mut lru = self.lru.write().await;
            lru.put(cache_key.clone(), cached.clone());
            return Ok(serde_json::from_slice(&cached)?);
        }
        
        // Layer 3: Database
        let value = fetcher()?;
        let serialized = serde_json::to_vec(&value)?;
        
        // Store in Redis
        let _: () = conn.set_ex(&cache_key, &serialized, 300).await?;
        
        // Store in LRU
        let mut lru = self.lru.write().await;
        lru.put(cache_key, serialized);
        
        Ok(value)
    }
}

3. Auth Middleware (Actix-web)

rust
use actix_web::{dev::ServiceRequest, Error, HttpMessage};
use actix_web_httpauth::extractors::bearer::BearerAuth;

pub async fn require_auth(
    req: ServiceRequest,
    credentials: BearerAuth,
) -> Result<ServiceRequest, Error> {
    let validator = req.app_data::<BridgeValidator>()
        .ok_or_else(|| actix_web::error::ErrorInternalServerError("Validator not found"))?;
    
    let session = validator
        .validate_session(
            credentials.token(),
            ValidationOptions {
                ip: req.peer_addr().map(|addr| addr.ip().to_string()),
                user_agent: req.headers()
                    .get("user-agent")
                    .and_then(|h| h.to_str().ok())
                    .map(String::from),
                device_id: None,
            },
        )
        .await
        .map_err(|_| actix_web::error::ErrorUnauthorized("Invalid session"))?;
    
    req.extensions_mut().insert(session.user_id);
    Ok(req)
}

Want to Contribute?

We're looking for Rust developers to help build the official Rust starter kit!

How to Contribute

  1. Join the discussion - discord.gg/pubflow
  2. Review the 7 Core Concepts - Core Concepts
  3. Implement in Rust - Follow Rust best practices
  4. Submit PR - github.com/pubflow/flowfull-rust

Requirements

  • Implement all 7 core concepts
  • Follow Rust conventions and best practices
  • Include comprehensive tests
  • Provide clear documentation
  • Support Rust 1.70+
  • Use async/await with Tokio

Resources

Support


Interested in building this? Join us! 🚀

Released under the MIT License.