Better values
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
def hello(name):
|
def hello(name):
|
||||||
print("Hello, bro! " + 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 {
|
pub enum FluxValue {
|
||||||
Int(i64),
|
Int(i64),
|
||||||
Float(f64),
|
Float(u64),
|
||||||
Str(String),
|
Str(String),
|
||||||
Null,
|
Null,
|
||||||
// later: List(Vec<FluxValue>), Dict(HashMap<String, FluxValue>)
|
Array(Vec<FluxValue>),
|
||||||
|
Map(BTreeMap<FluxValue, FluxValue>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Serialize {
|
pub trait Serialize {
|
||||||
@@ -21,9 +24,15 @@ pub trait FluxModule {
|
|||||||
fn call(&self, func: &str, args: Vec<&dyn Serialize>) -> FluxValue;
|
fn call(&self, func: &str, args: Vec<&dyn Serialize>) -> FluxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod values;
|
|
||||||
pub mod runtime;
|
pub mod runtime;
|
||||||
|
pub mod values;
|
||||||
|
|
||||||
pub mod prelude {
|
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 gil = python::get_gil();
|
||||||
let m = python::import("bro.py", &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 std::fs;
|
||||||
|
|
||||||
use crate::FluxModule;
|
use crate::{FluxModule, FluxValue};
|
||||||
use cpython::{GILGuard, ObjectProtocol, PyObject, PyTuple, Python, PythonObject, ToPyObject};
|
use cpython::{
|
||||||
|
GILGuard, ObjectProtocol, PyDict, PyList, PyObject, PyTuple, Python, PythonObject, ToPyObject,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn import<'a>(path: &str, gil: &'a GILGuard) -> PythonModule<'a> {
|
pub fn import<'a>(path: &str, gil: &'a GILGuard) -> PythonModule<'a> {
|
||||||
let m = PythonModule {
|
let m = PythonModule {
|
||||||
@@ -16,6 +18,30 @@ pub fn get_gil() -> GILGuard {
|
|||||||
Python::acquire_gil()
|
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> {
|
pub struct PythonModule<'a> {
|
||||||
path: String,
|
path: String,
|
||||||
python: Python<'a>,
|
python: Python<'a>,
|
||||||
@@ -33,28 +59,41 @@ impl FluxModule for PythonModule<'_> {
|
|||||||
|
|
||||||
let py_args: Vec<PyObject> = args
|
let py_args: Vec<PyObject> = args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| match a.serialize() {
|
.map(|a| flux_to_object(self.python, &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(),
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let args_tuple = PyTuple::new(self.python, &py_args);
|
let args_tuple = PyTuple::new(self.python, &py_args);
|
||||||
|
|
||||||
let result: PyObject = func.call(self.python, args_tuple, None).unwrap();
|
let result: PyObject = func.call(self.python, args_tuple, None).unwrap();
|
||||||
|
|
||||||
if let Ok(i) = result.extract::<i64>(self.python) {
|
to_flux_value(self.python, &result)
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(&self) {}
|
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};
|
use crate::{Deserialize, FluxValue, Serialize};
|
||||||
|
|
||||||
impl Serialize for i64 {
|
impl Serialize for i64 {
|
||||||
@@ -5,21 +7,61 @@ impl Serialize for i64 {
|
|||||||
FluxValue::Int(*self)
|
FluxValue::Int(*self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for f64 {
|
impl Serialize for f64 {
|
||||||
fn serialize(&self) -> FluxValue {
|
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 {
|
impl Serialize for &str {
|
||||||
fn serialize(&self) -> FluxValue {
|
fn serialize(&self) -> FluxValue {
|
||||||
FluxValue::Str(self.to_string())
|
FluxValue::Str(self.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Serialize for String {
|
||||||
|
fn serialize(&self) -> FluxValue {
|
||||||
|
FluxValue::Str(self.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Deserialize for i64 {
|
impl Deserialize for i64 {
|
||||||
fn deserialize(v: FluxValue) -> Self {
|
fn deserialize(v: FluxValue) -> Self {
|
||||||
match v {
|
match v {
|
||||||
FluxValue::Int(i) => i,
|
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