Skip to content

Commit bcec273

Browse files
committed
Initial Commit
1 parent 8fc692b commit bcec273

File tree

5 files changed

+184
-0
lines changed

5 files changed

+184
-0
lines changed

Cargo.toml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "python-rust-library"
3+
version = "0.1.0"
4+
authors = ["marcos"]
5+
6+
[lib]
7+
name = "mvrpl"
8+
crate-type = ["dylib"]
9+
10+
[dependencies]
11+
curl = "0.2.11"
12+
serde = "1.0"
13+
serde_derive = "1.0"
14+
serde_json = "1.0"
15+
16+
[dependencies.cpython]
17+
git = "https://github.com/dgrunwald/rust-cpython.git"
18+
default-features = false
19+
features = ["python27-sys"]

Makefile

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
all: run
2+
3+
build:
4+
cargo build --release
5+
mv ./target/release/libmvrpl.dylib ./mvrpl.so
6+
7+
run: build
8+
python test.py
9+
10+
clean:
11+
cargo clean
12+
rm ./example.so

src/lib.rs

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#[macro_use] extern crate cpython;
2+
extern crate curl;
3+
extern crate serde;
4+
extern crate serde_json;
5+
pub mod utils;
6+
7+
use cpython::{Python, PyDict, PyList, PyResult, ToPyObject, PyObject};
8+
use curl::http;
9+
use std::collections::BTreeMap;
10+
use serde_json::Value;
11+
12+
fn retpy(py: Python) -> PyResult<String> {
13+
let locals = PyDict::new(py);
14+
locals.set_item(py, "os", py.import("os")?)?;
15+
let user: String = py.eval("os.getenv('HOME')", None, Some(&locals))?.extract(py)?;
16+
Ok(user.to_string())
17+
}
18+
19+
fn returl(py: Python) -> PyResult<PyObject> {
20+
let url = "http://validate.jsontest.com/?json=%7B%22key%22:%22value%22%7D";
21+
let resp = http::handle()
22+
.get(url)
23+
.exec()
24+
.unwrap_or_else(|e| {
25+
panic!("Falha ao abrir URL {}; Erro: {}", url, e);
26+
});
27+
let body = std::str::from_utf8(resp.get_body()).unwrap_or_else(|e| {
28+
panic!("Falha ao interpretar resultado da URL {}; Erro: {}", url, e);
29+
});
30+
31+
let test: Value = serde_json::from_str(&body).unwrap();
32+
33+
let ret = utils::fromjson(py, test);
34+
35+
Ok(ret)
36+
}
37+
38+
fn retmapa(py: Python) -> PyResult<PyDict> {
39+
let dicionario = PyDict::new(py);
40+
dicionario.set_item(py, "chave1", "valor1")?;
41+
dicionario.set_item(py, "chave2", 123)?;
42+
Ok(dicionario)
43+
}
44+
45+
fn reclista(py: Python, lista_python: Vec<i32>) -> PyResult<PyList> {
46+
let lista_soma = lista_python.iter().map(|&x| x + x).collect::<Vec<i32>>();
47+
let lista_retorno = lista_soma.to_py_object(py);
48+
Ok(lista_retorno)
49+
}
50+
51+
fn btree_mapa(py: Python) -> PyResult<PyDict> {
52+
let mut dicionario_btree = BTreeMap::<String, i32>::new();
53+
dicionario_btree.insert("key".to_string(), 1);
54+
let py_map = dicionario_btree.to_py_object(py);
55+
Ok(py_map)
56+
}
57+
58+
fn rec_btree_mapa(py: Python, mapa: PyDict) -> PyResult<PyDict> {
59+
let mut dicionario_btree = BTreeMap::<String, i32>::new();
60+
let res = mapa.items(py);
61+
for f in res.iter() {
62+
dicionario_btree.insert(f.0.to_string(), f.1.to_string().parse::<i32>().unwrap()+10);
63+
}
64+
let ret_map = dicionario_btree.to_py_object(py);
65+
Ok(ret_map)
66+
}
67+
68+
py_module_initializer!(mvrpl, initmvrpl, PyInit_mvrpl, |py, m| {
69+
try!(m.add(py, "__doc__", "Este modulo foi escrito em Rust."));
70+
try!(m.add(py, "retpy", py_fn!(py, retpy())));
71+
try!(m.add(py, "retmapa", py_fn!(py, retmapa())));
72+
try!(m.add(py, "returl", py_fn!(py, returl())));
73+
try!(m.add(py, "reclista", py_fn!(py, reclista(rand_int:Vec<i32>))));
74+
try!(m.add(py, "mapa", py_fn!(py, btree_mapa())));
75+
try!(m.add(py, "recmapa", py_fn!(py, rec_btree_mapa(rand_int:PyDict))));
76+
Ok(())
77+
});

src/utils.rs

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
extern crate cpython;
2+
extern crate serde_json;
3+
4+
use cpython::*;
5+
use serde_json::Value;
6+
7+
pub fn fromjson(py: Python, json: Value) -> PyObject {
8+
macro_rules! obj {
9+
($x:ident) => {
10+
$x.into_py_object(py).into_object()
11+
}
12+
}
13+
14+
match json {
15+
Value::Number(x) => {
16+
if let Some(n) = x.as_u64() {
17+
obj!(n)
18+
} else if let Some(n) = x.as_i64() {
19+
obj!(n)
20+
} else if let Some(n) = x.as_f64() {
21+
obj!(n)
22+
} else {
23+
panic!("Número inválido")
24+
}
25+
}
26+
Value::String(x) => PyUnicode::new(py, &x).into_object(),
27+
Value::Bool(x) => obj!(x),
28+
Value::Array(vec) => {
29+
let mut elements = Vec::new();
30+
for item in vec {
31+
elements.push(fromjson(py, item));
32+
}
33+
PyList::new(py, &elements[..]).into_object()
34+
}
35+
Value::Object(map) => {
36+
let dict = PyDict::new(py);
37+
for (key, value) in map {
38+
dict.set_item(py, key, fromjson(py, value));
39+
}
40+
dict.into_object()
41+
}
42+
Value::Null => py.None(),
43+
}
44+
}

test.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import mvrpl
2+
import json
3+
4+
print "------------- Retorna DocString do modulo -------------"
5+
print mvrpl.__doc__
6+
print
7+
8+
print "------------- Retorna resultado Python -------------"
9+
print mvrpl.retpy()
10+
print
11+
12+
print "------------- Retorna Mapa Python -------------"
13+
for k,v in mvrpl.retmapa().iteritems():
14+
print "Chave: %s" % k
15+
print "Valor: %s" % v
16+
print
17+
18+
print "------------- Retorna Lista Python -------------"
19+
print "__".join([str(n) for n in mvrpl.reclista([1,2,3])])
20+
print
21+
22+
print "------------- Retorna resposta de URL -------------"
23+
print mvrpl.returl()
24+
print
25+
26+
print "------------- Retorna Mapa Rust no Python -------------"
27+
print mvrpl.mapa()
28+
print
29+
30+
print "------------- Retorna parse dict Python -------------"
31+
print mvrpl.recmapa({'key':15})
32+
print

0 commit comments

Comments
 (0)