use super::*;
#[derive(Debug, Serialize, Deserialize)]
pub enum Action {
Get,
Set { value: String },
}
#[derive(Debug, Serialize, Deserialize)]
pub enum Request {
ObjectProperty {
type_name: String,
id: Uuid,
property: String,
action: Action,
},
}
impl Request {
pub fn new_property(
type_name: String,
id: Uuid,
property: String,
value: Option<String>,
) -> String {
serde_json::json! {
Request::ObjectProperty {
type_name,
id,
property,
action: if let Some(value) = value {
Action::Set {
value,
}
} else {
Action::Get
}
}
}
.to_string()
}
}
#[derive(Debug, Serialize, Deserialize)]
pub enum Response {
Error {
message: String,
},
List {
value: Vec<ObjectValue>,
},
Dict {
value: IndexMap<String, ObjectValue>,
},
Object(ObjectValue),
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ObjectValue {
pub py_type: PyType,
pub value: serde_json::Value,
}
impl From<glib::Value> for Response {
fn from(value: glib::Value) -> Self {
use serde_json::json;
match value.type_() {
glib::types::Type::UNIT => Self::Object(ObjectValue {
py_type: PyType::None,
value: json!(null),
}),
glib::types::Type::BOOL => Self::Object(ObjectValue {
py_type: PyType::Bool,
value: json! {value.get::<bool>().unwrap()},
}),
glib::types::Type::STRING => Self::Object(ObjectValue {
py_type: PyType::String,
value: json! {value.get::<String>().unwrap()},
}),
glib::types::Type::F64 => Self::Object(ObjectValue {
py_type: PyType::Float,
value: json! {value.get::<f64>().unwrap()},
}),
glib::types::Type::U64 => Self::Object(ObjectValue {
py_type: PyType::Int,
value: json! {value.get::<u64>().unwrap()},
}),
glib::types::Type::I64 => Self::Object(ObjectValue {
py_type: PyType::Int,
value: json! {value.get::<i64>().unwrap()},
}),
other => unimplemented!("{other:?}"),
}
}
}
impl From<ObjectValue> for Response {
fn from(value: ObjectValue) -> Self {
Self::Object(value)
}
}
impl From<Uuid> for Response {
fn from(value: Uuid) -> Self {
use serde_json::json;
Self::Object(ObjectValue {
py_type: PyType::Bytes,
value: json!(value.as_bytes()),
})
}
}
impl From<Either<Uuid, ObjectValue>> for Response {
fn from(value: Either<Uuid, ObjectValue>) -> Self {
match value {
Either::A(uuid) => uuid.into(),
Either::B(val) => val.into(),
}
}
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub enum PyType {
Bool,
Bytes,
Dict,
List,
Float,
UInt,
Int,
String,
None,
}
impl PyType {
pub fn into_any(self, value: serde_json::Value, py: Python<'_>) -> Py<PyAny> {
use PyType::*;
match self {
Bool => PyBool::new(py, value.as_bool().unwrap()).into(),
Bytes => PyBytes::new(
py,
&serde_json::value::from_value::<Vec<u8>>(value).unwrap(),
)
.into(),
Dict => {
let ret = PyDict::new(py);
let map: IndexMap<std::string::String, Uuid> =
serde_json::value::from_value(value).unwrap();
for (k, v) in map {
ret.set_item(k, PyBytes::new(py, v.as_bytes())).unwrap();
}
ret.into()
}
List => unimplemented!("Python list() objects have not been implemented."),
Float => PyFloat::new(py, value.as_f64().unwrap()).into(),
UInt => value.as_u64().unwrap().into_py(py),
Int => value.as_i64().unwrap().into_py(py),
String => PyString::new(py, value.as_str().unwrap()).into(),
None => py.None(),
}
}
}