profile_kit

Crates.ioprofile_kit
lib.rsprofile_kit
version0.1.1
created_at2025-05-12 10:25:05.070252+00
updated_at2025-05-31 12:23:22.586585+00
descriptionA flexible, lightweight Rust library for managing user profiles.
homepage
repositoryhttps://github.com/jerry-maheswara-github/profile_kit
max_upload_size
id1670337
size46,823
Jerry Maheswara (jerry-maheswara-github)

documentation

https://docs.rs/profile_kit

README

profile_kit

A flexible, lightweight Rust library for managing user profiles โ€” framework-agnostic, developer-friendly, and production-ready.


โœจ Features

  • ๐Ÿ”Œ Pluggable profile storage via trait abstraction
  • โš™๏ธ Designed for composability in any Rust project
  • ๐ŸŒ Supports user preferences (language, currency, newsletter opt-in)
  • ๐Ÿงช Easy to test with in-memory implementation
  • ๐Ÿ“ฆ Lightweight dependencies, ready for web or backend apps

๐Ÿš€ Quick Start

use serde_json::{json, Value};
use uuid::Uuid;
use profile_kit::model::{UserAttributes, UserPreferences, UserProfile};

fn main() {
    let mut prefs = UserPreferences::new();
    prefs.set_newsletter_opt_in(true);
    prefs.set_extra("theme".to_string(), json!("dark"));
    prefs.set_extra("custom_field".to_string(), json!({"key": "value"}));

    let mut attrs = UserAttributes::new();
    attrs.set_first_name("John".to_string());
    attrs.set_last_name("Doe".to_string());
    attrs.set_extra("theme", Value::String("dark".into()));
    attrs.set_extra("roles", json!(vec!["admin", "editor"]));

    let id = Uuid::now_v7().simple();
    let email = "".to_string();
    let mut profile = UserProfile::new(id.to_string(), email);
    profile.set_email("john.doe@example.com".to_string());
    profile.set_attributes(Some(attrs));
    profile.set_preferences(Some(prefs));
    
    let serialized = serde_json::to_string_pretty(&profile).expect("REASON");
    eprintln!("Serialized profile: {}", serialized);

    let deserialized: UserProfile = serde_json::from_str(&serialized).expect("REASON");
    eprintln!("Deserialized profile: {:?}", deserialized);
    
    eprintln!("roles : {:?}", deserialized.get_attributes().expect("REASON").get_extra("roles"));
    eprintln!("first_name : {:?}", deserialized.get_attributes().expect("REASON").get_first_name());
}

๐Ÿ”ง Trait-based Storage Example

use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use profile_kit::error::ProfileKitError;
use profile_kit::model::UserProfile;
use profile_kit::repository::UserProfileRepository;

pub struct InMemoryUserProfileRepository {
    storage: Arc<RwLock<HashMap<String, UserProfile>>>,
}

impl InMemoryUserProfileRepository {
    pub fn new() -> Self {
        InMemoryUserProfileRepository {
            storage: Arc::new(RwLock::new(HashMap::new())),
        }
    }
}

impl UserProfileRepository for InMemoryUserProfileRepository {
    fn get_by_id(&self, id: String) -> Result<Option<UserProfile>, ProfileKitError> {
        let storage = self.storage.read().map_err(|_| ProfileKitError::StorageError)?;
        Ok(storage.get(&id).cloned())
    }

    fn create(&self, profile: UserProfile) -> Result<(), ProfileKitError> {
        let mut storage = self.storage.write().map_err(|_| ProfileKitError::StorageError)?;
        if storage.contains_key(&profile.id) {
            return Err(ProfileKitError::AlreadyExists);
        }
        storage.insert(profile.id.clone(), profile);
        Ok(())
    }

    fn update(&self, profile: UserProfile) -> Result<(), ProfileKitError> {
        let mut storage = self.storage.write().map_err(|_| ProfileKitError::StorageError)?;
        if !storage.contains_key(&profile.id) {
            return Err(ProfileKitError::NotFound);
        }
        storage.insert(profile.id.clone(), profile);
        Ok(())
    }

    fn delete(&self, id: String) -> Result<(), ProfileKitError> {
        let mut storage = self.storage.write().map_err(|_| ProfileKitError::StorageError)?;
        if storage.remove(&id).is_none() {
            return Err(ProfileKitError::NotFound);
        }
        Ok(())
    }
}

use uuid::Uuid;
use profile_kit::model;

fn main() {
    let repo = InMemoryUserProfileRepository::new();
    let id= Uuid::now_v7().simple();
    let mut user = UserProfile::new(id.to_string(), "test@example.com".into());
    user.set_email("john.doe@example.com".to_string());
    
    repo.create(user).expect("Failed to create user");
    
    eprintln!("id {:?}", id.to_string());
    eprintln!("id {:?}", repo.get_by_id(id.to_string()));
}

๐Ÿ“– License

This project is licensed under the Apache-2.0 license. LICENSE


๐Ÿง‘โ€ Author

Jerry Maheswara jerrymaheswara@gmail.com


โค๏ธ Built with Love in Rust

This project is built with โค๏ธ using Rust โ€” a systems programming language that is safe, fast, and concurrent. Rust is the perfect choice for building reliable and efficient applications.


๐Ÿ‘‹ Contributing

Pull requests, issues, and feedback are welcome!
If you find this crate useful, give it a โญ and share it with others in the Rust community.


Commit count: 5

cargo fmt