rice-sdk 0.1.2

Rust sdk for interacting with Rice
Documentation
use rice_core::config::RiceConfig;
use rice_core::error::RiceError;
use rice_state::client::StateClient;
use rice_storage::client::StorageClient;

pub struct Client {
    pub storage: Option<StorageClient>,
    pub state: Option<StateClient>,
}

impl Client {
    pub async fn new(config: RiceConfig) -> Result<Self, RiceError> {
        let storage = if let Some(storage_config) = config.storage {
            if storage_config.enabled {
                let url = storage_config
                    .base_url
                    .unwrap_or_else(|| "http://localhost:50051".to_string());
                let token = storage_config.auth_token;

                // Heuristic: If URL contains "grpc", treat as gRPC. Otherwise HTTP.
                // Or if it matches typical REST ports?
                // For now, let's assume if it doesn't say "grpc", it might be HTTP if it fails?
                // Better: Explicitly check scheme or keyword.
                // The provided URLs: `grpc...` vs `api...`.

                if url.contains("grpc") {
                    if let Some(t) = token {
                        Some(StorageClient::connect_with_token(url, t).await?)
                    } else {
                        Some(StorageClient::connect(url).await?)
                    }
                } else {
                    // Assume HTTP
                    let valid_url = if url.starts_with("http://") || url.starts_with("https://") {
                        url
                    } else {
                        format!("http://{}", url)
                    };
                    let mut client = StorageClient::connect_http_url(valid_url, token.clone())?;

                    // Auto-login mirroring Node SDK behavior:
                    // If username is present and auth_token (used as password) is present, attempt login.
                    if let Some(user) = &storage_config.username {
                        if let Some(pwd) = &token {
                            // We ignore errors here to allow partial functionality if auth fails/is not needed for some ops
                            let _ = client.login(user.clone(), pwd.clone()).await;
                        }
                    }
                    Some(client)
                }
            } else {
                None
            }
        } else {
            None
        };

        let state = if let Some(state_config) = config.state {
            if state_config.enabled {
                let url = state_config
                    .base_url
                    .unwrap_or_else(|| "http://localhost:50051".to_string());
                if let Some(token) = state_config.auth_token {
                    Some(StateClient::connect_with_token(url, token).await?)
                } else {
                    Some(StateClient::connect(url).await?)
                }
            } else {
                None
            }
        } else {
            None
        };

        Ok(Self { storage, state })
    }
}