Files
multiverse/xcom-ultra/xcu-iam-gatekeeper/rust_src/lib.rs
T

104 lines
3.2 KiB
Rust

//! [TSM.ID].[11031972] -- Platform X Ecosystem
//! xcu-iam-gatekeeper -- Identity Access Management gatekeeper engine
#![deny(warnings)]
use serde::{Serialize, Deserialize};
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
#[derive(Debug)]
pub enum BridgeError {
ConnectionFailed(String),
ConfigError(String),
OperationFailed(String),
NotReady,
}
impl std::fmt::Display for BridgeError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::ConnectionFailed(e) => write!(f, "Connection failed: {e}"),
Self::ConfigError(e) => write!(f, "Config error: {e}"),
Self::OperationFailed(e) => write!(f, "Op failed: {e}"),
Self::NotReady => write!(f, "Not ready"),
}
}
}
impl std::error::Error for BridgeError {}
pub type Result<T> = std::result::Result<T, BridgeError>;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BridgeConfig {
pub name: String,
pub endpoint: String,
pub params: HashMap<String, String>,
pub enabled: bool,
}
impl BridgeConfig {
pub fn new(name: &str, endpoint: &str) -> Self {
Self { name: name.to_string(), endpoint: endpoint.to_string(), params: HashMap::new(), enabled: true }
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum BridgeState { Disconnected, Connecting, Connected, Error(String) }
pub struct Bridge {
config: BridgeConfig,
state: Arc<Mutex<BridgeState>>,
message_count: Arc<Mutex<u64>>,
}
impl Bridge {
pub fn new(config: BridgeConfig) -> Result<Self> {
Ok(Self {
config, state: Arc::new(Mutex::new(BridgeState::Disconnected)),
message_count: Arc::new(Mutex::new(0)),
})
}
pub fn connect(&self) -> Result<()> {
let mut s = self.state.lock().map_err(|e| BridgeError::OperationFailed(e.to_string()))?;
*s = BridgeState::Connecting;
*s = BridgeState::Connected;
Ok(())
}
pub fn disconnect(&self) -> Result<()> {
let mut s = self.state.lock().map_err(|e| BridgeError::OperationFailed(e.to_string()))?;
*s = BridgeState::Disconnected;
Ok(())
}
pub fn send(&self, _payload: &[u8]) -> Result<u64> {
let s = self.state.lock().map_err(|e| BridgeError::OperationFailed(e.to_string()))?;
if *s != BridgeState::Connected { return Err(BridgeError::NotReady); }
drop(s);
let mut c = self.message_count.lock().map_err(|e| BridgeError::OperationFailed(e.to_string()))?;
*c += 1;
Ok(*c)
}
pub fn state(&self) -> Result<BridgeState> {
Ok(self.state.lock().map_err(|e| BridgeError::OperationFailed(e.to_string()))?.clone())
}
pub fn config(&self) -> &BridgeConfig { &self.config }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bridge() {
let b = Bridge::new(BridgeConfig::new("xcu-iam-gatekeeper", "localhost:3000")).unwrap();
assert_eq!(b.state().unwrap(), BridgeState::Disconnected);
b.connect().unwrap();
assert_eq!(b.state().unwrap(), BridgeState::Connected);
b.send(b"hello").unwrap();
b.disconnect().unwrap();
assert_eq!(b.state().unwrap(), BridgeState::Disconnected);
}
}