Better values

This commit is contained in:
2025-08-25 09:57:57 +02:00
parent e940987abb
commit 5f2e8fd25f
5 changed files with 117 additions and 26 deletions
+2 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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:?}"),
}
}
}