windjammer 0.48.0

A simple language inspired by Go, Ruby, and Elixir that transpiles to Rust - 80% of Rust's power with 20% of the complexity
Documentation
// Room management for wschat

use std::sync
use std::collections::HashMap
use std::collections::HashSet
use std::time

use ./message

const MAX_HISTORY_SIZE: int = 100

@derive(Debug, Clone)
pub struct Room {
    pub id: string,
    pub name: string,
    pub members: HashSet<string>,
    pub message_history: Vec<InternalMessage>,
    pub created_at: int,
}

impl Room {
    pub fn new(id: string, name: string) -> Self {
        Room {
            id: id.clone(),
            name: name,
            members: HashSet::new(),
            message_history: vec![],
            created_at: time.now_unix(),
        }
    }
    
    pub fn add_member(mut self, user_id: string) -> bool {
        self.members.insert(user_id)
    }
    
    pub fn remove_member(mut self, user_id: string) -> bool {
        self.members.remove(&user_id)
    }
    
    pub fn has_member(self, user_id: string) -> bool {
        self.members.contains(&user_id)
    }
    
    pub fn member_count(self) -> int {
        self.members.len()
    }
    
    pub fn add_message(mut self, msg: InternalMessage) {
        self.message_history.push(msg)
        
        // Trim history if too large
        if self.message_history.len() > MAX_HISTORY_SIZE {
            self.message_history = self.message_history
                .into_iter()
                .skip(self.message_history.len() - MAX_HISTORY_SIZE)
                .collect()
        }
    }
    
    pub fn get_history(self, limit: Option<int>) -> Vec<HistoryMessage> {
        let limit = limit.unwrap_or(50).min(MAX_HISTORY_SIZE)
        
        self.message_history
            .iter()
            .rev()
            .take(limit)
            .rev()
            .map(|msg| msg.clone().to_history_message())
            .collect()
    }
}

// Thread-safe room manager
pub struct RoomManager {
    rooms: Arc<Mutex<HashMap<string, Room>>>,
}

impl RoomManager {
    pub fn new() -> Self {
        RoomManager {
            rooms: Arc::new(Mutex::new(HashMap::new())),
        }
    }
    
    pub async fn create_room(self, room_id: string, room_name: string) -> Room {
        let mut rooms = self.rooms.lock().await
        
        if let Some(room) = rooms.get(&room_id) {
            return room.clone()
        }
        
        let mut room = Room::new(room_id.clone(), room_name)
        rooms.insert(room_id, room.clone())
        room
    }
    
    pub async fn get_room(self, room_id: string) -> Option<Room> {
        let rooms = self.rooms.lock().await
        rooms.get(&room_id).cloned()
    }
    
    pub async fn get_or_create_room(self, room_id: string) -> Room {
        if let Some(room) = self.get_room(room_id.clone()).await {
            return room
        }
        
        self.create_room(room_id.clone(), room_id).await
    }
    
    pub async fn join_room(self, room_id: string, user_id: string) -> Result<Room, Error> {
        let mut rooms = self.rooms.lock().await
        
        if let Some(room) = rooms.get_mut(&room_id) {
            room.add_member(user_id)
            Ok(room.clone())
        } else {
            // Create room if it doesn't exist
            let mut room = Room::new(room_id.clone(), room_id.clone())
            room.add_member(user_id)
            rooms.insert(room_id, room.clone())
            Ok(room)
        }
    }
    
    pub async fn leave_room(self, room_id: string, user_id: string) -> Result<bool, Error> {
        let mut rooms = self.rooms.lock().await
        
        if let Some(room) = rooms.get_mut(&room_id) {
            room.remove_member(user_id)
            
            // Remove empty rooms
            if room.member_count() == 0 {
                rooms.remove(&room_id)
                return Ok(true)  // Room deleted
            }
            
            Ok(false)  // Room still exists
        } else {
            Err("Room not found")
        }
    }
    
    pub async fn add_message(self, room_id: string, msg: InternalMessage) -> Result<(), Error> {
        let mut rooms = self.rooms.lock().await
        
        if let Some(room) = rooms.get_mut(&room_id) {
            room.add_message(msg)
            Ok(())
        } else {
            Err("Room not found")
        }
    }
    
    pub async fn get_history(
        self, 
        room_id: string, 
        limit: Option<int>
    ) -> Result<Vec<HistoryMessage>, Error> {
        let rooms = self.rooms.lock().await
        
        if let Some(room) = rooms.get(&room_id) {
            Ok(room.get_history(limit))
        } else {
            Err("Room not found")
        }
    }
    
    pub async fn get_members(self, room_id: string) -> Result<Vec<string>, Error> {
        let rooms = self.rooms.lock().await
        
        if let Some(room) = rooms.get(&room_id) {
            Ok(room.members.iter().cloned().collect())
        } else {
            Err("Room not found")
        }
    }
    
    pub async fn get_room_count(self) -> int {
        let rooms = self.rooms.lock().await
        rooms.len()
    }
    
    pub async fn get_total_members(self) -> int {
        let rooms = self.rooms.lock().await
        rooms.values().map(|r| r.member_count()).sum()
    }
}