socketboard 0.1.0

The official Rust SDK for Socketboard, a lightweight websocket variable table.
Documentation
use std::collections::HashMap;
use std::fmt::Display;
use serde_json::Value;

#[derive(Clone)]
pub enum Data {
    String(String),
    Number(f64),
    Boolean(bool),
    Array(Vec<Data>),
    Object(HashMap<String, Data>),
    None,
}

impl Display for Data {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            Data::String(s) => write!(f, "{}", s),
            Data::Number(n) => write!(f, "{}", n),
            Data::Boolean(b) => write!(f, "{}", b),
            Data::Array(a) => {
                write!(f, "[")?;
                for (i, data) in a.iter().enumerate() {
                    write!(f, "{}", data)?;
                    if i < a.len() - 1 {
                        write!(f, ", ")?;
                    }
                }
                write!(f, "]")
            }
            Data::Object(o) => {
                write!(f, "{{")?;
                for (i, (key, value)) in o.iter().enumerate() {
                    write!(f, "\"{}\": {}", key, value)?;
                    if i < o.len() - 1 {
                        write!(f, ", ")?;
                    }
                }
                write!(f, "}}")
            }
            Data::None => write!(f, "None"),
        }
    }
}

pub trait JSON {
    fn to_json(&self) -> serde_json::Value;
    fn from_json(value: &serde_json::Value) -> Self;
}

impl JSON for Data {
    fn to_json(&self) -> Value {
        match self {
            Data::String(s) => Value::String(s.clone()),
            Data::Number(n) => Value::Number(serde_json::Number::from_f64(*n).unwrap()),
            Data::Boolean(b) => Value::Bool(*b),
            Data::Array(a) => {
                let mut json_array = Vec::new();
                for data in a {
                    json_array.push(data.to_json());
                }
                Value::Array(json_array)
            }
            Data::Object(o) => {
                let mut json_object = serde_json::Map::new();
                for (key, value) in o {
                    json_object.insert(key.clone(), value.to_json());
                }
                Value::Object(json_object)
            }
            Data::None => Value::Null,
        }
    }
    
    fn from_json(value: &Value) -> Self {
        match value {
            Value::String(s) => Data::String(s.clone()),
            Value::Number(n) => Data::Number(n.as_f64().unwrap()),
            Value::Bool(b) => Data::Boolean(*b),
            Value::Array(a) => {
                let mut data_array = Vec::new();
                for json_value in a {
                    data_array.push(Data::from_json(json_value));
                }
                Data::Array(data_array)
            }
            Value::Object(o) => {
                let mut data_object = HashMap::new();
                for (key, json_value) in o {
                    data_object.insert(key.clone(), Data::from_json(json_value));
                }
                Data::Object(data_object)
            }
            Value::Null => Data::None,
        }
    }
}

#[derive(Clone)]
pub enum ConnectionStatus {
    Connected(String),
    Failed(String),
    Disconnected(String),
    Connecting,
    Stopped,
    None
}

impl Display for ConnectionStatus {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            ConnectionStatus::Connected(address) => write!(f, "Connected to {}", address),
            ConnectionStatus::Failed(address) => write!(f, "Failed to connect to {}", address),
            ConnectionStatus::Disconnected(address) => write!(f, "Disconnected from {}", address),
            ConnectionStatus::Connecting => write!(f, "Connecting..."),
            ConnectionStatus::Stopped => write!(f, "Stopped"),
            ConnectionStatus::None => write!(f, "None"),
        }
    }
}