#python #json #convert-json #serde-json #native #object #again

cpython-json

Converts native Python objects into serde_json Values and back again

4 releases (2 breaking)

Uses old Rust 2015

0.3.0 Oct 2, 2018
0.2.0 Aug 30, 2017
0.1.1 Feb 7, 2017
0.1.0 Jan 15, 2017

#17 in #again


Used in 2 crates (via gateway)

MIT/Apache

19KB
264 lines

rust-cpython-json

crates.io docs.rs Build Status

cpython-json converts native Python objects (via cpython PyObjects) to serde_json Values and back again.

It was developed for crowbar, a shim for writing native Rust code in AWS Lambda using the Python execution environment. Because Lambda is a JSON-in, JSON-out API, all objects passing through crowbar are JSON serializable.

Values are not actually converted to JSON as part of this process; serializing and deserializing JSON is slow. Instead, PyObjects are natively casted to a reasonably matching type of Value, and PyObjects are created directly from pattern-matching Values.

Data types that the Python json module can convert to JSON can be converted with this. (If you find something that works in the Python json module that doesn't work in cpython-json, please file an issue with your test case.)

Usage

Add cpython-json to your Cargo.toml alongside cpython:

[dependencies]
cpython = "*"
cpython-json = "0.3"

Similar to cpython, Python 3 is used by default. To use Python 2:

[dependencies.cpython-json]
version = "0.3"
default-features = false
features = ["python27-sys"]

Example code which reads sys.hexversion and bitbangs something resembling the version string (release level and serial not included for brevity):

extern crate cpython;
extern crate cpython_json;
extern crate serde_json;

use cpython::*;
use cpython_json::to_json;
use serde_json::Value;

fn main() {
    let gil = Python::acquire_gil();
    println!("{}", version(gil.python()).expect("failed to get Python version"));
}

fn version(py: Python) -> PyResult<String> {
    let sys = py.import("sys")?;
    let py_hexversion = sys.get(py, "hexversion")?;
    let hexversion = match to_json(py, &py_hexversion).map_err(|e| e.to_pyerr(py))? {
        Value::U64(x) => x,
        Value::I64(x) => x as u64,
        _ => panic!("hexversion is not an int"),
    };

    Ok(format!("{}.{}.{}", hexversion >> 24, hexversion >> 16 & 0xff, hexversion >> 8 & 0xff))
}

Dependencies

~1.2–1.9MB
~38K SLoC