Better values
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
def hello(name):
|
||||
print("Hello, bro! " + name)
|
||||
return "Idk, return value i guess"
|
||||
# return "Idk, return value i guess"
|
||||
return 1.1
|
||||
+14
-5
@@ -1,10 +1,13 @@
|
||||
#[derive(Debug)]
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub enum FluxValue {
|
||||
Int(i64),
|
||||
Float(f64),
|
||||
Float(u64),
|
||||
Str(String),
|
||||
Null,
|
||||
// later: List(Vec<FluxValue>), Dict(HashMap<String, FluxValue>)
|
||||
Array(Vec<FluxValue>),
|
||||
Map(BTreeMap<FluxValue, FluxValue>),
|
||||
}
|
||||
|
||||
pub trait Serialize {
|
||||
@@ -21,9 +24,15 @@ pub trait FluxModule {
|
||||
fn call(&self, func: &str, args: Vec<&dyn Serialize>) -> FluxValue;
|
||||
}
|
||||
|
||||
pub mod values;
|
||||
pub mod runtime;
|
||||
pub mod values;
|
||||
|
||||
pub mod prelude {
|
||||
pub use crate::{FluxModule, Serialize, Deserialize};
|
||||
pub use crate::{Deserialize, FluxModule, Serialize};
|
||||
}
|
||||
|
||||
impl FluxValue {
|
||||
pub fn extract<T: Deserialize>(self) -> T {
|
||||
T::deserialize(self)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,5 +7,5 @@ fn main() {
|
||||
let gil = python::get_gil();
|
||||
let m = python::import("bro.py", &gil);
|
||||
|
||||
println!("{:?}", m.call("hello", vec![&"leo"]));
|
||||
println!("{:?}", m.call("hello", vec![&"leo"]).extract::<f64>());
|
||||
}
|
||||
|
||||
+56
-17
@@ -1,7 +1,9 @@
|
||||
use std::fs;
|
||||
|
||||
use crate::FluxModule;
|
||||
use cpython::{GILGuard, ObjectProtocol, PyObject, PyTuple, Python, PythonObject, ToPyObject};
|
||||
use crate::{FluxModule, FluxValue};
|
||||
use cpython::{
|
||||
GILGuard, ObjectProtocol, PyDict, PyList, PyObject, PyTuple, Python, PythonObject, ToPyObject,
|
||||
};
|
||||
|
||||
pub fn import<'a>(path: &str, gil: &'a GILGuard) -> PythonModule<'a> {
|
||||
let m = PythonModule {
|
||||
@@ -16,6 +18,30 @@ pub fn get_gil() -> GILGuard {
|
||||
Python::acquire_gil()
|
||||
}
|
||||
|
||||
pub fn flux_to_object(py: Python<'_>, flux: &FluxValue) -> PyObject {
|
||||
match flux {
|
||||
crate::FluxValue::Null => py.None(),
|
||||
crate::FluxValue::Int(i) => i.to_py_object(py).into_object(),
|
||||
crate::FluxValue::Float(f) => f.to_py_object(py).into_object(),
|
||||
crate::FluxValue::Str(s) => s.to_py_object(py).into_object(),
|
||||
crate::FluxValue::Array(a) => PyList::new(
|
||||
py,
|
||||
&a.iter()
|
||||
.map(|f| flux_to_object(py, f))
|
||||
.collect::<Vec<PyObject>>(),
|
||||
)
|
||||
.into_object(),
|
||||
crate::FluxValue::Map(a) => {
|
||||
let map = PyDict::new(py);
|
||||
for (k, v) in a {
|
||||
map.set_item(py, flux_to_object(py, k), flux_to_object(py, v))
|
||||
.unwrap();
|
||||
}
|
||||
map.into_object()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PythonModule<'a> {
|
||||
path: String,
|
||||
python: Python<'a>,
|
||||
@@ -33,28 +59,41 @@ impl FluxModule for PythonModule<'_> {
|
||||
|
||||
let py_args: Vec<PyObject> = args
|
||||
.iter()
|
||||
.map(|a| match a.serialize() {
|
||||
crate::FluxValue::Int(i) => i.to_py_object(self.python).into_object(),
|
||||
crate::FluxValue::Float(f) => f.to_py_object(self.python).into_object(),
|
||||
crate::FluxValue::Str(s) => s.to_py_object(self.python).into_object(),
|
||||
crate::FluxValue::Null => self.python.None(),
|
||||
})
|
||||
.map(|a| flux_to_object(self.python, &a.serialize()))
|
||||
.collect();
|
||||
|
||||
let args_tuple = PyTuple::new(self.python, &py_args);
|
||||
|
||||
let result: PyObject = func.call(self.python, args_tuple, None).unwrap();
|
||||
|
||||
if let Ok(i) = result.extract::<i64>(self.python) {
|
||||
crate::FluxValue::Int(i)
|
||||
} else if let Ok(f) = result.extract::<f64>(self.python) {
|
||||
crate::FluxValue::Float(f)
|
||||
} else if let Ok(s) = result.extract::<String>(self.python) {
|
||||
crate::FluxValue::Str(s)
|
||||
} else {
|
||||
crate::FluxValue::Null
|
||||
}
|
||||
to_flux_value(self.python, &result)
|
||||
}
|
||||
|
||||
fn end(&self) {}
|
||||
}
|
||||
|
||||
fn to_flux_value(py: Python, result: &PyObject) -> crate::FluxValue {
|
||||
if let Ok(i) = result.extract::<i64>(py) {
|
||||
crate::FluxValue::Int(i)
|
||||
} else if let Ok(f) = result.extract::<f64>(py) {
|
||||
crate::FluxValue::Float(f.to_bits())
|
||||
} else if let Ok(s) = result.extract::<String>(py) {
|
||||
crate::FluxValue::Str(s)
|
||||
} else if let Ok(list) = result.cast_as::<PyList>(py) {
|
||||
let mut items = Vec::new();
|
||||
for item in list.iter(py) {
|
||||
items.push(to_flux_value(py, &item));
|
||||
}
|
||||
crate::FluxValue::Array(items)
|
||||
} else if let Ok(dict) = result.cast_as::<PyDict>(py) {
|
||||
let mut map = std::collections::BTreeMap::new(); // or HashMap if you don’t need ordering
|
||||
for (k, v) in dict.items(py) {
|
||||
let key = to_flux_value(py, &k);
|
||||
let val = to_flux_value(py, &v);
|
||||
map.insert(key, val);
|
||||
}
|
||||
crate::FluxValue::Map(map)
|
||||
} else {
|
||||
crate::FluxValue::Null
|
||||
}
|
||||
}
|
||||
|
||||
+44
-2
@@ -1,3 +1,5 @@
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
|
||||
use crate::{Deserialize, FluxValue, Serialize};
|
||||
|
||||
impl Serialize for i64 {
|
||||
@@ -5,21 +7,61 @@ impl Serialize for i64 {
|
||||
FluxValue::Int(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for f64 {
|
||||
fn serialize(&self) -> FluxValue {
|
||||
FluxValue::Float(*self)
|
||||
FluxValue::Float(self.to_bits())
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize for f64 {
|
||||
fn deserialize(v: FluxValue) -> Self {
|
||||
match v {
|
||||
FluxValue::Float(bits) => f64::from_bits(bits),
|
||||
v => panic!("Expected Int, instead got {v:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for &str {
|
||||
fn serialize(&self) -> FluxValue {
|
||||
FluxValue::Str(self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for String {
|
||||
fn serialize(&self) -> FluxValue {
|
||||
FluxValue::Str(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize for i64 {
|
||||
fn deserialize(v: FluxValue) -> Self {
|
||||
match v {
|
||||
FluxValue::Int(i) => i,
|
||||
_ => panic!("Expected Int"),
|
||||
v => panic!("Expected Int, instead got {v:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Serialize, V: Serialize> Serialize for HashMap<K, V> {
|
||||
fn serialize(&self) -> FluxValue {
|
||||
FluxValue::Map(
|
||||
self.iter()
|
||||
.map(|(k, v)| (k.serialize(), v.serialize()))
|
||||
.collect::<BTreeMap<FluxValue, FluxValue>>(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Deserialize + Ord, V: Deserialize> Deserialize for BTreeMap<K, V> {
|
||||
fn deserialize(v: FluxValue) -> Self {
|
||||
match v {
|
||||
FluxValue::Map(m) => m
|
||||
.iter()
|
||||
.map(|(k, v)| (K::deserialize(k.clone()), V::deserialize(v.clone())))
|
||||
.collect::<BTreeMap<K, V>>(),
|
||||
v => panic!("Expected Int, instead got {v:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user