thread-share 0.1.6

A Rust library for safe and efficient data sharing between threads with zero-copy operations, change detection, and enhanced thread management.
Documentation
use std::net::TcpStream;
use std::time::Duration;
use thread_share::{enhanced_share, spawn_workers};

// Structures for socket client work
#[derive(Clone, Debug)]
struct SocketStatus {
    is_connected: bool,
    last_error: Option<String>,
    address: String,
}

#[derive(Clone, Debug)]
struct Message {
    content: String,
}

#[derive(Clone, Debug)]
struct ClientStats {
    messages_sent: u32,
    messages_received: u32,
    connection_attempts: u32,
    total_bytes_sent: u64,
    total_bytes_received: u64,
}

#[derive(Clone, Debug)]
struct SocketClient {
    status: SocketStatus,
    stats: ClientStats,
    message_queue: Vec<Message>,
}

impl SocketClient {
    fn new(address: String) -> Self {
        Self {
            status: SocketStatus {
                is_connected: false,
                last_error: None,
                address,
            },
            stats: ClientStats {
                messages_sent: 0,
                messages_received: 0,
                connection_attempts: 0,
                total_bytes_sent: 0,
                total_bytes_received: 0,
            },
            message_queue: Vec::new(),
        }
    }

    fn connect(&mut self) -> Result<(), String> {
        match TcpStream::connect(&self.status.address) {
            Ok(_) => {
                self.status.is_connected = true;
                self.status.last_error = None;
                self.stats.connection_attempts += 1;
                Ok(())
            }
            Err(e) => {
                let error_msg = format!("Failed to connect: {}", e);
                self.status.last_error = Some(error_msg.clone());
                self.status.is_connected = false;
                self.stats.connection_attempts += 1;
                Err(error_msg)
            }
        }
    }

    fn disconnect(&mut self) {
        self.status.is_connected = false;
        self.status.last_error = Some("Disconnected by user".to_string());
    }

    fn send_message(&mut self, message: &str) -> Result<usize, String> {
        if !self.status.is_connected {
            return Err("Not connected".to_string());
        }

        // Simulate sending (in real app there would be TcpStream)
        let bytes_sent = message.len();
        self.stats.messages_sent += 1;
        self.stats.total_bytes_sent += bytes_sent as u64;

        // Track message count (content field removed to avoid warning)
        self.message_queue.push(Message {
            content: message.to_string(),
        });

        Ok(bytes_sent)
    }

    fn receive_message(&mut self) -> Result<String, String> {
        if !self.status.is_connected {
            return Err("Not connected".to_string());
        }

        // Simulate receiving response
        let response = format!(
            "Server response to message {}",
            self.stats.messages_received + 1
        );
        let bytes_received = response.len();

        self.stats.messages_received += 1;
        self.stats.total_bytes_received += bytes_received as u64;

        Ok(response)
    }
}

fn main() {
    println!("=== Socket Client Example with EnhancedThreadShare ===");

    // Create shared socket client with enhanced thread management
    let client = enhanced_share!(SocketClient::new("localhost:8080".to_string()));

    // Start all threads with one command!
    spawn_workers!(client, {
        connection: |client: thread_share::ThreadShare<SocketClient>| {
            let mut attempts = 0;

            while attempts < 3 {
                println!("Attempting to connect to localhost:8080 (attempt {})", attempts + 1);

                match client.write(|client| client.connect()) {
                    Ok(_) => {
                        println!("โœ… Successfully connected!");
                        break;
                    }
                    Err(e) => {
                        println!("โŒ Connection failed: {}", e);
                        attempts += 1;
                        std::thread::sleep(Duration::from_millis(2000));
                    }
                }
            }

            if attempts >= 3 {
                println!("โŒ Failed to connect after 3 attempts");
            }
        },

        sender: |client: thread_share::ThreadShare<SocketClient>| {
            // Wait for connection
            while !client.get().status.is_connected {
                std::thread::sleep(Duration::from_millis(100));
            }

            println!("๐Ÿ“ค Sender thread started");

            // Send test messages
            for i in 1..=5 {
                let message = format!("Hello Server! Message {}", i);

                match client.write(|client| client.send_message(&message)) {
                    Ok(bytes_sent) => {
                        println!("๐Ÿ“ค Sent: {} ({} bytes)", message, bytes_sent);
                    }
                    Err(e) => {
                        println!("โŒ Failed to send message: {}", e);
                    }
                }

                std::thread::sleep(Duration::from_millis(500));
            }

            // Disconnect after sending all messages
            client.update(|client| client.disconnect());
            println!("๐Ÿ“ค Sender thread finished");
        },

        receiver: |client| {
            // Wait for connection
            while !client.get().status.is_connected {
                std::thread::sleep(Duration::from_millis(100));
            }

            println!("๐Ÿ“ฅ Receiver thread started");

            // Receive responses from server
            for _ in 1..=5 {
                // Wait a bit before "receiving" response
                std::thread::sleep(Duration::from_millis(600));

                match client.write(|client| client.receive_message()) {
                    Ok(response) => {
                        println!("๐Ÿ“ฅ Received: {} ({} bytes)", response, response.len());
                    }
                    Err(e) => {
                        println!("โŒ Failed to receive message: {}", e);
                        break;
                    }
                }

                // Check if disconnected
                if !client.get().status.is_connected {
                    break;
                }
            }

            println!("๐Ÿ“ฅ Receiver thread finished");
        }
    });

    // Main thread - state monitoring
    println!("๐Ÿš€ Socket Client Example Started");
    println!("๐Ÿ”Œ Connecting to localhost:8080...");

    let mut last_stats = ClientStats {
        messages_sent: 0,
        messages_received: 0,
        connection_attempts: 0,
        total_bytes_sent: 0,
        total_bytes_received: 0,
    };

    // Real-time monitoring
    while client.get().status.is_connected
        || client.get().stats.messages_sent < 5
        || client.get().stats.messages_received < 5
    {
        let current_client = client.get();

        // Output statistics changes
        if current_client.stats.messages_sent != last_stats.messages_sent
            || current_client.stats.messages_received != last_stats.messages_received
            || current_client.stats.connection_attempts != last_stats.connection_attempts
        {
            println!("\n=== ๐Ÿ“Š Status Update ===");
            println!(
                "๐Ÿ”Œ Connection: {}",
                if current_client.status.is_connected {
                    "โœ… Connected"
                } else {
                    "โŒ Disconnected"
                }
            );
            println!("๐Ÿ“ค Messages sent: {}", current_client.stats.messages_sent);
            println!(
                "๐Ÿ“ฅ Messages received: {}",
                current_client.stats.messages_received
            );
            println!(
                "๐Ÿ”„ Connection attempts: {}",
                current_client.stats.connection_attempts
            );
            println!(
                "๐Ÿ“Š Total bytes sent: {}",
                current_client.stats.total_bytes_sent
            );
            println!(
                "๐Ÿ“Š Total bytes received: {}",
                current_client.stats.total_bytes_received
            );
            println!(
                "๐Ÿ“‹ Message queue size: {}",
                current_client.message_queue.len()
            );
            if let Some(last_msg) = current_client.message_queue.last() {
                println!("๐Ÿ“ Last message: {}", last_msg.content);
            }
            println!("๐Ÿงต Active threads: {}", client.active_threads());

            if let Some(ref error) = current_client.status.last_error {
                println!("โš ๏ธ  Last error: {}", error);
            }
            println!("==================\n");

            last_stats = current_client.stats.clone();
        }

        std::thread::sleep(Duration::from_millis(200));
    }

    // Wait for all threads to complete with one command!
    client.join_all().expect("Failed to join threads");

    // Final statistics
    let final_client = client.get();

    println!("\n=== ๐Ÿ Final Results ===");
    println!(
        "๐Ÿ”Œ Connection status: {}",
        if final_client.status.is_connected {
            "โœ… Connected"
        } else {
            "โŒ Disconnected"
        }
    );
    println!(
        "๐Ÿ“ค Total messages sent: {}",
        final_client.stats.messages_sent
    );
    println!(
        "๐Ÿ“ฅ Total messages received: {}",
        final_client.stats.messages_received
    );
    println!(
        "๐Ÿ”„ Total connection attempts: {}",
        final_client.stats.connection_attempts
    );
    println!(
        "๐Ÿ“Š Total bytes sent: {}",
        final_client.stats.total_bytes_sent
    );
    println!(
        "๐Ÿ“Š Total bytes received: {}",
        final_client.stats.total_bytes_received
    );
    println!(
        "๐Ÿ“‹ Final message queue size: {}",
        final_client.message_queue.len()
    );

    if let Some(ref error) = final_client.status.last_error {
        println!("โš ๏ธ  Final error: {}", error);
    }

    println!("\nโœ… Example completed successfully!");
    println!("๐ŸŽฏ This example demonstrates:");
    println!("   โ€ข Using EnhancedThreadShare for simplified thread management");
    println!("   โ€ข Single macro call to spawn multiple threads");
    println!("   โ€ข Automatic thread joining with join_all()");
    println!("   โ€ข Real-time monitoring of client state and thread count");
    println!("   โ€ข Error handling and status tracking");
    println!("   โ€ข No more manual clone() and thread::spawn() calls!");
}